From f9310371695c3323b5ae0f8361578ad0bd1632db Mon Sep 17 00:00:00 2001 From: gmegh Date: Mon, 15 Apr 2024 16:19:19 -0700 Subject: [PATCH] Add max_noll_index and ts_ofc zn_selected for zk28 --- bin.src/img_closed_loop.py | 1 + doc/versionHistory.rst | 6 +++++ python/lsst/ts/imsim/closed_loop_task.py | 27 +++++++++++++++++-- python/lsst/ts/imsim/imsim_cmpt.py | 33 +++++++++++++++++++++--- tests/test_closed_loop_task.py | 2 ++ tests/test_imsim_cmpt.py | 2 +- 6 files changed, 64 insertions(+), 7 deletions(-) diff --git a/bin.src/img_closed_loop.py b/bin.src/img_closed_loop.py index 1a1e864..93461a9 100644 --- a/bin.src/img_closed_loop.py +++ b/bin.src/img_closed_loop.py @@ -63,4 +63,5 @@ args.raw_seeing, args.imsim_log_file, args.wep_estimator, + args.max_noll_index, ) diff --git a/doc/versionHistory.rst b/doc/versionHistory.rst index db603f4..5b4044f 100644 --- a/doc/versionHistory.rst +++ b/doc/versionHistory.rst @@ -6,6 +6,12 @@ Version History ################## +------------- +1.5.0 +------------- + +* Add max_noll_index argument to control number of Zernikes used. + ------------- 1.4.0 ------------- diff --git a/python/lsst/ts/imsim/closed_loop_task.py b/python/lsst/ts/imsim/closed_loop_task.py index 4c6aeef..49972df 100644 --- a/python/lsst/ts/imsim/closed_loop_task.py +++ b/python/lsst/ts/imsim/closed_loop_task.py @@ -65,6 +65,9 @@ def __init__(self) -> None: # imSim Component self.imsim_cmpt = None + # Maximum Noll index + self.max_noll_index = None + # Ra/Dec/RotAng coordinates used in the simulation. self.boresight_ra = None self.boresight_dec = None @@ -195,6 +198,10 @@ def config_ofc_calc(self, cam_type: CamType) -> None: """ self.ofc_calc = OFC(OFCData(cam_type.value)) + self.ofc_calc.ofc_data.znmin = 3 + self.ofc_calc.ofc_data.zn_selected = np.arange( + self.ofc_calc.ofc_data.znmin, self.max_noll_index + ) def map_filter_ref_to_g(self, filter_type_name: str) -> str: """Map the reference filter to the G filter. @@ -897,7 +904,9 @@ def run_wep( collections=[f"ts_imsim_{seq_num}"], ) - sensor_wavefront_data = SensorWavefrontError() + sensor_wavefront_data = SensorWavefrontError( + num_of_zk=self.max_noll_index - self.ofc_calc.ofc_data.znmin + 1 + ) sensor_name = det_id_map[dataset.dataId["detector"]].getName() sensor_wavefront_data.sensor_name = sensor_name sensor_wavefront_data.sensor_id = det_name_map[sensor_name].getId() @@ -983,6 +992,7 @@ def write_wep_configuration( calcZernikesTask: class: lsst.ts.wep.task.calcZernikesTask.CalcZernikesTask config: + estimateZernikes.maxNollIndex: {self.max_noll_index} python: | from lsst.ts.wep.task import EstimateZernikesTieTask, EstimateZernikesDanishTask config.estimateZernikes.retarget(EstimateZernikes{wep_estimator.value.title()}Task) @@ -1012,6 +1022,7 @@ def run_img( raw_seeing: float, imsim_log_file: str, wep_estimator_method: str, + max_noll_index: int, ) -> None: """Run the simulation of images. @@ -1065,6 +1076,8 @@ def run_img( wep_estimator_method : str Specify the method used to calculate Zernikes in ts_wep. Options are "tie" or "danish". + max_noll_index : int + Maximum Noll index to calculate Zernikes. """ cam_type = CamType(inst) wep_estimator = WepEstimator(wep_estimator_method) @@ -1075,6 +1088,7 @@ def run_img( self.boresight_ra = boresight[0] self.boresight_dec = boresight[1] self.boresight_rot_ang = rot_cam_in_deg + self.max_noll_index = max_noll_index # Remap the reference filter to g filter_type_name = self.map_filter_ref_to_g(filter_type_name) @@ -1095,7 +1109,9 @@ def run_img( cam_type, obs_metadata, path_sky_file=path_sky_file, star_mag=star_mag ) self.config_ofc_calc(cam_type) - self.imsim_cmpt = ImsimCmpt() + self.imsim_cmpt = ImsimCmpt( + num_of_zk=self.max_noll_index - self.ofc_calc.ofc_data.znmin + 1 + ) # If path_sky_file using default OPD positions write this to disk # so that the Butler can load it later @@ -1356,6 +1372,13 @@ def set_default_parser(parser: ArgumentParser) -> ArgumentParser: help="Number of processor to run imSim and DM pipeline. (default: 1)", ) + parser.add_argument( + "--max_noll_index", + type=int, + default=28, + help="Maximum Noll index to calculate Zernikes. (default: 22)", + ) + parser.add_argument( "--wep_estimator", type=str, diff --git a/python/lsst/ts/imsim/imsim_cmpt.py b/python/lsst/ts/imsim/imsim_cmpt.py index f7acdee..ce57ac0 100644 --- a/python/lsst/ts/imsim/imsim_cmpt.py +++ b/python/lsst/ts/imsim/imsim_cmpt.py @@ -48,9 +48,34 @@ class ImsimCmpt: """Class to take configurations for each imsim component and generate full imsim configuration files. + + + Attributes + ---------- + _output_dir : str + Output directory. + _output_img_dir : str + Output image directory. + opd_file_path : str + OPD file path. + opd_metr : lsst.ts.imsim.OpdMetrology + OPD metrology. + num_of_zk : int + Number of Zernikes. + num_of_dof : int + Number of degrees of freedom. + dof_in_um : numpy.ndarray + Degrees of freedom in microns. """ - def __init__(self) -> None: + def __init__(self, num_of_zk: int) -> None: + """Initialize the ImsimCmpt class. + + Parameters + ---------- + num_of_zk : int + Number of Zernikes. + """ # Output directories self._output_dir = None self._output_img_dir = None @@ -60,7 +85,7 @@ def __init__(self) -> None: self.opd_metr = OpdMetrology() # Specify number of Zernikes - self.num_of_zk = 19 + self.num_of_zk = num_of_zk # AOS Degrees of Freedom self.num_of_dof = 50 @@ -523,7 +548,7 @@ def generate_star( mag_norm, sed_name, ) - content += "%.1f %.1f %.1f %.1f %.1f %.1f %s none none \n" % ( + content += "{:.1f} {:.1f} {:.1f} {:.1f} {:.1f} {:.1f} {} none none \n".format( redshift, gamma_1, gamma_2, @@ -649,7 +674,7 @@ def _map_opd_to_zk(self, rot_opd_in_deg: float, num_opd: int) -> np.ndarray: # also fits up to zk28 by default zk = self.opd_metr.get_zk_from_opd(opd_map=opd_rot, zk_terms=28)[0] - # Only need to collect z4 to z22 + # Only need to collect z4 to num_of_zk init_idx = 3 opd_data[idx, :] = zk[init_idx : init_idx + self.num_of_zk] diff --git a/tests/test_closed_loop_task.py b/tests/test_closed_loop_task.py index 9af38d5..a3eda20 100644 --- a/tests/test_closed_loop_task.py +++ b/tests/test_closed_loop_task.py @@ -69,6 +69,7 @@ def test_config_sky_sim_with_sky_file(self): def test_config_ofc_calc(self): cam_type = CamType.LsstCam + self.closed_loop_task.max_noll_index = 28 self.closed_loop_task.config_ofc_calc(cam_type) ofc_calc = self.closed_loop_task.ofc_calc @@ -133,6 +134,7 @@ def test_set_default_parser(self): self.assertEqual(args.pipeline_file, "") self.assertEqual(args.sky_seed, 42) self.assertEqual(args.pert_seed, 11) + self.assertEqual(args.max_noll_index, 28) self.assertEqual(args.wep_estimator, "tie") def test_wep_estimator_args(self): diff --git a/tests/test_imsim_cmpt.py b/tests/test_imsim_cmpt.py index df0a543..a3cf480 100644 --- a/tests/test_imsim_cmpt.py +++ b/tests/test_imsim_cmpt.py @@ -61,7 +61,7 @@ def setUp(self): "r", ) as test_file: self.full_test_yaml = yaml.safe_load(test_file) - self.imsim_cmpt = ImsimCmpt() + self.imsim_cmpt = ImsimCmpt(num_of_zk=19) # Set the output directories self.output_dir = os.path.join(get_module_path(), "tests", "tmp")