diff --git a/daq/src/mxlibs3/automated_collection_strategy.py b/daq/src/mxlibs3/automated_collection_strategy.py new file mode 100644 index 00000000..72087ef7 --- /dev/null +++ b/daq/src/mxlibs3/automated_collection_strategy.py @@ -0,0 +1,84 @@ +import math + +from aaredaqlib.models import SimpleScanParameters, DAQStatusModel, SimpleStrategyInputModel + +def get_simple_collection_parameters(status:DAQStatusModel, input_params:SimpleStrategyInputModel) -> SimpleScanParameters: + + last_best_res = input_params.last_best_res + last_best_b_factor = input_params.last_best_b_factor + wavelength = status.diffraction.wavelength_angstrom + beam_energy = wavelength* 1.23984193e-4 + temp = input_params.current_temp_k + total_angle = input_params.angular_range + image_angle = input_params.incr_omega_deg + start_angle = input_params.start_angle + d_vis = input_params.d_vis + xtal_size = status.crystal_size + xtal_x = xtal_size.x + xtal_y = xtal_size.y + xtal_z = xtal_size.z + + flux = 2.5e11 # TODO link flux + + if d_vis == 0.0: + d_vis = SimpleStrategyInputModel().d_vis + + d_tar = 1 / (1 / d_vis + 0.1) + + Kdose = 2000 / (wavelength** 2) + + beam_size_um_y = status.geom.beam_size_mm.y * 1000 + beam_size_um_x = status.geom.beam_size_mm.x * 1000 + dose_rate_MGy_s = (flux / (beam_size_um_x * beam_size_um_y * Kdose)) / 1e6 + if xtal_y is None or xtal_z is None or beam_size_um_x is None or beam_size_um_y is None: + xtal_size_dose_rate_MGy_s = dose_rate_MGy_s + + elif xtal_y > beam_size_um_y or xtal_z > beam_size_um_y: + multiplier_1 = max(xtal_y, beam_size_um_y) + multiplier_2 = max(xtal_z, beam_size_um_y) + new_beam_um_y = math.sqrt(multiplier_1 * multiplier_2) + xtal_size_dose_rate_MGy_s = (flux / (beam_size_um_x * new_beam_um_y * Kdose)) / 1e6 + + else: + xtal_size_dose_rate_MGy_s = dose_rate_MGy_s + + if temp > 250: + target_dose_MGy = 0.1 * d_tar / 2.0 + else: + target_dose_MGy = 10 * d_tar / 2.0 + + total_time_s = target_dose_MGy / dose_rate_MGy_s + + if image_angle == 0.0: + image_angle = 0.001 + n_images = round(total_angle / image_angle) + image_time_s = total_time_s / n_images + if image_time_s < 0.01: + transmission = image_time_s / 0.01 + image_time_s = 0.01 + else: + transmission = 1.0 + + dtz = status.diffraction.calc_dtz_mm(d_tar) + filename = input_params.filename if input_params.filename else "auto_scan" + + return SimpleScanParameters( + dtz=int(round(dtz)), + exp_time_s=image_time_s, + start_omega_deg=start_angle, + incr_omega_deg=image_angle, + steps=n_images, + transmission=transmission, + last_best_res=last_best_res, + last_best_b_factor=last_best_b_factor, + filename=input_params.filename, + crystal_size = xtal_size, + flux_ph_s = flux, + calculated_dose_rate_MGy_s = dose_rate_MGy_s, + xtal_size_dose_rate_MGy_s = xtal_size_dose_rate_MGy_s, + target_dose_MGy=target_dose_MGy, + beam_size_x_um = beam_size_um_x, + beam_size_y_um = beam_size_um_y, + d_vis = d_vis, + d_tar = d_tar, + ) \ No newline at end of file