diff --git a/notebooks/AGIPD/AGIPD_Correct_and_Verify.ipynb b/notebooks/AGIPD/AGIPD_Correct_and_Verify.ipynb index 3fdf35bc8046786557ac1830639e078f10be5c77..0d9de779b982b7eb85b0b6e07ae6640c5ae00944 100644 --- a/notebooks/AGIPD/AGIPD_Correct_and_Verify.ipynb +++ b/notebooks/AGIPD/AGIPD_Correct_and_Verify.ipynb @@ -49,6 +49,7 @@ "max_pulses = [0, 500, 1] # range list [st, end, step] of maximum pulse indices within a train. 3 allowed maximum list input elements.\n", "mem_cells_db = 0 # set to a value different than 0 to use this value for DB queries\n", "cell_id_preview = 1 # cell Id used for preview in single-shot plots\n", + "integration_time = -1 # integration time, negative values for auto-detection.\n", "\n", "# Correction parameters\n", "blc_noise_threshold = 5000 # above this mean signal intensity now baseline correction via noise is attempted\n", @@ -140,6 +141,7 @@ " AgipdCorrections,\n", " get_acq_rate,\n", " get_gain_mode,\n", + " get_integration_time,\n", " get_gain_setting,\n", " get_num_cells,\n", ")\n", @@ -372,7 +374,11 @@ " gain_setting = 0\n", "\n", "# Evaluate gain mode (operation mode)\n", - "gain_mode = get_gain_mode(control_fn, h5path_ctrl)" + "gain_mode = get_gain_mode(control_fn, h5path_ctrl)\n", + "\n", + "# Evaluate integration time\n", + "if integration_time < 0:\n", + " integration_time = get_integration_time(control_fn, h5path_ctrl)" ] }, { @@ -388,6 +394,7 @@ "print(f\"• Acquisition rate: {acq_rate}\")\n", "print(f\"• Gain setting: {gain_setting}\")\n", "print(f\"• Gain mode: {gain_mode.name}\")\n", + "print(f\"• Integration time: {integration_time}\")\n", "print(f\"• Photon Energy: {photon_energy}\")" ] }, @@ -476,17 +483,18 @@ " else:\n", " # TODO: replace with proper retrieval (as done in pre-correction)\n", " when = agipd_corr.initialize_from_db(\n", - " karabo_id,\n", - " k_da,\n", - " cal_db_interface,\n", - " creation_time,\n", - " mem_cells_db,\n", - " bias_voltage,\n", - " photon_energy,\n", - " gain_setting,\n", - " acq_rate,\n", - " mod,\n", - " False,\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=photon_energy,\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", " except Exception as e:\n", " err = f\"Error: {e}\\nError traceback: {traceback.format_exc()}\"\n", diff --git a/notebooks/AGIPD/AGIPD_Retrieve_Constants_Precorrection.ipynb b/notebooks/AGIPD/AGIPD_Retrieve_Constants_Precorrection.ipynb index df6dc058d7530ad8c26702615cc775079d6247c1..760e60941d08c91429037188d6d76472918d5648 100644 --- a/notebooks/AGIPD/AGIPD_Retrieve_Constants_Precorrection.ipynb +++ b/notebooks/AGIPD/AGIPD_Retrieve_Constants_Precorrection.ipynb @@ -44,6 +44,7 @@ "photon_energy = 9.2 # photon energy in keV\n", "max_cells_db_dark = 0 # set to a value different than 0 to use this value for dark data DB queries\n", "max_cells_db = 0 # set to a value different than 0 to use this value for DB queries\n", + "integration_time = -1 # integration time, negative values for auto-detection.\n", "\n", "# Correction Booleans\n", "only_offset = False # Apply only Offset correction. if False, Offset is applied by Default. if True, Offset is only applied.\n", @@ -161,6 +162,10 @@ "\n", "# Evaluate gain mode (operation mode)\n", "gain_mode = agipdlib.get_gain_mode(control_fn, h5path_ctrl)\n", + "\n", + "# Evaluate integration time\n", + "if integration_time < 0:\n", + " integration_time = agipblib.get_integration_time(control_fn, h5path_ctrl)\n", " \n", "print(f\"Gain setting: {gain_setting}\")\n", "print(f\"Gain mode: {gain_mode.name}\")\n", @@ -254,6 +259,7 @@ " gain_mode=gain_mode,\n", " beam_energy=None,\n", " only_dark=only_dark,\n", + " integration_time=integration_time\n", " )\n", "\n", " # Retrieve multiple constants through an input dictionary\n", @@ -384,6 +390,7 @@ " 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: {photon_energy}\")\n", " print(\"Constant metadata is saved under \\\"retrieved-constants\\\" in calibration_metadata.yml\\n\")" ] diff --git a/notebooks/AGIPD/Characterize_AGIPD_Gain_Darks_NBC.ipynb b/notebooks/AGIPD/Characterize_AGIPD_Gain_Darks_NBC.ipynb index 7661d99d8300ce7d9a9a02f211e7d91bc25ca983..35fddcd6ac142b9b73b3d4ee58995b6252623df2 100644 --- a/notebooks/AGIPD/Characterize_AGIPD_Gain_Darks_NBC.ipynb +++ b/notebooks/AGIPD/Characterize_AGIPD_Gain_Darks_NBC.ipynb @@ -101,6 +101,7 @@ " get_bias_voltage,\n", " get_gain_mode,\n", " get_gain_setting,\n", + " get_integration_time,\n", " get_num_cells,\n", ")\n", "from cal_tools.enums import AgipdGainMode, BadPixels\n", @@ -185,6 +186,13 @@ "else:\n", " print(f'Something is clearly wrong; slow data indicates gain modes {run_gain_modes}')\n", "\n", + "if integration_time < 0:\n", + " integration_times = [get_integration_time(fn, h5path_ctrl) for fn in control_names]\n", + " if len(set(integration_times)) > 1:\n", + " print(f'WARNING: integration time is not constant across the specified dark runs')\n", + "\n", + "integration_time = integration_times[0]\n", + "\n", "print(f\"Detector in use is {karabo_id}\")\n", "print(f\"Instrument {instrument}\")\n", "print(f\"Detector instance {dinstance}\")" @@ -254,6 +262,7 @@ "print(f\"Output: {out_folder}\")\n", "print(f\"Bias voltage: {bias_voltage}V\")\n", "print(f\"Gain setting: {gain_setting}\")\n", + "print(f\"Integration time: {integration_time}\")\n", "print(f\"Operation mode is {'fixed' if fixed_gain_mode else 'adaptive'} gain mode\")" ] }, @@ -589,7 +598,8 @@ " bias_voltage=bias_voltage,\n", " acquisition_rate=acq_rate,\n", " gain_setting=gain_setting,\n", - " gain_mode=fixed_gain_mode\n", + " gain_mode=fixed_gain_mode,\n", + " integration_time=integration_time\n", ")" ] }, @@ -645,7 +655,7 @@ " print(\"Constants parameter conditions are:\\n\")\n", " print(f\"• memory_cells: {max_cells}\\n• bias_voltage: {bias_voltage}\\n\"\n", " f\"• acquisition_rate: {acq_rate}\\n• gain_setting: {gain_setting}\\n\"\n", - " f\"• gain_mode: {fixed_gain_mode}\\n\"\n", + " f\"• gain_mode: {fixed_gain_mode}\\n• integration_time: {integration_time}\\n\"\n", " f\"• creation_time: {md.calibration_constant_version.begin_at if md is not None else creation_time}\\n\")" ] }, diff --git a/notebooks/AGIPD/Characterize_AGIPD_Gain_FlatFields_Summary.ipynb b/notebooks/AGIPD/Characterize_AGIPD_Gain_FlatFields_Summary.ipynb index f81a26a0df06649f5e847f3fe47d93647e0c2fb0..6d734bf9934e6c6835a897991ad73086b37d0937 100644 --- a/notebooks/AGIPD/Characterize_AGIPD_Gain_FlatFields_Summary.ipynb +++ b/notebooks/AGIPD/Characterize_AGIPD_Gain_FlatFields_Summary.ipynb @@ -59,7 +59,8 @@ "bias_voltage = 300 # Bias voltage\n", "acq_rate = 0. # the detector acquisition rate, use 0 to try to auto-determine\n", "gain_setting = 0.1 # the gain setting, use 0.1 to try to auto-determine\n", - "photon_energy = 8.05 # photon energy in keV" + "photon_energy = 8.05 # photon energy in keV\n", + "integration_time = -1 # integration time, negative values for auto-detection." ] }, { @@ -83,6 +84,7 @@ " get_acq_rate,\n", " get_bias_voltage,\n", " get_gain_setting,\n", + " get_integration_time,\n", " get_num_cells,\n", ")\n", "from cal_tools.agipdutils_ff import (\n", @@ -161,6 +163,10 @@ " print(e)\n", " print(\"Set gain settion to 0\")\n", " gain_setting = 0\n", + "\n", + "# Evaluate integration time\n", + "if integration_time < 0:\n", + " integration_time = get_integration_time(filename, h5path_ctrl)\n", " \n", "# Evaluate detector instance for mapping\n", "instrument = karabo_id.split(\"_\")[0]\n", @@ -171,7 +177,8 @@ "\n", "print(f\"Using {creation_time} as creation time\")\n", "print(f\"Operating conditions are:\\n• Bias voltage: {bias_voltage}\\n• Memory cells: {mem_cells}\\n\"\n", - " f\"• Acquisition rate: {acq_rate}\\n• Gain setting: {gain_setting}\\n• Photon Energy: {photon_energy}\\n\")" + " f\"• Acquisition rate: {acq_rate}\\n• Gain setting: {gain_setting}\\n• Integration time: {integration_time}\\n\"\n", + " f\"• Photon Energy: {photon_energy}\\n\")" ] }, { @@ -265,7 +272,16 @@ "# set the operating condition\n", "condition = Conditions.Illuminated.AGIPD(mem_cells, bias_voltage, 9.2,\n", " pixels_x=512, pixels_y=128, beam_energy=None,\n", - " acquisition_rate=acq_rate, gain_setting=gain_setting)\n", + " acquisition_rate=acq_rate, gain_setting=gain_setting,\n", + " integration_time=integration_time)\n", + "\n", + "# Modify acceptable deviations for integration time condition if and only if\n", + "# the integration time is not using the standard value (12).\n", + "if integration_time != 12:\n", + " for p in condition.parameters:\n", + " if p.name == 'Integration Time':\n", + " p.lower_deviation = 5\n", + " p.upper_deviation = 5\n", "\n", "# Retrieve a list of all modules corresponding to processed karabo_das\n", "db_modules = get_pdu_from_db(karabo_id, karabo_da, Constants.AGIPD.SlopesFF(),\n", diff --git a/notebooks/AGIPD/Chracterize_AGIPD_Gain_PC_NBC.ipynb b/notebooks/AGIPD/Chracterize_AGIPD_Gain_PC_NBC.ipynb index 8f7ffe5de01203fd761ee89c91d9e6f5e6042432..75c1a43da968cc286ba748fbbebc35a7c7515d7b 100644 --- a/notebooks/AGIPD/Chracterize_AGIPD_Gain_PC_NBC.ipynb +++ b/notebooks/AGIPD/Chracterize_AGIPD_Gain_PC_NBC.ipynb @@ -58,6 +58,7 @@ "mem_cells = 0. # number of memory cells used, use 0 to auto-derive\n", "acq_rate = 0. # the detector acquisition rate, use 0 to try to auto-determine\n", "gain_setting = 0.1 # gain setting can have value 0 or 1, Default=0.1 for no (None) gain-setting\n", + "integration_time = -1 # integration time, negative values for auto-detection.\n", "\n", "interlaced = False # assume interlaced data format, for data prior to Dec. 2017\n", "fit_hook = True # fit a hook function to medium gain slope\n", @@ -96,7 +97,9 @@ "%matplotlib inline\n", "\n", "import XFELDetAna.xfelpyanatools as xana\n", - "from cal_tools.agipdlib import get_acq_rate, get_gain_setting, get_num_cells\n", + "from cal_tools.agipdlib import (\n", + " get_acq_rate, get_gain_setting, get_integration_time, get_num_cells\n", + ")\n", "from cal_tools.enums import BadPixels\n", "from cal_tools.plotting import plot_badpix_3d, show_overview\n", "from cal_tools.tools import (\n", @@ -239,7 +242,11 @@ " print(\"Gain setting is not found in the control information\")\n", " print(\"Data will not be processed\")\n", " sequences = []\n", - "print(f\"Gain setting: {gain_setting}\")" + "print(f\"Gain setting: {gain_setting}\")\n", + "\n", + "if integration_time < 0:\n", + " integration_time = get_integration_time(control_fname, h5path_ctrl)\n", + "print(f\"Integration time: {integration_time}\")" ] }, { @@ -584,7 +591,8 @@ " memory_cells=mem_cells,\n", " bias_voltage=bias_voltage,\n", " acquisition_rate=acq_rate,\n", - " gain_setting=gain_setting),\n", + " gain_setting=gain_setting,\n", + " integration_time=integration_time),\n", " np.zeros((128, 512, mem_cells, 3)),\n", " cal_db_interface,\n", " creation_time=creation_time)\n", @@ -596,7 +604,8 @@ " memory_cells=mem_cells,\n", " bias_voltage=bias_voltage,\n", " acquisition_rate=acq_rate,\n", - " gain_setting=gain_setting),\n", + " gain_setting=gain_setting,\n", + " integration_time=integration_time),\n", " np.zeros((128, 512, mem_cells, 3)),\n", " cal_db_interface, creation_time=creation_time)\n", " noises[mod] = np.array(noise.data)\n", @@ -607,7 +616,8 @@ " memory_cells=mem_cells,\n", " bias_voltage=bias_voltage,\n", " acquisition_rate=acq_rate,\n", - " gain_setting=gain_setting),\n", + " gain_setting=gain_setting,\n", + " integration_time=integration_time),\n", " np.zeros((128, 512, mem_cells, 3)),\n", " cal_db_interface, creation_time=creation_time)\n", " thresholds[mod] = np.array(threshold.data)" @@ -1482,6 +1492,7 @@ "print(\"Constants parameter conditions are:\\n\")\n", "print(f\"• memory_cells: {maxcells}\\n• bias_voltage: {bias_voltage}\\n\"\n", " f\"• acquisition_rate: {acq_rate}\\n• gain_setting: {gain_setting}\\n\"\n", + " f\"• integration_time: {integration_time}\\n\"\n", " f\"• creation_time: {md.calibration_constant_version.begin_at if md is not None else creation_time}\\n\")" ] }, diff --git a/src/cal_tools/agipdlib.py b/src/cal_tools/agipdlib.py index 6c2142442f36ab3fec86f97888fec7bc11bd3166..c5a51c2ec7fac3352e49af77e87861ea2d077cef 100644 --- a/src/cal_tools/agipdlib.py +++ b/src/cal_tools/agipdlib.py @@ -165,6 +165,24 @@ def get_bias_voltage(fname: str, karabo_id_control: str, return fin[voltage_path][0] +def get_integration_time(fname: str, h5path_ctrl: str) -> int: + """Read integration time from the FPGA device. + + The integration time is specified as an integer number of clock + cycles each spanning ~9ns. The default (and legacy) value is 12. + + :param fname: path to file with control information + :param h5path_ctrl: path to control information inside the file + :return: integration time + """ + h5path_run = h5path_ctrl.replace('CONTROL/', 'RUN/', 1) + h5path_time = f'{h5path_run}/integrationTime/value' + with h5py.File(fname, 'r') as fd: + if h5path_time in fd: + return int(fd[h5path_time][0]) + return 12 + + class AgipdCorrections: def __init__( @@ -1311,8 +1329,8 @@ class AgipdCorrections: creation_time: 'datetime.datetime', memory_cells: float, bias_voltage: int, photon_energy: float, gain_setting: float, - acquisition_rate: float, module_idx: int, - only_dark: bool = False): + acquisition_rate: float, integration_time: int, + module_idx: int, only_dark: bool = False): """ Initialize calibration constants from the calibration database :param karabo_id: karabo identifier @@ -1324,6 +1342,7 @@ class AgipdCorrections: :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 @@ -1377,6 +1396,7 @@ class AgipdCorrections: photon_energy, beam_energy=None, only_dark=only_dark, + integration_time=integration_time ) cons_data, when = self.retrieve_constant_and_time( diff --git a/src/cal_tools/agipdutils.py b/src/cal_tools/agipdutils.py index 8cf5b4f375d36437f9ccd4f1332d31f5a52fdd9a..e7cbd4667317e0a543ae865ed7e6d8ecaf33d1c6 100644 --- a/src/cal_tools/agipdutils.py +++ b/src/cal_tools/agipdutils.py @@ -20,6 +20,7 @@ def assemble_constant_dict( beam_energy=None, only_dark=False, gain_mode=AgipdGainMode.ADAPTIVE_GAIN, + integration_time=None ): """ Assemble a dictionary with the iCalibrationDB constant names and @@ -34,6 +35,7 @@ def assemble_constant_dict( :param gain_setting: (Float) Gain setting :param acquisition_rate: (Float) Acquisition rate :param photon_energy: (Float) Photon energy + :param integration_time: (Float) Integration time :param beam_energy: (Float) Beam Energy :param only_dark: (Bool) Indicating a retrieval for dark constants only from db :param gain_mode: Operation mode of the detector (default to adaptive gain) @@ -49,6 +51,7 @@ def assemble_constant_dict( "acquisition_rate": acquisition_rate, "gain_setting": gain_setting, "gain_mode": gain_mode, + "integration_time": integration_time, "pixels_x": 512, "pixels_y": 128, }, diff --git a/tests/test_cal_tools.py b/tests/test_cal_tools.py index f17a290197ba0d0cb28707350eff07474e10e3ff..a2e14e86642cf67bef19cf27901a6195f703c642 100644 --- a/tests/test_cal_tools.py +++ b/tests/test_cal_tools.py @@ -21,6 +21,7 @@ from cal_tools.tools import ( ACQ_RATE = 1.1 BIAS_VOLTAGE = 300 GAIN_SETTING = 0 +INTEGRATION_TIME = 12 MEM_CELLS = 352 PHOTON_ENERGY = 9.2 @@ -357,6 +358,7 @@ def test_initialize_from_db(): photon_energy=PHOTON_ENERGY, gain_setting=GAIN_SETTING, acquisition_rate=ACQ_RATE, + integration_time=INTEGRATION_TIME, module_idx=0, only_dark=False, ) @@ -375,6 +377,7 @@ def test_initialize_from_db(): creation_time=creation_time, memory_cells=MEM_CELLS, bias_voltage=BIAS_VOLTAGE, photon_energy=PHOTON_ENERGY, gain_setting=GAIN_SETTING, + integration_time=INTEGRATION_TIME, acquisition_rate=ACQ_RATE, module_idx=0, only_dark=False, )