From e8b98ddd212ff54d7e47550dac87069efb468083 Mon Sep 17 00:00:00 2001 From: ahmedk <karim.ahmed@xfel.eu> Date: Tue, 13 Dec 2022 14:18:16 +0100 Subject: [PATCH] Agipd correction using calcat_interface --- .../AGIPD/AGIPD_Correct_and_Verify.ipynb | 105 ++++-- ...IPD_Retrieve_Constants_Precorrection.ipynb | 300 ++++++++---------- src/cal_tools/agipdlib.py | 174 +++++----- 3 files changed, 315 insertions(+), 264 deletions(-) diff --git a/notebooks/AGIPD/AGIPD_Correct_and_Verify.ipynb b/notebooks/AGIPD/AGIPD_Correct_and_Verify.ipynb index 03f09957c..f54860b29 100644 --- a/notebooks/AGIPD/AGIPD_Correct_and_Verify.ipynb +++ b/notebooks/AGIPD/AGIPD_Correct_and_Verify.ipynb @@ -123,10 +123,9 @@ "outputs": [], "source": [ "import itertools\n", - "import os\n", "import math\n", "import multiprocessing\n", - "import re\n", + "import os\n", "import warnings\n", "from datetime import timedelta\n", "from logging import warning\n", @@ -155,6 +154,7 @@ "sns.set_context(\"paper\", font_scale=1.4)\n", "sns.set_style(\"ticks\")\n", "\n", + "from calibration_client import CalibrationClient\n", "from cal_tools import agipdalgs as calgs\n", "from cal_tools.agipdlib import (\n", " AgipdCorrections,\n", @@ -164,6 +164,7 @@ ")\n", "from cal_tools.ana_tools import get_range\n", "from cal_tools.enums import AgipdGainMode, BadPixels\n", + "from cal_tools.restful_config import restful_config\n", "from cal_tools.step_timing import StepTimer\n", "from cal_tools.tools import (\n", " CalibrationMetadata,\n", @@ -368,7 +369,6 @@ "\n", "instrument_src_mod = [\n", " s for s in list(dc.all_sources) if f\"{first_mod_channel}CH\" in s][0]\n", - "mod_channel = int(re.findall(rf\".*{first_mod_channel}CH([0-9]+):.*\", instrument_src_mod)[0])\n", "\n", "agipd_cond = AgipdCtrl(\n", " run_dc=dc,\n", @@ -559,6 +559,26 @@ "module_index_to_karabo_da = {mod: da for (mod, da) in zip(modules, karabo_da)}" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Connect to CalCat.\n", + "calcat_config = restful_config['calcat']\n", + "client = CalibrationClient(\n", + " base_api_url=calcat_config['base-api-url'],\n", + " use_oauth2=calcat_config['use-oauth2'],\n", + " client_id=calcat_config['user-id'],\n", + " client_secret=calcat_config['user-secret'],\n", + " user_email=calcat_config['user-email'],\n", + " token_url=calcat_config['token-url'],\n", + " refresh_url=calcat_config['refresh-url'],\n", + " auth_url=calcat_config['auth-url'],\n", + " scope='')" + ] + }, { "cell_type": "code", "execution_count": null, @@ -584,26 +604,21 @@ " when = agipd_corr.initialize_from_yaml(k_da, const_yaml, mod)\n", " print(f\"Found constants for {k_da} in calibration_metadata.yml\")\n", " else:\n", - " try:\n", - " # TODO: replace with proper retrieval (as done in pre-correction)\n", - " when = agipd_corr.initialize_from_db(\n", - " karabo_id=karabo_id,\n", - " karabo_da=k_da,\n", - " cal_db_interface=cal_db_interface,\n", - " creation_time=creation_time,\n", - " memory_cells=mem_cells_db,\n", - " bias_voltage=bias_voltage,\n", - " photon_energy=9.2,\n", - " gain_setting=gain_setting,\n", - " acquisition_rate=acq_rate,\n", - " integration_time=integration_time,\n", - " module_idx=mod,\n", - " only_dark=False,\n", - " )\n", - " print(f\"Queried CalCat for {k_da}\")\n", - " except Exception as e:\n", - " warning(f\"Module: {k_da}, {e}\")\n", - " when = None\n", + " when = agipd_corr.initialize_from_db(\n", + " karabo_id=karabo_id,\n", + " karabo_da=k_da,\n", + " creation_time=creation_time,\n", + " memory_cells=mem_cells_db,\n", + " bias_voltage=bias_voltage,\n", + " photon_energy=9.2,\n", + " gain_setting=gain_setting,\n", + " acquisition_rate=acq_rate,\n", + " integration_time=integration_time,\n", + " gain_mode=gain_mode,\n", + " module_idx=mod,\n", + " client=client,\n", + " )\n", + " print(f\"Queried CalCat for {k_da}\")\n", " return mod, when, k_da\n", "\n", "\n", @@ -615,6 +630,50 @@ "print(f\"Constants were loaded in {perf_counter()-ts:.01f}s\")" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# if the yml file contains \"retrieved-constants\", that means a leading\n", + "# notebook got processed and the reporting would be generated from it.\n", + "fst_print = True\n", + "timestamps = {}\n", + "\n", + "for i, (modno, when, k_da) in enumerate(const_out):\n", + " qm = module_index_to_qm(modno)\n", + "\n", + " if k_da not in const_yaml:\n", + " if fst_print:\n", + " print(\"Constants are retrieved with creation time: \")\n", + " fst_print = False\n", + "\n", + " module_timestamps = {}\n", + "\n", + " print(f\"{qm}:\")\n", + " for key, item in when.items():\n", + " if hasattr(item, 'strftime'):\n", + " item = item.strftime('%y-%m-%d %H:%M')\n", + " when[key] = item\n", + " print('{:.<12s}'.format(key), item)\n", + "\n", + " # Store few time stamps if exists\n", + " # Add NA to keep array structure\n", + " for key in ['Offset', 'SlopesPC', 'SlopesFF']:\n", + " if when and key in when and when[key]:\n", + " module_timestamps[key] = when[key]\n", + " else:\n", + " module_timestamps[key] = \"NA\"\n", + " timestamps[qm] = module_timestamps\n", + "\n", + "seq = sequences[0] if sequences else 0\n", + "\n", + "if timestamps:\n", + " with open(f\"{out_folder}/retrieved_constants_s{seq}.yml\",\"w\") as fd:\n", + " yaml.safe_dump({\"time-summary\": {f\"S{seq}\": timestamps}}, fd)" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/notebooks/AGIPD/AGIPD_Retrieve_Constants_Precorrection.ipynb b/notebooks/AGIPD/AGIPD_Retrieve_Constants_Precorrection.ipynb index d0b20cadf..ee782ac7f 100644 --- a/notebooks/AGIPD/AGIPD_Retrieve_Constants_Precorrection.ipynb +++ b/notebooks/AGIPD/AGIPD_Retrieve_Constants_Precorrection.ipynb @@ -81,29 +81,21 @@ "metadata": {}, "outputs": [], "source": [ - "import numpy as np\n", "from logging import warning\n", "from pathlib import Path\n", - "from typing import Tuple\n", "\n", "import multiprocessing\n", "from datetime import timedelta\n", "from dateutil import parser\n", "from extra_data import RunDirectory\n", "\n", - "from cal_tools.agipdlib import (\n", - " AgipdCtrl,\n", - " SnowResolution,\n", - " assemble_constant_dict,\n", - ")\n", - "from cal_tools.enums import AgipdGainMode\n", - "from cal_tools.tools import (\n", - " calcat_creation_time,\n", - " get_from_db,\n", - " module_index_to_qm,\n", - " CalibrationMetadata,\n", - ")\n", - "from iCalibrationDB import Conditions, Constants, Detectors" + "from calibration_client import CalibrationClient\n", + "from cal_tools.agipdlib import AgipdCtrl, SnowResolution\n", + "from cal_tools.calcat_interface import AGIPD_CalibrationData, CalCatError\n", + "from cal_tools.restful_config import restful_config\n", + "from cal_tools.step_timing import StepTimer\n", + "from cal_tools.tools import CalibrationMetadata, calcat_creation_time, module_index_to_qm\n", + "from cal_tools.enums import AgipdGainMode" ] }, { @@ -233,7 +225,11 @@ " corr_bools.get('blc_hmatch'),\n", " corr_bools.get('blc_stripes'),\n", " melt_snow,\n", - "]" + "]\n", + "\n", + "da_to_qm = dict()\n", + "for module_index, k_da in zip(modules, karabo_da):\n", + " da_to_qm[k_da] = module_index_to_qm(module_index)" ] }, { @@ -242,124 +238,36 @@ "metadata": {}, "outputs": [], "source": [ - "def retrieve_constants(\n", - " k_da: str, idx: int\n", - ") -> Tuple[str, str, float, float, str, dict]:\n", - " \"\"\"\n", - " Retrieve constants for a module.\n", - "\n", - " :return:\n", - " k_da: karabo data aggregator.\n", - " acq_rate: acquisition rate parameter.\n", - " mem_cells: number of memory cells.\n", - " mdata_dict: (DICT) dictionary with the metadata for the retrieved constants.\n", - " \"\"\"\n", - " # check if this module has images to process.\n", - " if instrument_src.format(idx) not in instr_dc.all_sources:\n", - " print(\"ERROR: No raw images found for \"\n", - " f\"{module_index_to_qm(idx)}({k_da}).\")\n", - "\n", - " return None, k_da, None, None\n", - "\n", + "def find_cells_acq_rate_module(idx):\n", + " \"\"\"Find memory cells and acquisition rate for a module.\"\"\"\n", " agipd_cond.image_src = instrument_src.format(idx)\n", "\n", - " if mem_cells == -1:\n", - " # Read value from fast data.\n", - " local_mem_cells = agipd_cond.get_num_cells()\n", - " else:\n", - " # or use overriding notebook parameter.\n", - " local_mem_cells = mem_cells\n", - "\n", - " if acq_rate == -1.:\n", - " local_acq_rate = agipd_cond.get_acq_rate()\n", - " else:\n", - " local_acq_rate = acq_rate\n", - "\n", - " const_dict = assemble_constant_dict(\n", - " corr_bools,\n", - " pc_bools,\n", - " local_mem_cells,\n", - " bias_voltage,\n", - " gain_setting,\n", - " local_acq_rate,\n", - " photon_energy=9.2,\n", - " gain_mode=gain_mode,\n", - " beam_energy=None,\n", - " only_dark=False,\n", - " integration_time=integration_time\n", - " )\n", - "\n", - " # Retrieve multiple constants through an input dictionary\n", - " # to return a dict of useful metadata.\n", - " mdata_dict = dict()\n", - " mdata_dict[\"constants\"] = dict()\n", - " mdata_dict[\"physical-detector-unit\"] = None # initialization\n", - "\n", - " for const_name, (const_init_fun, const_shape, (cond_type, cond_param)) in const_dict.items(): # noqa\n", - " if gain_mode and const_name in (\"ThresholdsDark\",):\n", - " continue\n", - " \n", - " # saving metadata in a dict\n", - " const_mdata = dict()\n", - " mdata_dict[\"constants\"][const_name] = const_mdata\n", - "\n", - " if slopes_ff_from_files and const_name in [\"SlopesFF\", \"BadPixelsFF\"]:\n", - " const_mdata[\"file-path\"] = (\n", - " f\"{slopes_ff_from_files}/slopesff_bpmask_module_{module_index_to_qm(idx)}.h5\") # noqa\n", - " const_mdata[\"creation-time\"] = \"00:00:00\"\n", - " continue\n", - " \n", - " if gain_mode and const_name in (\n", - " \"BadPixelsPC\", \"SlopesPC\", \"BadPixelsFF\", \"SlopesFF\"\n", - " ):\n", - " param_copy = cond_param.copy()\n", - " del param_copy[\"gain_mode\"]\n", - " condition = getattr(Conditions, cond_type).AGIPD(**param_copy)\n", - " else:\n", - " condition = getattr(Conditions, cond_type).AGIPD(**cond_param)\n", - "\n", - " _, mdata = get_from_db(\n", - " karabo_id,\n", - " k_da,\n", - " getattr(Constants.AGIPD, const_name)(),\n", - " condition,\n", - " getattr(np, const_init_fun)(const_shape),\n", - " cal_db_interface,\n", - " creation_time,\n", - " meta_only=True,\n", - " verbosity=0,\n", - " )\n", - " mdata_const = mdata.calibration_constant_version\n", - " # check if constant was sucessfully retrieved.\n", - " if mdata.comm_db_success:\n", - " const_mdata[\"file-path\"] = (\n", - " f\"{mdata_const.hdf5path}\" f\"{mdata_const.filename}\"\n", - " )\n", - " const_mdata[\"creation-time\"] = f\"{mdata_const.begin_at}\"\n", - " mdata_dict[\"physical-detector-unit\"] = mdata_const.device_name\n", - " else:\n", - " const_mdata[\"file-path\"] = const_dict[const_name][:2]\n", - " const_mdata[\"creation-time\"] = None\n", + " if agipd_cond.image_src not in instr_dc.all_sources:\n", + " warning(f\"No raw images found for {module_index_to_qm(idx)}({k_da}).\")\n", + " return None, None\n", + " \n", + " _mem_cells = agipd_cond.get_num_cells() if mem_cells == -1 else mem_cells\n", + " _acq_rate = agipd_cond.get_acq_rate() if acq_rate == -1 else acq_rate\n", "\n", - " return mdata_dict, k_da, local_acq_rate, local_mem_cells" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "inp = []\n", - "da_to_qm = dict()\n", - "for module_index, k_da in zip(modules, karabo_da):\n", - " da_to_qm[k_da] = module_index_to_qm(module_index)\n", - " if k_da in retrieved_constants:\n", - " print(\n", - " f\"Constant for {k_da} already in calibration_metadata.yml, won't query again.\")\n", - " continue\n", + " return _mem_cells, _acq_rate\n", + "\n", + "\n", + "all_mem_cells = set()\n", + "all_acq_rates = set()\n", "\n", - " inp.append((k_da, module_index))" + "with multiprocessing.Pool(processes=nmods) as pool:\n", + " results = pool.map(find_cells_acq_rate_module, modules)\n", + "\n", + "for (_mem_cells, _acq_rate) in results:\n", + " all_mem_cells.add(_mem_cells)\n", + " all_acq_rates.add(_acq_rate)\n", + "# Validate that mem_cells and acq_rate are the same for all modules.\n", + "if len(all_mem_cells) != 1 or len(all_acq_rates) != 1:\n", + " warning(\n", + " \"Number of memory cells or acquisition rate are not identical for all modules.\\n\"\n", + " f\"different mem_cells values: {all_mem_cells}.\\ndifferent acq_rate values: {all_acq_rates}.\")\n", + "mem_cells = all_mem_cells.pop()\n", + "acq_rate = all_acq_rates.pop()" ] }, { @@ -368,8 +276,18 @@ "metadata": {}, "outputs": [], "source": [ - "with multiprocessing.Pool(processes=nmods) as pool:\n", - " results = pool.starmap(retrieve_constants, inp)" + "# Connect to CalCat.\n", + "calcat_config = restful_config['calcat']\n", + "client = CalibrationClient(\n", + " base_api_url=calcat_config['base-api-url'],\n", + " use_oauth2=calcat_config['use-oauth2'],\n", + " client_id=calcat_config['user-id'],\n", + " client_secret=calcat_config['user-secret'],\n", + " user_email=calcat_config['user-email'],\n", + " token_url=calcat_config['token-url'],\n", + " refresh_url=calcat_config['refresh-url'],\n", + " auth_url=calcat_config['auth-url'],\n", + " scope='')" ] }, { @@ -378,36 +296,77 @@ "metadata": {}, "outputs": [], "source": [ - "acq_rate_mods = []\n", - "mem_cells_mods = []\n", - "for md_dict, k_da, acq_rate, mem_cells in results:\n", - " if acq_rate is None and mem_cells is None:\n", - " continue\n", - " md_dict, k_da, acq_rate, mem_cells\n", - " retrieved_constants[k_da] = md_dict\n", - " mem_cells_mods.append(mem_cells)\n", - " acq_rate_mods.append(acq_rate)\n", + "step_timer = StepTimer()\n", + "step_timer.start()\n", + "agipd_cal = AGIPD_CalibrationData(\n", + " detector_name=karabo_id,\n", + " modules=karabo_da,\n", + " sensor_bias_voltage=bias_voltage,\n", + " memory_cells=mem_cells,\n", + " acquisition_rate=acq_rate,\n", + " integration_time=integration_time,\n", + " source_energy=9.2,\n", + " gain_mode=gain_mode,\n", + " gain_setting=gain_setting,\n", + " event_at=creation_time,\n", + " client=client,\n", + ")\n", "\n", - "# Validate that mem_cells and acq_rate are the same for all modules.\n", - "# TODO: Should a warning be enough?\n", - "if len(set(mem_cells_mods)) != 1 or len(set(acq_rate_mods)) != 1:\n", - " print(\n", - " \"WARNING: Number of memory cells or \"\n", - " \"acquisition rate are not identical for all modules.\\n\"\n", - " f\"mem_cells: {mem_cells_mods}.\\nacq_rate: {acq_rate_mods}.\")\n", - "\n", - "# check if it is requested not to retrieve any constants from the database\n", - "print(\"\\nRetrieved constants for modules:\",\n", - " ', '.join([module_index_to_qm(x) for x in modules]))\n", - "print(f\"Operating conditions are:\")\n", - "print(f\"• Bias voltage: {bias_voltage}\")\n", - "print(f\"• Memory cells: {mem_cells}\")\n", - "print(f\"• Acquisition rate: {acq_rate}\")\n", - "print(f\"• Gain mode: {gain_mode.name}\")\n", - "print(f\"• Gain setting: {gain_setting}\")\n", - "print(f\"• Integration time: {integration_time}\")\n", - "print(f\"• Photon Energy: 9.2\")\n", - "print(\"Constant metadata is saved under \\\"retrieved-constants\\\" in calibration_metadata.yml\\n\")" + "dark_constants = [\"Offset\", \"Noise\", \"BadPixelsDark\"] if gain_mode else [\"ThresholdsDark\", \"Offset\", \"Noise\", \"BadPixelsDark\"]\n", + "\n", + "gain_constants = []\n", + "if pc_bools:\n", + " gain_constants += [\"SlopesPC\", \"BadPixelsPC\"]\n", + "if xray_gain:\n", + " gain_constants += [\"SlopesFF\", \"BadPixelsFF\"]\n", + "\n", + "constants = dark_constants\n", + "constants += gain_constants\n", + "\n", + "# The main metadata dict for all modules and retrieved CCVs.\n", + "agipd_metadata = {mod:{} for mod in agipd_cal.modules}\n", + "\n", + "# This is done to alter the condition for gain constants and avoid using gain_mode.\n", + "for cname in constants:\n", + " if cname in gain_constants:\n", + " agipd_cal.gain_mode = None\n", + " try:\n", + " a = agipd_cal.metadata([cname])\n", + " for mod, ccv_entry in a.items():\n", + " agipd_metadata[mod].update(a[mod])\n", + " except CalCatError as e:\n", + " pass # a validation of missing constants is done later.\n", + "\n", + "# Validate the constants availability and raise/warn correspondingly. \n", + "for mod, ccv_dict in agipd_metadata.items():\n", + " missing_dark_constants = set(\n", + " c for c in dark_constants if c not in ccv_dict.keys())\n", + " missing_gain_constants = set(\n", + " c for c in gain_constants if c not in ccv_dict.keys())\n", + " if missing_dark_constants:\n", + " raise KeyError(\n", + " f\"Dark constants {missing_dark_constants} are not available for correction. Module: {mod}\") # noqa\n", + " if missing_gain_constants:\n", + " warning(\n", + " f\"Gain constants {missing_gain_constants} were not retrieved. Module: {mod}\")\n", + "\n", + "for mod, ccv_dict in agipd_metadata.items():\n", + " mdata_dict = {\"constants\": dict()}\n", + " for cname, ccv_metadata in ccv_dict.items():\n", + " if slopes_ff_from_files and cname in [\"SlopesFF\", \"BadPixelsFF\"]:\n", + " mdata_dict[\"constants\"][cname] = {\n", + " \"path\": f\"{slopes_ff_from_files}/slopesff_bpmask_module_{module_index_to_qm(int(mod[-2:]))}.h5\", # noqa\n", + " \"dataset\": \"\",\n", + " \"creation-time\": \"00:00:00\",\n", + " }\n", + " else:\n", + " mdata_dict[\"constants\"][cname] = {\n", + " \"path\": str(agipd_cal.caldb_root / ccv_metadata[\"path\"]),\n", + " \"dataset\": ccv_metadata[\"dataset\"],\n", + " \"creation-time\": ccv_metadata[\"begin_validity_at\"],\n", + " }\n", + " mdata_dict[\"physical-name\"] = ccv_metadata[\"physical_name\"]\n", + " retrieved_constants[mod] = mdata_dict" ] }, { @@ -442,6 +401,25 @@ "\n", "metadata.save()" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"\\nRetrieved constants for modules:\",\n", + " ', '.join([module_index_to_qm(x) for x in modules]))\n", + "print(f\"Operating conditions are:\")\n", + "print(f\"• Bias voltage: {bias_voltage}\")\n", + "print(f\"• Memory cells: {mem_cells}\")\n", + "print(f\"• Acquisition rate: {acq_rate}\")\n", + "print(f\"• Gain mode: {gain_mode.name}\")\n", + "print(f\"• Gain setting: {gain_setting}\")\n", + "print(f\"• Integration time: {integration_time}\")\n", + "print(f\"• Photon Energy: 9.2\")\n", + "step_timer.done_step(f\"Constant metadata is saved under \\\"retrieved-constants\\\" in {metadata.filename}\")" + ] } ], "metadata": { diff --git a/src/cal_tools/agipdlib.py b/src/cal_tools/agipdlib.py index 038ca342b..5d5aa54a2 100644 --- a/src/cal_tools/agipdlib.py +++ b/src/cal_tools/agipdlib.py @@ -2,20 +2,19 @@ import os import posixpath import zlib from datetime import datetime +from logging import warning from multiprocessing import Manager from multiprocessing.pool import ThreadPool -from typing import Any, Dict, List, Optional, Tuple +from typing import Any, Dict, List, Optional import h5py import numpy as np import sharedmem from dateutil import parser from extra_data import DataCollection, H5File, by_id, components -from iCalibrationDB import Conditions, Constants from cal_tools import agipdalgs as calgs from cal_tools.agipdutils import ( - assemble_constant_dict, baseline_correct_via_noise, baseline_correct_via_stripe, correct_baseline_via_hist, @@ -27,7 +26,6 @@ from cal_tools.agipdutils import ( ) from cal_tools.enums import AgipdGainMode, BadPixels, SnowResolution from cal_tools.h5_copy_except import h5_copy_except_paths -from cal_tools.tools import get_from_db class AgipdCtrl: @@ -1357,12 +1355,12 @@ class AgipdCorrections: cons_data = dict() when = dict() variant = dict() - db_module = const_yaml[karabo_da]["physical-detector-unit"] + db_module = const_yaml[karabo_da]["physical-name"] for cname, mdata in const_yaml[karabo_da]["constants"].items(): base_key = f"{db_module}/{cname}/0" when[cname] = mdata["creation-time"] if when[cname]: - with h5py.File(mdata["file-path"], "r") as cf: + with h5py.File(mdata["path"], "r") as cf: cons_data[cname] = np.copy(cf[f"{base_key}/data"]) # Set variant to 0 if the attribute is missing # as for old constants. @@ -1372,54 +1370,43 @@ class AgipdCorrections: variant[cname] = 0 else: # Create empty constant using the list elements - cons_data[cname] = getattr(np, mdata["file-path"][0])(mdata["file-path"][1]) # noqa + cons_data[cname] = getattr(np, mdata["path"][0])(mdata["path"][1]) # noqa self.init_constants(cons_data, when, module_idx, variant) return when - def initialize_from_db(self, karabo_id: str, karabo_da: str, - cal_db_interface: str, - creation_time: datetime, - memory_cells: float, bias_voltage: int, - photon_energy: float, gain_setting: float, - acquisition_rate: float, integration_time: int, - module_idx: int, only_dark: bool = False): + def initialize_from_db( + self, karabo_id: str, + karabo_da: str, + module_idx: int, + creation_time: datetime, + memory_cells: int, + bias_voltage: int, + gain_setting: float, + gain_mode: int, + acquisition_rate: float, + integration_time: int, + photon_energy: float = 9.2, + client=None, + ): """ Initialize calibration constants from the calibration database - :param karabo_id: karabo identifier - :param karabo_da: karabo data aggregator - :param cal_db_interface: database interaface port - :param creation_time: time for desired calibration constant version - :param memory_cells: number of memory cells used for CCV conditions - :param bias_voltage: bias voltage used for CCV conditions - :param photon_energy: photon energy used for CCV conditions - :param gain_setting: gain setting used for CCV conditions - :param acquisition_rate: acquistion rate used for CCV conditions - :param integration_time: integration time used for CCV conditions - :param module_idx: module index to save retrieved CCV in sharedmem - :param only_dark: load only dark image derived constants. This - implies that a `calfile` is used to load the remaining - constants. Useful to reduce DB traffic and interactions - for non-frequently changing constants, i.e. such which are - not usually updated during a beamtime. - - The `cal_db_interface` parameter in the `dbparms` tuple may be in - one of the following notations: - * tcp://host:port to directly identify the host and port to - connect to - * tcp://host:port_low#port_high to specify a port range from - which a random port will be picked. E.g. specifying - - tcp://max-exfl-cal001:8015#8025 - - will randomly pick an address in the range max-exfl-cal001:8015 and - max-exfl-cal001:8025. - - The latter notation allows for load-balancing. - - This routine loads the following constants as given in - `iCalibrationDB`: + :param karabo_id: karabo detector identifier. + :param karabo_da: karabo module data aggregator name. + :param module_idx: module index to save retrieved CCV in sharedmem. + :param creation_time: time for desired calibration constant version. + :param memory_cells: number of memory cells used for CCV conditions. + :param bias_voltage: bias voltage used for CCV conditions. + :param gain_setting: gain setting used for CCV conditions. + :param gain_mode: gain mode used for CCV conditions. + :param acquisition_rate: acquistion rate used for CCV conditions. + :param integration_time: integration time used for CCV conditions. + :param photon_energy: photon energy value used for CCV conditions. + :param client: calibration_client object for CalibrationData objects. + + Loading the following constants based on the + correction configuration: Dark Image Derived ------------------ @@ -1433,50 +1420,77 @@ class AgipdCorrections: ----------------------- * Constants.AGIPD.SlopesPC + * Constants.AGIPD.BadPixelsPC Flat-Field Derived * Constants.AGIPD.SlopesFF - + * Constants.AGIPD.BadPixelsFF """ - - const_dict = assemble_constant_dict( - self.corr_bools, - self.pc_bools, - memory_cells, - bias_voltage, - gain_setting, - acquisition_rate, - photon_energy, - beam_energy=None, - only_dark=only_dark, - integration_time=integration_time - ) + from cal_tools.calcat_interface import AGIPD_CalibrationData when = {} cons_data = {} variant = {} - for cname, cval in const_dict.items(): - condition = getattr( - Conditions, cval[2][0]).AGIPD(**cval[2][1]) - cdata, md = get_from_db( - karabo_id=karabo_id, - karabo_da=karabo_da, - constant=getattr(Constants.AGIPD, cname)(), - condition=condition, - empty_constant=getattr(np, cval[0])(cval[1]), - cal_db_interface=cal_db_interface, - creation_time=creation_time, - verbosity=0, - ) - cons_data[cname] = cdata - variant[cname] = md.calibration_constant_version.variant + agipd_cal = AGIPD_CalibrationData( + detector_name=karabo_id, + modules=[karabo_da], + sensor_bias_voltage=bias_voltage, + memory_cells=memory_cells, + acquisition_rate=acquisition_rate, + integration_time=integration_time, + source_energy=photon_energy, + gain_mode=gain_mode, + gain_setting=gain_setting, + event_at=creation_time, + client=client, + ) - when[cname] = None - # Read the CCV begin at if constant was retrieved successfully. - if md and md.comm_db_success: - when[cname] = md.calibration_constant_version.begin_at + dark_constants = [ + "Offset", + "Noise", + "BadPixelsDark" + ] if self.gain_mode else [ + "ThresholdsDark", + "Offset", + "Noise", + "BadPixelsDark" + ] + + gain_constants = [] + if any(self.pc_bools): + gain_constants += ["SlopesPC", "BadPixelsPC"] + if self.corr_bools.get("xray_corr"): + gain_constants += ["SlopesFF", "BadPixelsFF"] + + constants = dark_constants + constants += gain_constants + metadata = agipd_cal.metadata(constants) + # Validate the constants availability and raise/warn correspondingly. + for mod, ccv_dict in metadata.items(): + missing_dark_constants = set( + c for c in dark_constants if c not in ccv_dict.keys()) + missing_gain_constants = set( + c for c in gain_constants if c not in ccv_dict.keys()) + if missing_dark_constants: + raise KeyError( + f"Dark constants {missing_dark_constants} are not available" + f" for correction. Module: {mod}") + if missing_gain_constants: + warning( + f"Gain constants {missing_gain_constants} were" + f" not retrieved. Module: {mod}") + + for cname in constants: + if metadata[karabo_da].get(cname): + when[cname] = metadata[karabo_da][cname]["begin_validity_at"] + dataset = metadata[karabo_da][cname]["dataset"] + with h5py.File(agipd_cal.caldb_root / metadata[karabo_da][cname]["path"], "r") as cf: # noqa + cons_data[cname] = np.copy(cf[f"{dataset}/data"]) + variant[cname] = cf[dataset].attrs["variant"] if cf[dataset].attrs.keys() else 0 # noqa + else: + when[cname] = None self.init_constants(cons_data, when, module_idx, variant) -- GitLab