def __init__(self, args): super(OpenClosedLoopProcedure, self).__init__() self.args = args self.calibr = CalibrationTables() # This is used when the user specifies the switch --print-biases self.used_biases = []
def run(self): calibr = CalibrationTables() for cur_board in STRIP_BOARD_NAMES: # Append the sequence of commands to turnon this board to # the JSON object self.command_emitter.command_list += self.turn_on_board(cur_board) # Wait a while after having turned on the board self.wait(seconds=5) # Verification step with StripTag( conn=self.command_emitter, name=f"PINCHOFF_VERIFICATION_1", ): self.wait(seconds=300) for cur_board in STRIP_BOARD_NAMES: # Now run the pinch-off procedure for each board with StripTag( conn=self.command_emitter, name=f"PINCHOFF_TILE_{cur_board}", ): for cur_horn_idx in range(8): if cur_board == "I" and cur_horn_idx == 7: continue if cur_horn_idx == 7: cur_horn_name = BOARD_TO_W_BAND_POL[cur_board] else: cur_horn_name = f"{cur_board}{cur_horn_idx}" self.conn.enable_electronics(polarimeter=cur_horn_name, pol_mode=5) for id_value_muA in (100, 4_000, 8_000, 12_000): for cur_lna in ("HA3", "HA2", "HA1", "HB3", "HB2", "HB1"): # Convert the current (μA) in ADU adu = calibr.physical_units_to_adu( polarimeter=cur_horn_name, hk="idrain", component=cur_lna, value=id_value_muA, ) self.conn.set_id(cur_horn_name, cur_lna, value_adu=adu) with StripTag( conn=self.command_emitter, name= f"PINCHOFF_IDSET_{cur_horn_name}_{cur_lna}_{id_value_muA:.0f}muA", ): self.conn.wait(seconds=18)
def test_calibration(): try: cal_tables = CalibrationTables() except InputLogin: # We're probably running on Travis, so just forget about it return assert cal_tables.physical_units_to_adu("R0", "idrain", "HA1", 1000) == 180 # W3 belongs to the R board assert cal_tables.physical_units_to_adu("W3", "vdrain", "HA1", 156) == 256
def _forward( self, calibr: CalibrationTables, cur_board: str, pol_name: str, unit_test_data: UnitTestDC, proc_number: int, ): for pin, ps, phsw_state in PIN_PS_STATE_COMBINATIONS: # First do a stable acquisition… self._stable_acquisition(pol_name, phsw_state, proc_number=proc_number) # …and then acquire the curves try: Ifor = get_sequence_of_biases(unit_test_data, ps, "IFVF") except KeyError: log.warning(f"IFVF does not exist for {pol_name} {ps}") self.conn.log( message= f"IFVF does not exist for {pol_name} {ps} in unit-level tests. " "Using a synthetic curve instead") Ifor = get_sequence_of_biases(None, ps, "IFVF") Ifor *= 1e6 # Convert from A to µA self.conn.log( message= f"Acquiring PH/SW forward curve for {pol_name}, {ps} Vpin{pin}" ) with StripTag( conn=self.command_emitter, name= f"phsw_proc{proc_number}_fcurve_{pol_name}_{ps}_ipin{pin}", ): for i in Ifor: adu = calibr.physical_units_to_adu(pol_name, hk="iphsw", component=pin, value=i) self.conn.set_phsw_bias(pol_name, phsw_index=pin, vpin_adu=None, ipin_adu=adu) self.conn.set_hk_scan(cur_board) self.conn.log(message=f"Set I={i:.1f} µA = {adu} ADU") wait_with_tag( conn=self.command_emitter, seconds=5, name= f"phsw_proc{proc_number}_set_i_{pol_name}_{ps}_vpin{pin}", )
def _reverse( self, calibr: CalibrationTables, cur_board: str, pol_name: str, unit_test_data: UnitTestDC, proc_number: int, ): for pin, ps, phsw_state in PIN_PS_STATE_COMBINATIONS: # First do a stable acquisition… self.stable_acquisition(pol_name, phsw_state) # …and then acquire the curves try: Vrev = get_sequence_of_biases(unit_test_data, ps, "IRVR") except KeyError: log.warning(f"IRVR does not exist for {pol_name} {ps}") self.conn.log( message= f"IRVR does not exist for {pol_name} {ps} in unit-level tests. " "Using a synthetic curve instead") Vrev = get_sequence_of_biases(None, ps, "IRVR") Vrev *= 1e3 # convert from V to mV self.conn.log( message= f"Acquiring PH/SW reverse curve for {pol_name}, {ps} Vpin{pin}" ) with StripTag( conn=self.command_emitter, name= f"phsw_proc{proc_number}_rcurve_{pol_name}_{ps}_ipin{pin}", ): for v in Vrev: adu = calibr.physical_units_to_adu(pol_name, hk="vphsw", component=pin, value=v) self.conn.set_phsw_bias(pol_name, phsw_index=pin, vpin_adu=adu, ipin_adu=None) self.conn.set_hk_scan(cur_board) self.conn.log(message=f"Set V={v:.1f} mV = {adu} ADU") wait_with_tag( conn=self.command_emitter, seconds=5, name= f"phsw_proc{proc_number}_set_v_{pol_name}_{ps}_vpin{pin}", )
def run(self): calibr = CalibrationTables() # Open loop test if self.args.open_loop_filename: biases_per_pol = self.read_biases_per_pol( self.args.open_loop_filename, "OPEN_LOOP") self.run_open_loop_test(self.args.polarimeters, biases_per_pol) # Closed loop test if self.args.closed_loop_filename: biases_per_pol = self.read_biases_per_pol( self.args.closed_loop_filename, "CLOSED_LOOP") self.run_closed_loop_test(self.args.polarimeters, biases_per_pol)
class OpenClosedLoopProcedure(StripProcedure): def __init__(self, args): super(OpenClosedLoopProcedure, self).__init__() self.args = args self.calibr = CalibrationTables() # This is used when the user specifies the switch --print-biases self.used_biases = [] def turn_on_polarimeters(self, polarimeters): log.info(f"Turnon of polarimeters {0}".format(", ".join( [str(x) for x in polarimeters]))) turnon_proc = TurnOnOffProcedure(waittime_s=1.0, stable_acquisition_time_s=1.0, turnon=True) turn_on_board = True for cur_polarimeter in polarimeters: board = normalize_polarimeter_name(cur_polarimeter)[0] turnon_proc.set_board_horn_polarimeter(new_board=board, new_horn=cur_polarimeter, new_pol=None) turnon_proc.run_turnon(stable_acquisition_time_s=1.0, turn_on_board=turn_on_board) turn_on_board = False return turnon_proc.get_command_list() def _run_test( self, test_name, polarimeters, biases_per_pol: Dict[str, BiasConfiguration], sequence, ): # This method is used internally to implement both the # open-loop and closed-loop tests for cur_pol in polarimeters: # Append the sequence of commands to turnon all the polarimeters # to the JSON commands self.command_emitter.command_list += self.turn_on_polarimeters( [cur_pol]) if test_name == "OPEN_LOOP": self.conn.set_pol_mode(cur_pol, OPEN_LOOP_MODE) else: self.conn.set_pol_mode(cur_pol, CLOSED_LOOP_MODE) cur_biases = biases_per_pol[cur_pol]._asdict() self.used_biases.append({ "polarimeter": cur_pol, "test_name": test_name, "calibrated_biases": {key: val for (key, val) in cur_biases.items() if val}, }) bias_repr = ", ".join([ f"{key}={val:.1f}" for (key, val) in cur_biases.items() if val ]) with StripTag( conn=self.command_emitter, name=f"{test_name}_TEST_SETUP_{cur_pol}", comment=f"(calibrated) biases are: {bias_repr}", ): for component, param, key in sequence: params = { "polarimeter": cur_pol, "lna": component, "value_adu": self.calibr.physical_units_to_adu( polarimeter=cur_pol, hk=key, component=component, value=cur_biases[param], ), } if key == "vdrain": self.conn.set_vd(**params) elif key == "idrain": self.conn.set_id(**params) elif key == "vgate": self.conn.set_vg(**params) if not self.args.acquisition_at_end: with StripTag( conn=self.command_emitter, name=f"{test_name}_TEST_ACQUISITION_{cur_pol}", comment=f"Stable acquisition for polarimeter {cur_pol}", ): self.conn.wait(seconds=self.args.wait_time_s) if self.args.acquisition_at_end: with StripTag( conn=self.command_emitter, name=f"{test_name}_TEST_ACQUISITION", comment="Stable acquisition with polarimeters {pols}". format(pols=", ".join(polarimeters)), ): self.conn.wait(seconds=self.args.wait_time_s) def run_open_loop_test(self, polarimeters, biases_per_pol: Dict[str, BiasConfiguration]): self._run_test( test_name="OPEN_LOOP", polarimeters=polarimeters, biases_per_pol=biases_per_pol, sequence=[ ("H0", "vd0", "vdrain"), ("H1", "vd1", "vdrain"), ("H2", "vd2", "vdrain"), ("H3", "vd3", "vdrain"), ("H4", "vd4", "vdrain"), ("H5", "vd5", "vdrain"), ("H0", "vg0", "vgate"), ("H1", "vg1", "vgate"), ("H2", "vg2", "vgate"), ("H3", "vg3", "vgate"), ("H4", "vg4", "vgate"), ("H4A", "vg4a", "vgate"), ("H5A", "vg5a", "vgate"), ], ) def run_closed_loop_test(self, polarimeters, biases_per_pol: Dict[str, BiasConfiguration]): self._run_test( test_name="CLOSED_LOOP", polarimeters=polarimeters, biases_per_pol=biases_per_pol, sequence=[ ("H0", "id0", "idrain"), ("H1", "id1", "idrain"), ("H2", "id2", "idrain"), ("H3", "id3", "idrain"), ("H4", "id4", "idrain"), ("H5", "id5", "idrain"), ("H0", "vg0", "vgate"), ("H1", "vg1", "vgate"), ("H2", "vg2", "vgate"), ("H3", "vg3", "vgate"), ("H4", "vg4", "vgate"), ("H4A", "vg4a", "vgate"), ("H5A", "vg5a", "vgate"), ], ) def read_biases_per_pol(self, filename, test_name): if str(filename).startswith("http"): assert len(self.args.polarimeters) == 1 biases_per_pol = retrieve_biases_from_url( polarimeter_name=self.args.polarimeters[0], url=str(filename)) else: if filename.suffix == ".h5": biases_per_pol = retrieve_biases_from_hdf5( polarimeters=self.args.polarimeters, test_name=test_name, filename=filename, tag_template=self.args.tag_template, calibr=self.calibr, ) else: biases_per_pol = instrument_biases_to_dict( polarimeters=self.args.polarimeters, biases=InstrumentBiases(filename), ) return biases_per_pol def run(self): # Open loop test if self.args.open_loop_filename: biases_per_pol = self.read_biases_per_pol( self.args.open_loop_filename, "OPEN_LOOP") self.run_open_loop_test(self.args.polarimeters, biases_per_pol) # Closed loop test if self.args.closed_loop_filename: biases_per_pol = self.read_biases_per_pol( self.args.closed_loop_filename, "CLOSED_LOOP") self.run_closed_loop_test(self.args.polarimeters, biases_per_pol) def output_biases(self): print(json.dumps(self.used_biases, indent=4))
def __init__(self, turn_on_polarimeters, wait_time_s, long_wait_time_s): super().__init__() self.calib = CalibrationTables() self.turn_on_polarimeters = turn_on_polarimeters self.wait_time_s = wait_time_s self.long_wait_time_s = long_wait_time_s
def __init__(self, wait_time_s): super(ReferenceTestProcedure, self).__init__() self.calib = CalibrationTables() self.wait_time_s = wait_time_s
def run(self): # Turn on the polarimeter(s) for cur_board in STRIP_BOARD_NAMES: # Append the sequence of commands to turnon this board to # the JSON object # self.command_emitter.command_list += self.turn_on_board(cur_board) pass # Verification step with StripTag( conn=self.command_emitter, name="IVTEST_VERIFICATION_TURNON", ): # Wait a while after having turned on all the boards self.wait(seconds=10) # Load the matrices of the unit-test measurements done in # Bicocca and save them in "self.bicocca_data" self.bicocca_test = get_unit_test(args.bicocca_test_id) module_name = InstrumentBiases().polarimeter_to_module_name( self.bicocca_test.polarimeter_name) log.info( "Test %d for %s (%s) loaded from %s, is_cryogenic=%s", args.bicocca_test_id, self.bicocca_test.polarimeter_name, module_name, self.bicocca_test.url, str(self.bicocca_test.is_cryogenic), ) self.bicocca_data = load_unit_test_data(self.bicocca_test) assert isinstance(self.bicocca_data, UnitTestDC) log.info( " The polarimeter %s corresponds to module %s", self.bicocca_test.polarimeter_name, module_name, ) calibr = CalibrationTables() defaultBias = InstrumentBiases() lna_list = get_lna_list(pol_name=self.bicocca_test.polarimeter_name) #--> First test: ID vs VD --> For each VG, we used VD curves self.conn.tag_start(name=f"IVTEST_IDVD_{module_name}") for lna in lna_list: lna_number = get_lna_num(lna) #Read default configuration with StripTag( conn=self.command_emitter, name=f"{module_name}_{lna}_READDEFAULT_VGVD", ): # read bias in mV default_vg_adu = calibr.physical_units_to_adu( polarimeter=module_name, hk="vgate", component=lna, value=defaultBias.get_biases(module_name, param_hk=f"VG{lna_number}"), ) # read bias in mV default_vd_adu = calibr.physical_units_to_adu( polarimeter=module_name, hk="vdrain", component=lna, value=defaultBias.get_biases(module_name, param_hk=f"VD{lna_number}"), ) #Get the data matrix and the Gate Voltage vector. matrixIDVD = self.bicocca_data.components[lna].curves["IDVD"] #from V to mV vgate = np.mean(matrixIDVD["GateV"], axis=0) * 1000 selvg = vgate >= -360 vgate = vgate[selvg] # For each Vg, we have several curves varing Vd for vg_idx, vg in enumerate(vgate): vg_adu = calibr.physical_units_to_adu( polarimeter=module_name, hk="vgate", component=lna, value=vg, ) self.conn.set_vg( polarimeter=module_name, lna=lna, value_adu=vg_adu, ) #from V to mV curve_vdrain = matrixIDVD["DrainV"][:, vg_idx] * 1000 for vd_idx, vd in enumerate(curve_vdrain): vd_adu = calibr.physical_units_to_adu( polarimeter=module_name, hk="vdrain", component=lna, value=vd, ) self.conn.set_vd( polarimeter=module_name, lna=lna, value_adu=vd_adu, ) with StripTag( conn=self.command_emitter, name= f"{module_name}_{lna}_SET_VGVD_{vg_idx}_{vd_idx}", comment=f"VG_{vg:.2f}mV_VD_{vd:.2f}mV", ): self.conn.set_hk_scan(allboards=True) self.conn.wait(self.waittime_perconf_s) # Back to the default values of vd and vg (for each LNA) with StripTag( conn=self.command_emitter, name=f"{module_name}_{lna}_BACK2DEFAULT_VGVD", ): self.conn.set_vg( polarimeter=module_name, lna=lna, value_adu=default_vg_adu, ) self.conn.set_vd( polarimeter=module_name, lna=lna, value_adu=default_vd_adu, ) self.conn.wait(self.waittime_perconf_s) self.conn.tag_stop(name=f"IVTEST_IDVD_{module_name}") # #--> Second test: ID vs VG --> For each VD, we used VG curves self.conn.tag_start(name=f"IVTEST_IDVG_{module_name}") for lna in lna_list: lna_number = get_lna_num(lna) #Read default configuration with StripTag( conn=self.command_emitter, name=f"{module_name}_{lna}_READDEFAULT_VDVG", ): # read bias in mV default_vg_adu = calibr.physical_units_to_adu( polarimeter=module_name, hk="vgate", component=lna, value=defaultBias.get_biases(module_name, param_hk=f"VG{lna_number}"), ) # read bias in mV default_vd_adu = calibr.physical_units_to_adu( polarimeter=module_name, hk="vdrain", component=lna, value=defaultBias.get_biases(module_name, param_hk=f"VD{lna_number}"), ) #Get the data matrix and the Gate Voltage vector. matrixIDVG = self.bicocca_data.components[lna].curves["IDVG"] #from V to mV vdrain = np.mean(matrixIDVG["DrainV"], axis=0) * 1000 # For each Vd, we have several curves varing Vg for vd_idx, vd in enumerate(vdrain): vd_adu = calibr.physical_units_to_adu( polarimeter=module_name, hk="vdrain", component=lna, value=vd, ) self.conn.set_vg( polarimeter=module_name, lna=lna, value_adu=vd_adu, ) #from V to mV curve_vgate = matrixIDVG["GateV"][:, vd_idx] * 1000. selcurvg = curve_vgate >= -360 curve_vgate = vgate[selvg] for vg_idx, vg in enumerate(curve_vgate): vg_adu = calibr.physical_units_to_adu( polarimeter=module_name, hk="vgate", component=lna, value=vg, ) self.conn.set_vd( polarimeter=module_name, lna=lna, value_adu=vg_adu, ) with StripTag( conn=self.command_emitter, name=f"{module_name}_{lna}_VDVG_{vd_idx}_{vg_idx}", comment=f"VD_{vd:0.2f}mV_VG_{vg:.2f}mV", ): # self.conn.set_hk_scan(allboards=True) self.conn.wait(self.waittime_perconf_s) # Back to the default values of vd and vg (for each LNA) with StripTag( conn=self.command_emitter, name=f"IVTEST_IDVG_{module_name}_{lna}_BACK2DEFAULT_VDVG", ): self.conn.set_vg( polarimeter=module_name, lna=lna, value_adu=default_vg_adu, ) self.conn.set_vd( polarimeter=module_name, lna=lna, value_adu=default_vd_adu, ) self.conn.wait(self.waittime_perconf_s) self.conn.tag_stop(name=f"IVTEST_IDVG_{module_name}")
def run(self): # Turn on the polarimeter(s) for cur_board in STRIP_BOARD_NAMES: # Append the sequence of commands to turnon this board to # the JSON object # self.command_emitter.command_list += self.turn_on_board(cur_board) pass # Verification step with StripTag(conn=self.command_emitter, name="IVTEST_VERIFICATION_TURNON"): # Wait a while after having turned on all the boards self.wait(seconds=10) # Load the matriix with the min, max and step for # each LNA for each polarimeter count_conf = 0 for pol_name in self.polarimeters: module_name = self.inputBiasIV["Module"][pol_name] log.info("-->Polarimeter %s (%s)", pol_name, module_name) calibr = CalibrationTables() defaultBias = InstrumentBiases() lna_list = get_lna_list(pol_name=pol_name) # --> First test: ID vs VD --> For each VG, we used VD curves self.conn.tag_start(name=f"IVTEST_{module_name}") for lna in lna_list: lna_number = get_lna_num(lna) # Read default configuration with StripTag( conn=self.command_emitter, name=f"{module_name}_{lna}_READDEFAULT_VGVD", ): # read bias in mV default_vg_adu = calibr.physical_units_to_adu( polarimeter=module_name, hk="vgate", component=lna, value=getattr(defaultBias.get_biases(module_name), f"vg{lna_number}"), ) # read bias in mV default_vd_adu = calibr.physical_units_to_adu( polarimeter=module_name, hk="vdrain", component=lna, value=getattr(defaultBias.get_biases(module_name), f"vd{lna_number}"), ) # Get the data matrix and the Gate Voltage vector. # in mV vgate = self.get_bias_curve(pol_name, lna) vdrain = np.arange(0, 900, 50) count_conf += len(vgate) * len(vdrain) # For each Vg, we have several curves varing Vd for vg_idx, vg in enumerate(vgate): vg_adu = calibr.physical_units_to_adu( polarimeter=module_name, hk="vgate", component=lna, value=vg) self.conn.set_vg(polarimeter=module_name, lna=lna, value_adu=vg_adu) for vd_idx, vd in enumerate(vdrain): vd_adu = calibr.physical_units_to_adu( polarimeter=module_name, hk="vdrain", component=lna, value=vd, ) self.conn.set_vd(polarimeter=module_name, lna=lna, value_adu=vd_adu) with StripTag( conn=self.command_emitter, name= f"{module_name}_{lna}_SET_VGVD_{vg_idx}_{vd_idx}", comment=f"VG_{vg:.2f}mV_VD_{vd:.2f}mV", ): if self.hk_scan == "True": # print(f"hk_scan is {self.hk_scan}") self.conn.set_hk_scan(allboards=True) self.conn.wait(self.waittime_perconf_s) # Back to the default values of vd and vg (for each LNA) with StripTag( conn=self.command_emitter, name=f"{module_name}_{lna}_BACK2DEFAULT_VGVD", ): self.conn.set_vg(polarimeter=module_name, lna=lna, value_adu=default_vg_adu) self.conn.set_vd(polarimeter=module_name, lna=lna, value_adu=default_vd_adu) self.conn.wait(self.waittime_perconf_s) count_conf += 1 self.conn.tag_stop(name=f"IVTEST_IDVD_{module_name}") log.info( "Number of configuration and time [hrs, days]: %s [%s, %s]\n", int(count_conf), np.around(count_conf * self.waittime_perconf_s / 3600.0, 1), np.around(count_conf * self.waittime_perconf_s / 3600 / 24, 3), )
def run_proc2(self): calibr = CalibrationTables() if self.turn_on: turnon_proc = TurnOnOffProcedure( waittime_s=1.0, turnon=True, bias_file_name=self.bias_file_name, ) with StripTag(conn=self.command_emitter, name="phsw_proc2_turnon_pol"): for cur_board, pol_idx, pol_name in polarimeter_iterator( args.board): # turnon pol turnon_proc.set_board_horn_polarimeter( new_board=cur_board, new_horn=pol_name, new_pol=None, ) turnon_proc.run() self.command_emitter.command_list += turnon_proc.get_command_list( ) turnon_proc.clear_command_list() self.conn.wait(seconds=self.pre_acquisition_time_s) for cur_board, pol_idx, pol_name in polarimeter_iterator(args.board): self._stable_acquisition(pol_name, "1111", proc_number=2) wait_with_tag( conn=self.command_emitter, seconds=self.pre_acquisition_time_s, name=f"acquisition_unsw0101_pol{pol_name}", ) # curves test_num, unit_test_data = load_unit_level_test( self.pol_unittest_associations, pol_name, no_unit_level_tests=self.no_unit_level_tests, cryo=self.cryo, ) if self.no_unit_level_tests: self.conn.log( f"The ph/sw test #2 for polarimeter {pol_name} is *not* based on unit-level tests" ) else: assert unit_test_data is not None self.conn.log( f"The ph/sw test #2 for polarimeter {pol_name} is based on unit test #{test_num}" ) if self.reverse_test: self._reverse(calibr, cur_board, pol_name, unit_test_data, proc_number=2) if self.forward_test: self._forward(calibr, cur_board, pol_name, unit_test_data, proc_number=2) self._restore_phsw_state(pol_name, proc_number=1)