From 372f6c031bcf5e6a7002b278296061a300e758fd Mon Sep 17 00:00:00 2001 From: Thomas Kluyver <thomas.kluyver@xfel.eu> Date: Thu, 14 Nov 2024 13:33:56 +0100 Subject: [PATCH] Parameter to drop last frame of each gain stage in LPD parallel gain mode --- notebooks/LPD/LPDChar_Darks_NBC.ipynb | 53 +++++++++++++++------------ 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/notebooks/LPD/LPDChar_Darks_NBC.ipynb b/notebooks/LPD/LPDChar_Darks_NBC.ipynb index ece0a09e0..8a94df8b1 100644 --- a/notebooks/LPD/LPDChar_Darks_NBC.ipynb +++ b/notebooks/LPD/LPDChar_Darks_NBC.ipynb @@ -54,6 +54,8 @@ "ntrains = 500 # maximum number of trains to use in each gain stage\n", "skip_first_ntrains = 10 # Number of first trains to skip\n", "min_trains = 370 # minimum number of trains needed for each gain stage\n", + "drop_last_frames_parallelgain = 1 # Discard last N frames of each gain stage in parallel gain mode\n", + "bad_gain_tolerance_parallelgain = 0.2 # Error if more than this proportion of pixels are in the wrong gain stage in parallel gain mode\n", "\n", "# Parameters for plotting\n", "skip_plots = False # exit after writing corrected files\n", @@ -260,31 +262,34 @@ " im = im.astype(np.float32)\n", " \n", " if is_parallel_gain:\n", - " # Frames in the transition region between the gain stages\n", - " # often have some pixels in the previous gain stage.\n", - " # The proper way would be to use np.median, but this is\n", - " # significantly more expensive and .mean().round() should\n", - " # give the same result.\n", - " gain_by_frame = gains.mean(axis=(1, 2)).round().astype(np.int32)\n", - " \n", - " num_frames_by_gain = np.bincount(gain_by_frame)\n", - " \n", - " if not np.all(num_frames_by_gain == num_frames_by_gain[0]):\n", - " raise ValueError(f'Unequal number of frames per gain stage '\n", - " f'in parallel gain: {num_frames_by_gain}')\n", - " elif len(num_frames_by_gain) != 3:\n", - " raise ValueError(f'Parallel gain contains pixels in {len(num_frames_by_gain)} '\n", - " f'gain stages, expected 3')\n", - " \n", + " if len(cellid_pattern) % 3 != 0:\n", + " raise ValueError(f\"{len(cellid_pattern)} frames per train is not a multiple \"\n", + " \"of 3, as expected in parallel gain mode\")\n", + "\n", " # Always pick cell IDs from high gain,\n", " # as the other gain stages are corrupted.\n", - " cellid = cellid[gain_by_frame == 0]\n", - " \n", - " # By this point the parallel gain assumption is valid.\n", " cellid_pattern = cellid_pattern[:(len(cellid_pattern) // 3)]\n", - " \n", - " # Pick images for the \"right\" gain stage.\n", - " im = im[gain_by_frame == gg]\n", + "\n", + " # (trains, gains, frames)\n", + " frame_indexes = np.arange(len(cellid)).reshape(-1, 3, len(cellid_pattern))\n", + "\n", + " # The last frame in each gain stage is often bad, so we may drop it\n", + " if drop_last_frames_parallelgain:\n", + " cellid_pattern = cellid_pattern[:-drop_last_frames_parallelgain]\n", + " frame_indexes = frame_indexes[..., :-drop_last_frames_parallelgain]\n", + "\n", + " # Cell IDs from high gain, data from the current gain stage\n", + " cellid = cellid[frame_indexes[:, 0].ravel()]\n", + " gains = gains[frame_indexes[:, gg].ravel()]\n", + " im = im[frame_indexes[:, gg].ravel()]\n", + "\n", + " if not np.array_equal(cellid, np.tile(cellid_pattern, len(data.train_ids))):\n", + " raise ValueError(\"Memory cells used are not consistent across trains\")\n", + "\n", + " wrong_gain_fraction = (gains != gg).mean(axis=(1, 2)) # fraction per frame\n", + " if (wrong_gain_fraction > bad_gain_tolerance_parallelgain).any():\n", + " raise ValueError(f\"Frames for gain stage {gg} have up to {wrong_gain_fraction.max()} \"\n", + " f\"pixels in other gain stages (tolerance {bad_gain_tolerance_parallelgain})\")\n", "\n", " elif (gains != gg).any():\n", " raise Exception(f\"Adaptive gain run {run_path} contains pixels \"\n", @@ -1350,9 +1355,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.10" + "version": "3.11.8" } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } -- GitLab