// Compute pattern angle of a vector on the sky double procedure AngleFromVector { {double,double} vector = {1.0,1.0}; // Vector }{ double degpi = 180.0 / 3.14159265; double fullcircle = 360.0; double angle = atan2(vector{0},vector{1}) * degpi; // translate into range between 0 and 360 degrees angle = (angle + fullcircle) % fullcircle; return angle; } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the OTF observing mode procedure OTFmap_commanding { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // chunk size given by the data rates and optimum speed int nlines_tot = 1; // Total number of lines to scan int n_linesperscan = 1; // Number of lines between two OFFs int n_intoff = 3; // Number of data dumps for the OFF integration time int n_pp = 10; // Number of data dumps per line int n_loadinterval = 1; // number of nods before a load measurement int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,2,2,40,10,20,21,0]; // Timing of the observation from telescope int loadlength = 21; // Load duration }{ // Auxiliary variables // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time int toffslew = telescopetimes[6]; // slew dead time between points //////////////////////////////////////////////////////////////////////// // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // // Clustering is currently not implemented in MPS - switched off here int clustered = 0; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] rates = dataparms{1}; int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); // Count OFFs by hand, their counter is not returned in the state array int ioff = 0; //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 1) { // Initialization if(clustered != 1) { HIFIInitObs(); TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal"); } delay(tinitslew - (time() - startobs) - loadlength - hkduration); // First load measurement HIFISetHK("normal",false); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } if(state[0] == 4) { // OFF Integration HIFIConfigureContIntegration(data_time,n_intoff,band,lo_freq,backendreadoutparms); HIFIContOffIntegration(data_time,n_intoff,rates); // OFF counter ioff = ioff + 1; // Check for normal slew after OFF if(state[2] * state[3] < nlines_tot) { HIFIActiveHK("normal",toffslew); } } if(state[0] == 8) { // OTF integration // Check whether we come from the OFF if((state[2] + n_linesperscan - 1) % n_linesperscan == 0) { HIFIConfigureContIntegration(data_time,n_pp,band,lo_freq,backendreadoutparms); } HIFIContOnIntegration(data_time,n_pp,rates); // Check for normal slew towards the OFF if(state[2] % n_linesperscan == 0) { if(ioff % n_loadinterval > 0) { HIFIActiveHK("normal",toffslew); } } } if(state[0] == 9) { // Load slew delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } if(state[0] == 5) { // Final hold - close observation delay(readoutdead); HIFICloseObs(); } } } ////////////////////////////////////////////////////////////////// // Procedure to compute detailed pre timing for the version of the // frequency switch mode with baseline measurement // {int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int} procedure FSwitch_pre_timing { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4 in [1,20]; // data dump interval limited by the data rates int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_chop_on = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles on ON int n_chop_off = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles on OFF int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF calibration cycles int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // First check validity of frequencies CheckLOFrequencies(band,lo_freq + min(freq_throw,0.0),lo_freq + max(freq_throw,0.0)); // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // First perform consistency checks // Check chunk size given by the data rates CheckDataTaking(backendreadoutparms,data_time); CheckDataTaking(backendreadoutparms,data_time_off); CheckFswOutOfBand(band,lo_freq,freq_throw,backendreadoutparms); int jitterdead = GetMaxTimeJitter(band,lo_freq); // Compute parameters for the instrument timing int on_inttime = 2 * n_chop_on * data_time; int off_inttime = 2 * n_chop_off * data_time_off; // compute load integration time int loadlength = duration(DoubleLoadMeasurement(band,lo_freq,freq_throw,eff_resolution{0},data_time,backendreadoutparms)); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); loadlength = loadlength + readoutdead; // For double phases I can use the added jitterdead in both phases for load int halfloadlength = (loadlength - jitterdead + 1) / 2; // Compare load interval and position switch interval int load_spacing = CheckedLoadSpacing(load_interval - loadlength,8); int n_load_on = on_inttime / load_spacing; int n_load_off = off_inttime / load_spacing; // This determines the order of the loops if(load_spacing > 2 * on_inttime) { int n_per_on = n_chop_on; bool end_load_on = false; int on_pointing = on_inttime + jitterdead; } else { n_per_on = n_chop_on / (n_load_on + 1); if(n_per_on < 1) { SError("FS phase length on source too long relative to load period."); } end_load_on = true; on_inttime = 2 * n_per_on * (n_load_on + 1) * data_time; on_pointing = on_inttime + halfloadlength + n_load_on * loadlength + jitterdead; } if(load_spacing > 2 * off_inttime) { int n_per_off = n_chop_off; bool end_load_off = false; int off_pointing = off_inttime + jitterdead; } else { n_per_off = n_chop_off / (n_load_off + 1); if(n_per_off < 1) { SError("FS phase length on OFF position too long relative to load period."); } end_load_off = true; off_inttime = 2 * n_per_off * (n_load_off + 1) * data_time_off; off_pointing = off_inttime + halfloadlength + n_load_off * loadlength + jitterdead; } // Duration of initial set up // determine exact duration only in case of full commanding if(docommands) { int initlength = duration(HIFIInitObs()); initlength = initlength + duration(TuneHIFIFsw(band,lo_freq,freq_throw,hrs1,hrs2,wbs1{0},wbs2{0},"normal")); // Add time for HK readout int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); initlength = initlength + hkduration; } else { initlength = GetRoughInitLength(band,lo_freq,true); } initlength = initlength + loadlength; // Compute the overall cycle length // First estimate of the load interval int n_loadinterval = imax(load_interval / (on_pointing + off_pointing),1); // Exception handling for very uneven phases if(end_load_on || end_load_off) { n_loadinterval = 1; } // dangling time given by readout dead time int dangling = readoutdead; // Return all the times needed for telescope call and post_timing processing return {on_inttime,off_inttime,on_pointing,off_pointing,loadlength,jitterdead,load_spacing,n_loadinterval,n_per_on,n_per_off,n_load_on,n_load_off,end_load_on,end_load_off,initlength,dangling}; } // HBB Response time, procedure procedure HBB_Response_time_proc_fm { }{ error("Cannot be used in warm context"); // //It just configures the FPU, setting the HBB at the required temp. //Then we just wait for the temperature to stabilize to the final value... //For the sake of simplicity, we use Band0 parameters. Band0_hbb_on_fm("0","CLOSE"); // } //Set LCU back to standby status without setting any particular LO band, block //LCU is only set to standby if the band has been switched off block LCU_standby_block_aot HIFI 6629 { }{ {double,string}[] result = ConfigurationReader("name_delays",["stdby_delay"],"0",0.0); int stdby_delay = iround(result[0]{0}); // //Set in standby mode Hifi_HIFI_HL_Standby($BBID); delay(stdby_delay); } //Heater setting in manual commanding mode HifiManCmd_Set_HL_Heater { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! }{ mois_comment("Procedure for LOU heater setting adjustement"); StartMode_block_ops(); // mois_step("Set heater voltage"); mois_spacon("In the next TC, the heater voltage HP397194 should be treated as an FP"); HL_heater_block_fm("1a","nominal"); // StopMode_block_ops(); // -> to issue last obsd/bbid } // IV curve, block block IVcurve_pumped_fm HIFI 3213 { string band = "1a"; double lo_freq = 522.0; //LO frequency }{ //Start_block() ; {double,string}[] result_d = ConfigurationReader("name_confilfpu",["bias_min_h","bias_max_h","bias_steps_h","bias_min_v","bias_max_v","bias_steps_v"],band,0.0); //H polar double bias_min_h = result_d[0]{0}; double bias_max_h = result_d[1]{0}; int steps_h = iround(result_d[2]{0}); //V polar double bias_min_v = result_d[3]{0}; double bias_max_v = result_d[4]{0}; int steps_v = iround(result_d[5]{0}); //Nominal bias set at the end result_d = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); double bias_h = result_d[0]{0}; double bias_v = result_d[1]{0}; double magnetcurrent_h = 0.0; double magnetcurrent_v = 0.0; // if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); magnetcurrent_h = result_d[0]{0}; magnetcurrent_v = result_d[1]{0}; } // //The IVCurve is done on the smallest range and the finest step double bias_min = max(bias_min_h,bias_min_v); double bias_max = min(bias_max_h,bias_max_v); int steps = iround(max(double(steps_h),double(steps_v))); // //First set magnets to max. double magnet_current_max_h = 0.0; double magnet_current_max_v = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,0.0); magnet_current_max_h = result_d[0]{0}; magnet_current_max_v = result_d[1]{0}; } Hifi_HIFI_CH1_MX_MG_C($BBID,magnet_current_max_h); Hifi_HIFI_CV1_MX_MG_C($BBID,magnet_current_max_v); delay(1); //Perform IV curve IVcurve(band,bias_min,bias_max,steps,magnetcurrent_h,magnetcurrent_v,bias_h,bias_v); } //Notify PDU status OFF, procedure procedure HIFI_notify_PDU_status_off_proc_ops { string status_FCU = "OFF" in ["ON","OFF"]; //Status of FCU string status_LCU = "OFF" in ["ON","OFF"]; //Status of LCU string status_WBSV = "OFF" in ["ON","OFF"]; //Status of WBSV string status_WBSH = "OFF" in ["ON","OFF"]; //Status of WBSH string status_HRSV = "OFF" in ["ON","OFF"]; //Status of HRSV string status_HRSH = "OFF" in ["ON","OFF"]; //Status of HRSH }{ Hifi_HIFI_notify_PDU_status(status_FCU,status_LCU,status_WBSV,status_WBSH,status_HRSV,status_HRSH); //Prepare message for operator: we will check whether one particular HK is ON if(status_FCU == "OFF") { string subsyst_off = "HI_FCU_S"; } if(status_WBSH == "OFF") { subsyst_off = "HI_WBSH_S"; } if(status_WBSV == "OFF") { subsyst_off = "HI_WBSV_S"; } if(status_HRSH == "OFF") { subsyst_off = "HI_HRSH_S"; } if(status_HRSV == "OFF") { subsyst_off = "HI_HRSV_S"; } if(status_LCU == "OFF") { subsyst_off = "HI_LCU_S"; } mois_tmcheck("Check that the HK parameter " + subsyst_off + " is OFF."); delay(1); } //Peak test configuration, block block Peakup_test_configure_block_fm HIFI 3820 { string band = "1" in ["1","2","3","4","5","6","7"]; // HIFI band string mixer_polarization = "H" in ["H","V"]; //mixer polarization to be used }{ //Start_block(); //Get offset of observed aperture wrt band 6H string tab = "peakup_offset.config"; double peakup_scale_y = dlookup(tab,"" + band,"scale_y"); double peakup_scale_z = dlookup(tab,"" + band,"scale_z"); double offset_y = dlookup(tab,"" + band,"offset_y_H"); double offset_z = dlookup(tab,"" + band,"offset_z_H"); if(mixer_polarization == "V") { offset_y = dlookup(tab,"" + band,"offset_y_V"); offset_z = dlookup(tab,"" + band,"offset_z_V"); } // Hifi_HIFI_configure_peakup_r1($BBID,iround(peakup_scale_y),iround(peakup_scale_z),iround(offset_y),iround(offset_z)); //no delay ? tests with fm_cus_12.7 show that 1sec may be not enough delay(2); } // common statistics messages procedure PerformanceMessages { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz int totaltime = 180; // HIFI time without initial slew double posinttime = 10.0; // Integration time on source double posofftime = 10.0; // Integration time on OFF double timeefficiency = 0.5; // time efficiency double noiseefficiency = 0.125; // noise efficiency double relnoise = 0.01; // drift noise contribution bool reduced = false; // whether deconvolution is assumed }{ // close any previous messages message("

"); message("

Observing mode performance

"); message("

"); // Actual messages message("Observing time without initial slew " + totaltime + "s
"); message("On-source integration time " + posinttime + "s
", 1); message("OFF integration time " + posofftime + "s
", 1); message("Overhead " + (double(totaltime) - posinttime - posofftime) + "s
", 1); message("

"); message("Total time efficiency " + timeefficiency * 100.0 + "%
", 1); message("Total noise efficiency " + noiseefficiency * 100.0 + "%
", 1); message("Drift noise contribution " + relnoise * 100.0 + "%
", 2); message("

"); // Auxiliary explanations - Main beam double fwhm = GetMainBeamSize(band,lo_freq); fwhm = fwhm * 3600.0; double eta_mb = InterpolateCoupling(band,lo_freq); // System temperature is recomputed to be printed without passing double tsys = InterpolateTsys(band,lo_freq); double[] gssb = InterpolateGssb(band,lo_freq); double tsys_lsb = tsys / (eta_mb * gssb[0]); double tsys_usb = tsys / (eta_mb * gssb[1]); message("

"); message("The system noise temperature at " + lo_freq / 1000.0 + " GHz is " + tsys_lsb + " K in the lower and " + tsys_usb + " K in the upper sideband.", 0); message("
"); if(reduced) { message("Deconvolved noise values are given on a two-polarization," + " single-sideband, main beam temperature scale of a " + fwhm + "'' beam with a main beam efficiency of " + eta_mb * 100.0 + "%.", 1); } else { message("All noise values are given on a two-polarization," + " single-sideband, main beam temperature scale of a " + fwhm + "'' beam with a main beam efficiency of " + eta_mb * 100.0 + "%.", 1); } message("

"); message(""); } // Second part of FPSS FM functional test, block // Check cryogenic health block FT_FPU_check_cryohealth_fm HIFI 3801 { string band = "1a"; int integ_time = 4; //Integation time in seconds double lo_freq = 500.0; //LO frequency string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); //We will check the IF noise // Backends are required !! //We assume the bias voltage is already at its //normal value //Get magnets in case band 1-5 is used if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { {double,string}[] result = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,0.0); // //Set magnet to max. for hysteresis issues Hifi_HIFI_CH1_MX_MG_C($BBID,result[0]{0}); Hifi_HIFI_CV1_MX_MG_C($BBID,result[1]{0}); delay(1); } //Get nominal biases and magnets result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v","norm_magn_h","norm_magn_v"],band,lo_freq); double bias_h = result[0]{0}; double bias_v = result[1]{0}; double magnet_current_h = result[2]{0}; double magnet_current_v = result[3]{0}; // Hifi_HIFI_FCU_parameter_scan($BBID,1,1,0.1,bias_h,bias_v,0.0,magnet_current_h,magnet_current_v,0.0); //Sets magnet current delay(2); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // // //Perform IF noise test result = ConfigurationReader("name_confilfpu",["bias_low_resistive_h","bias_low_resistive_v","bias_high_resistive_h","bias_high_resistive_v"],band,0.0); //1. bias 5 Volts bias_h = result[0]{0}; bias_v = result[1]{0}; // Hifi_HIFI_FCU_parameter_scan($BBID,1,1,0.1,bias_h,bias_v,0.0,0.0,0.0,0.0); //Sets magnet current to 0 delay(2); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // // //Perform IF noise test //2. bias 10 Volts bias_h = result[2]{0}; bias_v = result[3]{0}; // Hifi_HIFI_FCU_parameter_scan($BBID,1,1,0.1,bias_h,bias_v,0.0,0.0,0.0,0.0); //Sets magnet current to 0 delay(2); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // // } //HIFI measurement of HEB spectra variation vs Imix, mode //Takes spectra over the full Vd2 range obs HifiEng_HEB_Spectra_vs_Imix_COP { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band bool lo_chain_switch = false; //Whether the chain is already switched on int testtime = 900; //total time we want to spend on testing }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(HEB_Spectra_vs_Imix_proc_fm_COP(band,lo_chain_switch,testtime)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution HEB_Spectra_vs_Imix_proc_fm_COP(band,lo_chain_switch,testtime); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } //Systematic deflux after LO switch-on, procedure procedure Deflux_at_switchon_proc_aot { string band = "4a" in ["ALL","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band. ALL does all bands and all multipliers }{ // } // Integrate only on external cold, block // We take 1 spectrum per phase. block Stability_extcold_fm HIFI 3437 { string band = "1a"; // HIFI band int n = 100; //The number of integrations int integ_time = 4; //Total integration time in sec. to be set at end of test string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code string obsmode = "fastchop" in ["fastchop","tp"]; //tp or fastchop double chop_phase = 1.0 in [0.2,2.0]; // Chop phase length }{ Start_block(); Chopper_Rotation_proc_fm(band,"chop_hot_ang","chop_M3_ang"); //Look at M3 //Get chopper settings {double,string}[] result = ConfigurationReader("name_confilfpu",["chop_M3"],band,0.0); double chop_M3 = result[0]{0}; //Close shutter //Shutter_rotate_proc_fm("closed"); //Do a long integration // - for B1-5, use 2 sec. with wbs or hrs only, thus tp is OK // - for B6: use 1 sec. with reduced wbs (wbsFast), thus tp is OK //We implement a special spectroscopy configuration with fixed values if(obsmode == "tp") { Total_power_spectro_for_Stability_proc_fm(band,n,integ_time,backend,hrs_mode); } if(obsmode == "fastchop") { Fast_chop_spectro_for_Stability_proc_fm(band,n,integ_time * 2,backend,hrs_mode,chop_M3,chop_M3,chop_phase); } } //DEPRECATED. USE OBS COMMAND INSTEAD // WBS zero, procedure // This is a work-around for WBS_Zero. //procedure WBS0_fm_proc { // string band="1a"; // HIFI band // }{ // Hifi_HIFI_Single_cmd ($BBID, "HWH_ZERO_ON"); // Hifi_HIFI_Single_cmd ($BBID, "HWV_ZERO_ON"); // delay (1) ; // //Configure spectroscopy // {double, string}[] result_d = ConfigurationReader("name_delays", // ["integ_time_zero"],band,0.0); // int integ_time_zero = iround(result_d[0]{0}); // Configure_Spectrometer_proc_fm(band,integ_time_zero,["wb1","wb1"],backend); // // // HIFI_Spectr_total_power_proc_fm(band,"wbs",integ_time_zero); // // // Hifi_HIFI_Single_cmd ($BBID, "HWH_ZERO_OFF"); // Hifi_HIFI_Single_cmd ($BBID, "HWV_ZERO_OFF"); // delay (1) ; // // // } ////////////////////////////////////// // WITH THE NEW RULES THIS SHOULD BE // A BLOCK. HOWEVER THIS PROCEDURE SHOULD // NOT BE USED AS DEFAULT SO I EXPECT IT // DISAPPEARS SOON. ////////////////////////////////////// // WBS comb, procedure // This is a work-around for WBS_Comb, with controlable att. // and no zero integration // The integration time is read in a configuration file procedure WBS_comb_fm_proc { string band = "1a"; // HIFI band string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Set zero On Hifi_HIFI_switch_zero_WBS_H($BBID,"ON"); Hifi_HIFI_switch_zero_WBS_V($BBID,"ON"); delay(1); //We have to set attenuators to values different from max. //Initial configuration //H-Polarization // {double,string}[] result_d = ConfigurationReader("name_configwbs",["hwh_laser1_s","hwh_laser2_s","hwh_heater","hwh_latchup_s","hwh_att_band4_comb","hwh_att_band3_comb","hwh_att_band2_comb","hwh_att_band1_comb","hwh_att_in_comb"],band,0.0); string hwh_laser1_s = result_d[0]{1}; string hwh_laser2_s = result_d[1]{1}; int hwh_heater = iround(result_d[2]{0}); string hwh_latchup_s = result_d[3]{1}; int hwh_att_band4 = iround(result_d[4]{0}); int hwh_att_band3 = iround(result_d[5]{0}); int hwh_att_band2 = iround(result_d[6]{0}); int hwh_att_band1 = iround(result_d[7]{0}); int hwh_att_in = iround(result_d[8]{0}); // result_d = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result_d[0]{0}); // //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); // //delay(wbs_config_delay); //Wait for configuration to be applied // //V-Polarization // result_d = ConfigurationReader("name_configwbs",["hwv_laser1_s","hwv_laser2_s","hwv_heater","hwv_latchup_s","hwv_att_band4_comb","hwv_att_band3_comb","hwv_att_band2_comb","hwv_att_band1_comb","hwv_att_in_comb"],band,0.0); string hwv_laser1_s = result_d[0]{1}; string hwv_laser2_s = result_d[1]{1}; int hwv_heater = iround(result_d[2]{0}); string hwv_latchup_s = result_d[3]{1}; int hwv_att_band4 = iround(result_d[4]{0}); int hwv_att_band3 = iround(result_d[5]{0}); int hwv_att_band2 = iround(result_d[6]{0}); int hwv_att_band1 = iround(result_d[7]{0}); int hwv_att_in = iround(result_d[8]{0}); // //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // delay(wbs_config_delay); //Wait for configuration to be applied // //Configure spectroscopy result_d = ConfigurationReader("name_delays",["integ_time_comb"],band,0.0); int integ_time_comb = iround(result_d[0]{0}); Configure_Spectrometer_proc_fm(band,integ_time_comb,["wb1","wb1"],"wbs"); // Hifi_HIFI_Single_cmd($BBID,"HWH_COMB_ON"); Hifi_HIFI_Single_cmd($BBID,"HWV_COMB_ON"); delay(1); // HIFI_Spectr_total_power_proc_fm(band,"wbs",integ_time_comb); // Hifi_HIFI_Single_cmd($BBID,"HWH_COMB_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWV_COMB_OFF"); delay(1); Hifi_HIFI_switch_zero_WBS_H($BBID,"OFF"); Hifi_HIFI_switch_zero_WBS_V($BBID,"OFF"); delay(1); // //Set attenuators back to default WBS_config_block_fm(band); } ///////////////////////////////////////////////////////////////// // Second step of timing computation after telescope behaviour // is known - Spectral Scan DBS observing mode // {int,{int,int,int,int,int,int,int,int,int,bool,int,int,int},double,double,double} procedure SScanDBS_post_timing { {int,int,int,int,int,int,int,int,int,bool,int,int,int} pre_timing = {4,15,4,21,11,1800,22,32,1,false,0,50,0}; // pre_timing parameter list int[] telescopetimes = [300,180,20,1,21,0]; int grouplen = 1; int groupnumber = 50; // Total umber of frequency groups int n_cycles = 1; // Number of half OFF-ON-ON-OFF cycles at one frequency bool fastchop = false; // whether fast-chop is used instead of slow-chop }{ // Get all values from the pre_timing section int inttime = pre_timing{0}; int pointing = pre_timing{1}; int readouttime = pre_timing{2}; int loadlength = pre_timing{3}; int jitterdead = pre_timing{4}; int load_spacing = pre_timing{5}; int bigtunestep = pre_timing{6}; int n_loadinterval = pre_timing{7}; int n_bchop = pre_timing{8}; bool end_load = pre_timing{9}; int smallstep = pre_timing{10}; int initlength = pre_timing{11}; int dangling = pre_timing{12}; // Computation for slow-chop or fast-chop if(fastchop) { int readoutperchop = 1; } else { readoutperchop = 2; } // Get all values from the telescope section int telinit = telescopetimes[1]; // Initial slew time int slewtime = telescopetimes[2]; // Slew time to OFF int longslew = telescopetimes[4]; // Actual slew time for load slew int pointwaittime = telescopetimes[3]; // Idle time between two phases int tend = telescopetimes[5]; // Final deceleration time ////////////////////////////////////////////////////////////////// // Now we start the actual computations // Pointwaittime is used for tuning // In all non-tuning cycles, pointwaittime acts like a longer slew slewtime = slewtime + pointwaittime; longslew = longslew + pointwaittime; // Half tune step has to be rounded up int halftunestep = (bigtunestep - jitterdead - pointwaittime + 1) / 2; ////////////////////////////////////////////////////////////////////// // Compute timing parameters for the two cases divided by n_cycles > 1 // // Observations with ncycles >1 may be somewhat less efficient // if(n_cycles > 1) { int scan_time = 2 * inttime + slewtime; // How often do I have to perform a load slew // Never switch between short load and long load here if(n_loadinterval > 1) { int old_n_loadinterval = n_loadinterval; n_loadinterval = imax((load_spacing + slewtime) / scan_time,1); // fit with n_cycles n_loadinterval = imin(n_loadinterval,n_cycles); n_loadinterval = IMultiple(n_loadinterval,n_cycles); if(n_loadinterval <= 1) { n_loadinterval = old_n_loadinterval; } } // part of integrations is removed for tuning int n_add = iceil(double(halftunestep) / double(readoutperchop * readouttime)); n_bchop = n_bchop - n_add; if(n_bchop <= 0) { SError("Readout cycle too long relative to nod cycle."); } // Pointing time pointing = inttime + jitterdead; // Average times for noise estimate int shortint = n_bchop * readoutperchop * readouttime; double effinttime = double((n_cycles - 1) * inttime + shortint) / double(n_cycles); int loadpercycle = n_cycles / n_loadinterval; double cycletime = double(2 * pointing) + double(loadpercycle * longslew + (n_cycles - loadpercycle) * slewtime) / double(n_cycles); double avchopnum = double(n_cycles * (n_bchop + n_add) - n_add) / double(n_cycles); // Compute total duration int totaltime = iround(cycletime * double(groupnumber * n_cycles)); } else { // Retuning after each nod cycle // Check group length limited by load_interval scan_time = 2 * (grouplen * inttime + (grouplen - 1) * smallstep) + bigtunestep + slewtime; if(scan_time > load_spacing + slewtime && grouplen > 1) { SError("Frequency group length too large for load interval."); } pointing = grouplen * inttime + (grouplen - 1) * smallstep + halftunestep + jitterdead; // Average times for noise estimate effinttime = double(grouplen * inttime); // ignore the tuning time between cycles cycletime = double(longslew + 2 * pointing - bigtunestep); avchopnum = double(n_bchop); // Compute total duration totaltime = (iround(cycletime) + bigtunestep) * groupnumber; } double tdead = cycletime - 2.0 * effinttime; ////////////////////////////////////////////////////////////////////// // The initial time is no longer contained in the total time initlength = initlength - halftunestep; int shiftlength = halftunestep; // Compute total duration, remove pointwaittime for last slew int closelength = duration(HIFICloseObs()); dangling = imax(dangling + closelength - tend,0); totaltime = totaltime + dangling - pointwaittime + tend; // show gyro-propagation messages int pointcycle = longslew + 2 * pointing; GCPMessages(pointing,2 * pointcycle,tend); // Return all the times needed in the observing mode modules return {totaltime,{inttime,pointing,readouttime,loadlength,jitterdead,load_spacing,bigtunestep,n_loadinterval,n_bchop,end_load,shiftlength,initlength,dangling},avchopnum,cycletime,tdead}; } //HIFI LO tuning only for M1/M2 investigation in 3b, block //Target current is read from look-up table block LO_tuning_w_M1M2M3_block_fm HIFI 3919 { string band = "3b" in ["3b","3b"]; // HIFI band double lo_freq = 930.0; //LO frequency double m1 = 10.0; //M1 multiplier voltage double m2 = -8.0; //M2 multiplier voltage double m3 = 1.5; //M3 multiplier voltage }{ //Clear potential failure mode Set_LO_Nominal_proc_fm(); // //Start_block(); {double,string}[] result = ConfigurationReader("name_confpolar4lotune",[band],band,lo_freq); string mixer_polarization = result[0]{1}; // //Get target mixer current result = ConfigurationReader("name_confilmix",["target_mx_c_h","target_mx_c_v"],band,lo_freq); double target_current = result[0]{0}; if(mixer_polarization == "V") { target_current = result[1]{0}; } if(mixer_polarization == "B") { target_current = 0.5 * (result[1]{0} + result[0]{0}); } // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; name_configlcutune = "name_configlcutune_b"; } // result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = m1; //result[1]{0}; double m2_v = m2; //result[2]{0}; double m3_v = m3; //result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // result = ConfigurationReader(name_configlotune,["step_drain2_v","nsteps","step_time"],band,lo_freq); double step_drain2_v = result[0]{0}; int nsteps = iround(result[1]{0}); double step_time = result[2]{0}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // //Adjust scan cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); double drain2_safe = cresult[0]; // double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); // //For all bands, scan will be done with decreasing drain2 voltages //The best guess is taken from look-up table double tune_range = 0.1; result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lo_freq); double middle_d2 = result[0]{0}; double drain2_v_start = min(middle_d2 * (1.0 + tune_range / 2.0),drain2_bluemax); double drain2_v_end = (1.0 - tune_range / 2.0) / (1.0 + tune_range / 2.0) * middle_d2; //drain2_v_start; step_drain2_v = (drain2_v_end - drain2_v_start) / double(nsteps - 1); // result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); // if(band == "3b") { Hifi_HIFI_Conf_nom_LCU_ch3b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,macro_checksum); //Send command: specific to M3 in 3b delay(config_lo_delay); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } // // if(band == "3b") { //Band 3b Hifi_HIFI_Load_vector_nom_3b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } // delay(1); // //Execute tuning: check which mixer is to be used if(mixer_polarization == "V") { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCV($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCV($BBID,target_current); } } else { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCH($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCH($BBID,target_current); } } // double time_needed = double(nsteps) * step_time; delay(iround(time_needed + 2.0 + 0.5)); //0.5s added for completion of load_vector // //Store settings into available register HIFI_HL_store_tm_only_proc_fm(); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } ///////////////////////////////////////////////////////////////// // Fast chop dual beam switch observing mode // // Implemented as procedure returning time and noise levels for HSPOT {string,double,double}[] procedure HifiPointProcFastDBSSequencerInit { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 10 in [4,80]; // data dump interval int n_int_on = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_switch_on = 1 in [1,1800]; // number of data transfer cycles per pointing int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Get the drift parameters to compute the drift noise {double,double} phaselengths = DBSPhaseLengths(band,lo_freq,effResolution,continuumDetection,oneGHzReference); // Compute derived quantities // Top down approach here int main_phase = iceil(phaselengths{0}); int data_time_guess = 40; int n_switch_on_guess = main_phase / data_time_guess; if(n_switch_on_guess < 2) { n_switch_on_guess = 2; data_time_guess = main_phase / n_switch_on_guess; } // Check with data rate {int,double[]} dataparms = DataTaking(backendreadoutparms,8); int datalimit = 2 * dataparms{0}; if(data_time_guess < datalimit) { data_time_guess = datalimit; n_switch_on_guess = 1; } int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } // Chop phase length double phase_min = min(max(phaselengths{1},0.15),1.5); int n_int_on_guess = ifloor(double(data_time_guess) / (2.0 * phase_min)); int n_int_on_range = -n_int_on_guess / 2; if(n_int_on_range == 0) { n_int_on_range = 1; } // Add pointing requirements condition: >=10s {int,int} new_data_time = MatchMinPointing(data_time_guess,data_time_range,n_switch_on_guess); data_time_guess = new_data_time{0}; data_time_range = new_data_time{1}; // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"n_int_on",double(n_int_on_guess),double(n_int_on_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)}]; return retvalues; } // FSW Response time, procedure procedure FSW_Response_time_proc_fm { double hr_central_freq = 5.0; //IF freq of HRS hr sub-band in GHz string hrs_polar = "H" in ["H","V","B"]; //HRS polarizations in use int[] del_wbs_param = [10,200,10,100]; //starting, ending and step value for del_wbs }{ //FSW will be called with increasing delta time between the two phases //Need special spectroscopy configuration: // - HRS only in hr resolution, optionally H, V or B, 1sec integration HRS_config_resol_block_fm("0",["hr","hr"]); FSW_Response_time_HRSConfig_block_fm("0",["hr","hr"],hr_central_freq); //Optimize HRS level HRS_tune_block_fm("0"); //Now call FSW at successive del_wbs FSW_Response_time_block_fm(hrs_polar,del_wbs_param); // } // Chopper scan, procedure (IF power as function of chopper position) procedure Chopper_scan_proc { string band = "1a"; // HIFI band //Setting file double chopper_pos_min = -7.0; //minimum chopper position double chopper_pos_max = 8.0; //maximum chopper position int n_steps = 300; //number of steps string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3 string shutter = "open"; //Status of shutter during scan: closed/open int integ_time = 4; //Total integration time in sec.: at least 2sec ! string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string chopmode = "tp" in ["tp","slowchop","fastchop"]; //modulation mode between hot/cold: tp, slowchop, fastchop double chop_phase = 1.0 in [0.2,2.0]; // Chop phase length bool ref_position = false; //Do we take a reference spectrum every 100sec ? bool shutter_used = true; }{ double chop = 0.0; // //close shutter if necessary if(shutter_used) { //Shutter_rotate_proc_fm("closed"); } // //Prepare for backend attenuation on hottest spot if(shutter == "open") { //External hot is available Chopper_Rotation_block_fm(band,"chop_hot_ang","chop_M3_ang"); } else { //Have to use internal hot Chopper_Rotation_block_fm(band,"chop_M3_ang","chop_hot_ang"); } // //Configure and tune backends //16/11/05: NOT ANYMORE, THIS SHOULD BE DONE INDEPENDENTLY //HRS_config_block_fm(band,hrs_mode); //WBS_config_block_fm(band); //WBS calibration if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band); WBS_tune_proc_fm(band); } if(backend == "hrs" || backend == "both") { HRS_tune_block_fm(band); } // //Configure spectrometers integration after tuning int[] res = [0,0]; int n_wbs1 = 0; int n_hrs_trans = 0; int total_time = 0; if(chopmode == "tp") { res = Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); total_time = res[0] * res[1]; } if(chopmode == "slowchop") { res = Configure_Spectrometer_hc_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); total_time = res[0] * res[1]; } if(chopmode == "fastchop") { //Integ_time expected here is the TOTAL integration time with both phases + residual HRS time res = Configure_Spectrometer_fast_chop_proc_fm(band,integ_time * 2,chop_phase,hrs_mode,backend); total_time = iceil(chop_phase * double(res[1] * res[2])); n_wbs1 = res[2]; n_hrs_trans = res[3]; //debug_print("Fast chop parameters: n_wbs1 = "+res[2]+", n_hrs_trans = "+res[3]); } // Chopper_scan_fm(band,chopper_pos_min,chopper_pos_max,n_steps,total_time,backend,chopmode,n_wbs1,n_hrs_trans,ref_position,shutter_used,hrs_mode,chop_phase); // //Configure spectrometers integration back to default in tp mode Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); //We end with a spectrum on both external loads: Only for ILT !! //They are needed in the analysis //Hot_cold_external (band,total_time,backend); //integration on external loads: sky path // } ////////////////////////////////////// // low-level procedures ////////////////////////////////////// string procedure GetLcuSection { }{ {double,string}[] result_d = ConfigurationReader("name_chopper",["prime_or_redundant"],"0",0.0); string section = "P"; if(result_d[0]{1} == "redundant") { section = "R"; } return section; } procedure HalfFastDBSRaster_commanding { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 10 in [4,80]; // data dump interval int n_int = 20; // number chop cycles to integrate in ICU before transfer int n_seq = 1; // number of data transfer cycles per pointing int n_cycles = 1; // Number of half OFF-ON-ON-OFF cycles int n_pointsperscan = 1; // Number of points measured before moving to the second pointing phase int n_loadinterval = 10; // number of nods before a load measurement int n_load = 0; // additional load measurements in one pointing phase bool final_load = false; // Need for final load measurement int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,10,0,10,20,21,0,0]; // Timing of the observation from telescope int loadlength = 21; // Load duration bool iscross = false; // Whether we use a cross instead of a raster }{ // Auxiliary variables // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Fixed timings in the fast-chop mode int load_datatime = GetStdLoadReadout(band,lo_freq); // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time //////////////////////////////////////////////////////////////////////// // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // // Clustering is currently not implemented in MPS - switched off here int clustered = 0; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time / 2); double[] rates = dataparms{1}; int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,true); int readoutdead = FastChopReadoutDelay(band,lo_freq,backendreadoutparms); // Count phases by hand to allow simultaneous usage by Raster and Cross int iphase = 0; // There is no nod counter in the return values - count this by hand int inod = 0; // Do I have to make loads in short nods and subsequent holds? if(iscross) { bool holdforload = n_pointsperscan > 1; } else { holdforload = n_pointsperscan == 1 && n_loadinterval > n_cycles; } bool isOffAtPoint = false; //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; int[] choppars = [2 * n_int,0]; bool runintostate = false; while(state[0] >= 0) { if(runintostate) { state = next_state_no_check(); } else { state = next_state(); } if(state[0] == 1) { // Initialization if(clustered != 1) { HIFIInitObs(); TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal"); } delay(tinitslew - (time() - startobs) - hkduration - loadlength); // First load measurement HIFISetHK("normal",false); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); runintostate = false; iphase = iphase + 1; } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 3) { // First nodding position // Check whether we are in a cross mode using computed OFF isOffAtPoint = iscross && inod % 2 == 0; // Configure measurement choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_seq,band,lo_freq,backendreadoutparms); // Loop for load cycles // The use of n_load differs by 1 from the other observing modes here for(int i1 = 1 .. n_load - 1) { if(isOffAtPoint) { HIFIFastHalfChopOffIntegration(data_time,n_seq,band,lo_freq,choppars,rates); } else { HIFIFastHalfChopOnIntegration(data_time,n_seq,band,lo_freq,choppars,rates); } // Perform load calibration delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_seq,band,lo_freq,backendreadoutparms); } // Last cycle - no load if(isOffAtPoint) { HIFIFastHalfChopOffIntegration(data_time,n_seq,band,lo_freq,choppars,rates); } else { HIFIFastHalfChopOnIntegration(data_time,n_seq,band,lo_freq,choppars,rates); } // Load measurement if required - time included in pointing if(n_load > 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); } // Final point before nod // Special treatment for all cases where load has to be replaced by hold: // n_pointsperscan=1, n_loadinterval > n_cycles if(iphase % n_pointsperscan == 0 && iphase / n_pointsperscan % 2 == 1) { inod = inod + 1; if(holdforload && inod % n_loadinterval == 0 && n_load == 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); runintostate = true; } } else { // keep shift if we come from a holdforload nod, otherwise reset if(!holdforload) { runintostate = false; } } // Update phase counter iphase = iphase + 1; } // Second pointing phase if(state[0] == 7) { // second nod position choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_seq,band,lo_freq,backendreadoutparms); for(int i2 = 1 .. n_load - 1) { HIFIFastHalfChopOffIntegration(data_time,n_seq,band,lo_freq,choppars,rates); // Perform load calibration delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_seq,band,lo_freq,backendreadoutparms); } // Last cycle HIFIFastHalfChopOffIntegration(data_time,n_seq,band,lo_freq,choppars,rates); // Load measurement if required - time included in pointing if(n_load > 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); } // Final point before nod // Special treatment for all cases where load has to be replaced by hold: if(iphase % n_pointsperscan == 0 && iphase / n_pointsperscan % 2 == 1) { inod = inod + 1; if(holdforload && inod % n_loadinterval == 0 && n_load == 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); runintostate = true; } } else { // keep shift if we come from a holdforload nod, otherwise reset if(!holdforload) { runintostate = false; } } // Update phase counter iphase = iphase + 1; } // Load nod if(state[0] == 9) { // Load nod delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); runintostate = false; } // Hold if(state[0] == 6) { // finished shift of instrument operations relative to pointing command runintostate = false; } // Final load if(state[0] == 5) { delay(readoutdead); if(final_load) { // Perform final load measurement LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); } runintostate = false; HIFICloseObs(); } } } // Compute the offset between two points // This is an approximation for small offsets {double,double} procedure ApproxAngularOffset { {double,double} vector1 = {0.0,0.0}; // First vector {double,double} vector2 = {0.2,0.2}; // Second vector }{ double pideg = 3.14159265 / 180.0; double fac = cos(0.5 * pideg * (vector1{1} + vector2{1})); return {(vector2{0} - vector1{0}) * fac,vector2{1} - vector1{1}}; } // LCU3a configuration into SAFE mode, procedure procedure LCU3a_config_safe_proc_fm { string band = "3a"; // HIFI band double lo_freq = 810.0 in [807.0,848.0]; //LO frequency }{ error("This module is obsolete: use LCU_config_nominal_proc_fm instead"); } ////////////////////////////////////////////////////////////////////// // Procedure to perform the noise level evaluation for the observing mode {double,double,double,double,double} procedure SScanDBS_noisecomputer { string band = "4a"; // HIFI band double reffreq = 978300.0; // Reference LO frequency in scan center int nfreq = 4; // Number of frequency points per IF bool dsb = true; // Both sidebands covered {double,double} eff_resolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuum = false; // Whether timing is for total-power level int n_cycles = 1; // Number of half OFF-ON-ON-OFF cycles at one frequency double tscan = 60.0; // Total average duration of one scan {double,double,double} tact = {10.0,4.9,0.05}; // Field of actual dead and integration times }{ // spectral scans always use the full bandwidth for reference bool oneGHzReference = false; double tdead = tact{0}; // Average total dead time in one scan double inttimeperphase = tact{1}; // Actual integration time double deadtimeperphase = tact{2}; // Dead time per switch phase // Currently it is not possible to return both drift noise and radiometric // noise so that only their sum is computed. // // Get parameters which are needed double tsys = InterpolateTsys(band,reffreq); double eta_mb = InterpolateCoupling(band,reffreq); double[] gssb = InterpolateGssb(band,reffreq); // Get the drift parameters to compute the drift noise if(continuum) { double[] allanparms = InterpolateTpAllan(band,reffreq,oneGHzReference); } else { allanparms = InterpolateSpecAllan(band,reffreq,oneGHzReference); } // rescale to frequency resolution double alpha = allanparms[1]; double binningexp = 1.0 / allanparms[2]; double allan_time_lores = allanparms[0] * pow(1.0 / eff_resolution{1},binningexp); double allan_time_hires = allanparms[0] * pow(1.0 / eff_resolution{0},binningexp); // Differential Allan variance if(continuum) { allanparms = InterpolateTpChopAllan(band,reffreq,oneGHzReference); } else { allanparms = InterpolateSpecChopAllan(band,reffreq,oneGHzReference); } // rescale to frequency resolution double dalpha = allanparms[1]; binningexp = 1.0 / allanparms[2]; double dallan_time_lores = allanparms[0] * pow(1.0 / eff_resolution{1},binningexp); double dallan_time_hires = allanparms[0] * pow(1.0 / eff_resolution{0},binningexp); // Compute integration time in one pointing cycle double deadtimeperswitch = deadtimeperphase; double effinttime = (tscan - tdead) / 2.0; // Get actual noise // This is returned twice: for both limiting resolutions double systemnoise_lores = DoubleDifferenceNoise(inttimeperphase / allan_time_lores,[1.0,1.0,effinttime / allan_time_lores,effinttime / allan_time_lores,deadtimeperswitch / allan_time_lores,tdead / allan_time_lores,alpha,dallan_time_lores / allan_time_lores,dalpha]); double systemnoise_hires = DoubleDifferenceNoise(inttimeperphase / allan_time_hires,[1.0,1.0,effinttime / allan_time_hires,effinttime / allan_time_hires,deadtimeperswitch / allan_time_hires,tdead / allan_time_hires,alpha,dallan_time_hires / allan_time_hires,dalpha]); double noiseratio = DoubleDifferenceNoiseRatio(inttimeperphase / allan_time_lores,[1.0,1.0,effinttime / allan_time_lores,effinttime / allan_time_lores,deadtimeperswitch / allan_time_lores,tdead / allan_time_lores,alpha,dallan_time_lores / allan_time_lores,dalpha]); // Compute total double sideband noise // Correct for signal in difference phase double dsbnoise_lores = systemnoise_lores / (eff_resolution{1} * 4000000.0 * tscan); double dsbnoise_hires = systemnoise_hires / (eff_resolution{0} * 4000000.0 * tscan); // Divide by n_cycles and number of frequencies double accumulation = double(nfreq * n_cycles); // Compute noise temperature dsbnoise_lores = tsys * sqrt(dsbnoise_lores / accumulation); dsbnoise_hires = tsys * sqrt(dsbnoise_hires / accumulation); // Translate to the main beam scale, correct for eta_mb // (This is typically not done at ground based telescopes, // but leads often to problems there - to be discussed.) dsbnoise_lores = dsbnoise_lores / eta_mb; dsbnoise_hires = dsbnoise_hires / eta_mb; // Check for double sideband coverage if(dsb) { // Combine both sidebands // In full spectral scans we have only a combined noise temperature for // both sidebands double usbnoise_lores = dsbnoise_lores / sqrt(gssb[0] * gssb[0] + gssb[1] * gssb[1]); double usbnoise_hires = dsbnoise_hires / sqrt(gssb[0] * gssb[0] + gssb[1] * gssb[1]); double lsbnoise_lores = usbnoise_lores; double lsbnoise_hires = usbnoise_hires; } else { // Get single sideband noise equivalent usbnoise_lores = dsbnoise_lores / gssb[0]; usbnoise_hires = dsbnoise_hires / gssb[0]; lsbnoise_lores = dsbnoise_lores / gssb[1]; lsbnoise_hires = dsbnoise_hires / gssb[1]; } // In spectral scans we have only a combined noise temperature for both // sidebands, so that the USB/LSB separation is not used return {usbnoise_lores,usbnoise_hires,lsbnoise_lores,lsbnoise_hires,noiseratio}; } // LCU5b configuration into SAFE mode, procedure procedure LCU5b_config_safe_proc_fm { string band = "5b"; // HIFI band double lo_freq = 1200.0 in [1192.0,1242.0]; //LO frequency }{ error("This module is obsolete: use LCU_config_nominal_proc_fm instead"); } // Equivalent procedure for configuration parameters following // the master file structure currently used for these calibration files // // This is the generic part used for ILT and AOTs // {double,string}[] procedure FlexibleConfigurationReader { string mainmasterfile = "configuration_masterfile"; // Configuration master file string topicname = "name_confilfpu"; // Name of entry in master file string[] objectnames = ["bias_standby_h"]; // Names of calibration objects to be read string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency }{ // first step: read band master file string masterfile = slookup(mainmasterfile,band,"filename"); // read master file string calibfile = slookup(masterfile,topicname,"value_string"); int dep = ilookup(masterfile,topicname,"dependence"); int readnum = length(objectnames); {double,string}[] retvalues = []; if(dep == 0) { // Quantity is only band dependent // directly read from file looking up the object for(int k = 1 .. readnum) { double dres = dlookup(calibfile,objectnames[k - 1],"value"); string sres = slookup(calibfile,objectnames[k - 1],"value_string"); retvalues[k - 1] = {dres,sres}; } } else { // Quantity is band and frequency dependent // read interpolated value from the data base for(int j = 1 .. readnum) { dres = interpolate(calibfile,objectnames[j - 1],lo_freq); sres = ""; retvalues[j - 1] = {dres,sres}; } } return retvalues; } //backend attenuation during peakup in IST context, procedure procedure Peakup_backend_attenuation_proc_fm { string band = "1" in ["1","2","3","4","5","6","7"]; // HIFI band int position = 1 in [1,9]; //peakup pattern sequence number: from 1 to 9 string peakup_matrix = "centred" in ["centred","offseted","flat"]; //Which brightness distribution to simulate with shutter string backend = "hrs" in ["hrs","wbs"]; //Backend in use: hrs or wbs int total_time = 2; //Total integration time in sec. }{ //Get number of shutter rotation steps depending on position number string band_nb = band + "a"; string name_shutter_pos = "name_shutter_pos_centred"; if(peakup_matrix == "offseted") { name_shutter_pos = "name_shutter_pos_offseted"; } {double,string}[] result = ConfigurationReader(name_shutter_pos,["new_att"],band_nb,double(position)); //If flat distribution is chosen, the attenuators shall not be changed double new_att = result[0]{0}; if(peakup_matrix == "flat") { new_att = 10.0; } // //Apply new attenuation if(backend == "hrs") { HRS_config_att_lo_w_att_fm(band_nb,["wb1","wb1"],new_att); } else { new_att = new_att + 5.0; //for WBS we move the main att, all others to 7 int[] att_h = [7,7,7,7,iround(new_att)]; int[] att_v = [7,7,7,7,iround(new_att)]; //Presently assumes use of laser2 WBS_config_w_laser_and_att_proc_fm(band_nb,"Laser2","Laser2",att_h,att_v,total_time,backend); } // } //HIFI-COP-3-Deflux //Systematic deflux at beginning of each OD, or band switch procedure Deflux_SingleBand_proc_ops { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b"]; // HIFI band. ALL does all mixer bands }{ // Get reference frequency string keyfreqname = "keyfreq"; //this is for cold LO operations // "keyfreq" for cold LO operations // "keyfreq_dummy" for dummy LO operations double[] result_d = CalibrationReader("name_keyfreq",[keyfreqname],band,0.0); double lo_freq = result_d[0]; // //Switch on LO LCU_switchon_proc_fm(band); //Wait 1 min from now sync(); int startobs = time(); //Insert FPU setting at this frequency Init_MSA_HBB_fm(band,"CLOSE",lo_freq,"ON"); delay(60 - (time() - startobs)); //Tune LO LO_tuning_block_fm(band,lo_freq); //First magnet tuning Magnet_tuning_block_fm(band,lo_freq,"HRS",40); //Deflux heaters Heater_cop(band); //Second magnet tuning Magnet_tuning_block_fm(band,lo_freq,"HRS",40); //Third magnet tuning Magnet_tuning_block_fm(band,lo_freq,"HRS",40); } //Find out stepmargin double procedure Stepmargin { double low = 0.0; double high = 10.0; string parameter = "hifi_HIF_mx_mg_step_C"; }{ double range = high - low; int range_raw = convert_to_raw(parameter,range); if(range_raw < 1) { range_raw = 1; } double bitsize = range / double(range_raw); return bitsize / 4.0; } // Double load chop measurement performed at both frequencies // of a frequency switch observation // Most code is dublicated from normal load measurement // // Most generic version for spectral scans with potentially different // frequencies for tuning and timing and retuning switch // procedure SScanDoubleLoadMeasurement { string band = "4a"; // HIFI band (needed to estimate stabilization) double tuning_freq = 978200.0; // LO tuning frequency double lo_freq = 978200.0; // LO calibration frequency double freq_throw = -40.0; // throw of frequency switch in MHz bool retunelo = true; // Whether LO retuning is enabled double deltanu = 1.0; // minimum effective resolution of the calibrated data int data_time = 4; // time between subsequent data readouts {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // Readout parameters for HRS1,HRS2, WBS1,WBS2 }{ // Initial computations {int,int,bool} calinit = HIFICalInit(band,lo_freq,deltanu,data_time); int used_datatime = calinit{0}; int n_inttime = calinit{1}; bool retuning = calinit{2} && retunelo; // Perform zero and comb measurement ZeroCombMeasurement(band,lo_freq,used_datatime,backendreadoutparms); // No we perform the actual hot-cold measurement - 2 frequencies int danglingreadout = HIFI_DoubleCalibrate_hot_cold(band,lo_freq,used_datatime,n_inttime,backendreadoutparms,retuning); // Retune and another load if we are in HEB bands if(retuning) { // we have to wait for readout delay(danglingreadout); // Another LO vector scan at the same frequency for a stable HEB operation // For FSW measurements a full preamble of 2xLCU_Configure is needed // as for a new setting (not fully confirmed yet, but safe solution !) HIFITuneFreqFsw(band,tuning_freq,tuning_freq + freq_throw,true,""); danglingreadout = HIFI_DoubleCalibrate_hot_cold(band,lo_freq,used_datatime,n_inttime,backendreadoutparms,false); } } // Get standard load read out data cycle used only in fast-chop observations int procedure GetStdLoadReadout { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency }{ double[] dead = CalibrationReader("stdloadreadout",["loadreadout"],band,lo_freq); return iceil(dead[0]); } ///////////////////////////////////////////////////////////////// // Fast chop dual beam switch observing mode // // The timing is defined as WBS timing, the HRS takes more data during // the WBS read out, but this is ignored in the computations here. // // Combination of four modules implementing the new structure // // Implemented as procedure returning time and noise levels for HSPOT {int,double,double,double,double,double} obs HifiPointProcFastDBS { /* Setup parameters */ int naifid = 0; // Tracing object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 10 in [4,80]; // data dump interval int n_int_on = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_switch_on = 1 in [1,1800]; // number of data transfer cycles per pointing int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Single Point - DBS fastChop",{data_time,0,n_switch_on,n_int_on,0,0,0,0,n_cycles,load_interval}); // Call first part of the timing computer {int,int,int,int,int,int,int,int,int,bool,int,int,int} pre_timing = FastDBS_pre_timing(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_switch_on,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,int,int,int,int,int,int} tpar = DBS_telescope(naifid,onPosition,band,lo_freq,"",pre_timing,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = nodding_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},false); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,bool,int,int,int},bool,double,double} post_timing = DBS_post_timing(pre_timing,telescopetimes,n_cycles); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = DBS_telescope(naifid,onPosition,band,lo_freq,"",post_timing{1},n_cycles); // Call telescope command telescopetimes = nodding_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},false); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{3}; int n_load = post_timing{1}{6}; int n_loadinterval = post_timing{1}{7}; int n_seq = post_timing{1}{8}; bool end_load = post_timing{1}{9}; int shiftlength = post_timing{1}{10}; bool final_load = post_timing{2}; double tscan = post_timing{3}; double tdead = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { FastDBS_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_seq,n_load,n_loadinterval,end_load,final_load,startobs,telescopetimes,loadlength,shiftlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double} tact = FastDBS_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_seq,n_load,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = DBS_noisecomputer(band,lo_freq,effResolution,continuumDetection,oneGHzReference,n_cycles,tscan,tact); // Evaluate performance DBS_performance(band,lo_freq,effResolution,noisevalues,timeTaken,n_cycles,n_seq * n_int_on * (n_load + 1),tscan,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } {string,double,double}[] procedure HifiPointModeDBSSequencerInit { string modeName = "dbs"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_switch_on = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per pointing int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // Get the drift parameters to compute the drift noise {double,double} phaselengths = DBSPhaseLengths(band,lo_freq,effResolution,continuumDetection,oneGHzReference); // Compute derived quantities int data_time_guess = imin(imax(iceil(phaselengths{1}),datalimit),20); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } int n_switch_on_guess = imax(iceil(phaselengths{0} / (2.0 * double(data_time_guess))),1); int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } // Add pointing requirements condition: >=10s {int,int} new_data_time = MatchMinPointing(data_time_guess,data_time_range,2 * n_switch_on_guess); data_time_guess = new_data_time{0}; data_time_range = new_data_time{1}; // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)}]; return retvalues; } // Spectrometer configuration for slow chop, low level procedure // Specific for hotcold or chopper calib cases (longer del_wbs) int[] procedure Configure_Spectrometer_hc_slow_chop_proc_fm { string band = "1a"; // HIFI band int integ_time = 8; //Total integration time in sec. for the two phases ! string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4,wb5 string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //First derive backend setting codes as expected by VO's routine //Build up backend parameter tupple: {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = BackendSettings(band,0.0,hrs_mode,backend); // Readout parameters for HRS1,HRS2, WBS1,WBS2 //Compute data_time and n_switch use the wrapper int[] res = ConfigSlowChop(integ_time,"chopcal",band,0.0,backendreadoutparms); int data_time = res[0]; int n_switch = res[1]; // Now call the spectroscopy setup: it is common to ILT and AOT CUS. // The deadtimes output is not used at ILT level. {double,double} dtimes = ConfigSpectroscopySlowChop_IST(data_time,n_switch,"chopcal",band,0.0,backendreadoutparms,true); // return res; } // //Set LOU to nominal, block //Set LOU in nominal mode with no //channel selected block Set_LO_Nominal_block_fm HIFI 3626 { }{ // //Start_block(); {double,string}[] result = ConfigurationReader("name_delays",["set_to_nominal_delay"],"0",0.0); int set_to_nominal_delay = iround(result[0]{0}); // Hifi_HIFI_HL_Normal($BBID); delay(set_to_nominal_delay); // } //////////////////////////////////// // Special DBS raster - cross observing mode // // Return time and noise levels {int,double,double,double,double,double} obs HifiMappingProcDBSCross { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source double stepsize = 0.0050 in [5.5556E-4,0.13333]; // Distance between subsequent points in the two raster lines int npoints = 10 in [2,100]; // Number of points per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_switch_on = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Mapping - DBS Cross Map slowChop",{data_time,0,0,n_switch_on,0,0,n_pointsperscan,0,n_cycles,load_interval}); // Call first part of the timing computer {int,int,int,int,int,int,int,int,int,int,int,int,int} pre_timing = DBSRaster_pre_timing(2,npoints,band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_switch_on,n_pointsperscan,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,bool,double,double,double,double[],double[],int[],double,double,int,int,int,int,int,int} tpar = DBSCross_telescope(naifid,onPosition,stepsize,npoints,band,lo_freq,"",pre_timing,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = custom_map_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21}); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,int},bool,double,double} post_timing = DBSCross_post_timing(pre_timing,telescopetimes,npoints,n_switch_on,n_cycles,load_interval,false); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = DBSCross_telescope(naifid,onPosition,stepsize,npoints,band,lo_freq,"",post_timing{1},n_cycles); telescopetimes = custom_map_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21}); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{3}; int n_load = post_timing{1}{6}; int n_loadinterval = post_timing{1}{7}; int n_seq = post_timing{1}{8}; int scansize = post_timing{1}{10}; int initlength = post_timing{1}{11}; int dangling = post_timing{1}{12}; bool final_load = post_timing{2}; double tscan = post_timing{3}; double tdead = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { DBSRaster_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_seq,n_cycles,scansize,n_loadinterval,n_load,final_load,startobs,telescopetimes,loadlength,true); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double} tact = DBSRaster_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_seq,n_load,scansize,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = DBS_noisecomputer(band,lo_freq,effResolution,continuumDetection,oneGHzReference,n_cycles,tscan,tact); // Evaluate performance DBSRaster_performance(band,lo_freq,effResolution,noisevalues,timeTaken,2,npoints,n_cycles,n_seq * imax(n_load,1),tact); // Correct for double counting of central point // The central point noise is returned only double multiplier = sqrt(0.5); noisevalues{0} = noisevalues{0} * multiplier; noisevalues{1} = noisevalues{1} * multiplier; noisevalues{2} = noisevalues{2} * multiplier; noisevalues{3} = noisevalues{3} * multiplier; noisevalues{4} = noisevalues{4} / multiplier; // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // FPU Standby with chopper switched on. HBB is also ON per default, block block Band0_chopper_on_fm HIFI 3297 { string band = "0"; // HIFI band string chop_loop = "CLOSE"; // Chopper Loop status }{ Start_block(); //Get parameters {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,0.0); int band_nb = iround(result_d[0]{0}); // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,0.0); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // string chop_sine_s = "ON"; result_d = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,0.0); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // double calibcurrent = result_d[7]{0}; // result_d = ConfigurationReader("name_confilfpu",["bias_standby_h","diplexer_standby_h","bias_standby_v","diplexer_standby_v","diplex_h_ctrl_mode","diplex_v_ctrl_mode","chop_M3right"],band,0.0); // double bias_H = result_d[0]{0}; double diplex_H = result_d[1]{0}; double bias_V = result_d[2]{0}; double diplex_V = result_d[3]{0}; int diplex_h_ctrl_mode = iround(result_d[4]{0}); int diplex_v_ctrl_mode = iround(result_d[5]{0}); // //Retrieve magnets Magnet are so far at maximum value. Now set to nominal double magnetcurrent_H = result_d[1]{0}; double magnetcurrent_V = result_d[4]{0}; // if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilfpu",["magnet_standby_h","magnet_standby_v"],band,0.0); magnetcurrent_H = result_d[0]{0}; magnetcurrent_V = result_d[1]{0}; } // result_d = ConfigurationReader("name_chopper",["chop_startup_cold"],band,0.0); if(chop_loop == "OPEN") { result_d = ConfigurationReader("name_chopper",["chop_startup_warm"],band,0.0); } double chopper = result_d[0]{0}; //For this configuration we won't convert prime chopper voltage into redundant voltage //Just checking we are in range. //chopper = Check_Chopper_Prime_Redundant(chopper); chopper = Check_Chopper_Range(chopper); // //Switch on upconverter, assuming chopper and mixers are also ON Hifi_HIFI_Configure_FCU_Power($BBID,"ON","ON","ON","ON","ON"); // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result_d = ConfigurationReader("name_delays",["config_fpu_delay"],band,0.0); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // } //////////////////////////////////// // Blocks //////////////////////////////////// // Simulating PU report packet emission block Simulate_PU_block_ops HIFI 7822 { }{ StartBlock_ops(); mois_step("Send simulated micro-rotations to ACMS"); int hifi_HI_microrot_y = 5; // HI_microrot_y int hifi_HI_microrot_z = 7; // HI_microrot_z Hifi_HIFI_simulate_peakup(hifi_HI_microrot_y,hifi_HI_microrot_z); delay(1); } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the OTF observing mode procedure OTFFSwitch_commanding { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // chunk size given by the data rates and optimum speed int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_perline = 10; // Number of frequency switch cycles per line int n_switch_off = 3; // Number of frequency switch cycles on OFF int nlines_tot = 1; // Total number of lines to scan int n_linesperscan = 1; // Number of lines between two OFFs int n_loadinterval = 1; // number of nods before a load measurement int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,2,2,40,10,20,21,0]; // Timing of the observation from telescope int loadlength = 21; // Load duration }{ // Auxiliary variables // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time int toffslew = telescopetimes[6]; // slew dead time between points //////////////////////////////////////////////////////////////////////// // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // // Clustering is currently not implemented in MPS - switched off here int clustered = 0; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] onrates = dataparms{1}; dataparms = DataTaking(backendreadoutparms,data_time_off); double[] offrates = dataparms{1}; int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); // Count OFFs by hand, their counter is not returned in the state array int ioff = 0; //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 1) { // Initialization if(clustered != 1) { HIFIInitObs(); TuneHIFIFsw(band,lo_freq,freq_throw,hrs1,hrs2,wbs1{0},wbs2{0},"normal"); } delay(tinitslew - (time() - startobs) - loadlength - hkduration); // First load measurement HIFISetHK("normal",false); DoubleLoadMeasurement(band,lo_freq,freq_throw,eff_resolution{0},data_time,backendreadoutparms); } if(state[0] == 4) { // OFF Integration HIFIConfigureFSwitchIntegration(data_time_off,n_switch_off,band,lo_freq,backendreadoutparms); HIFIFSwitchOffIntegration(data_time_off,n_switch_off,band,lo_freq,offrates); // OFF counter ioff = ioff + 1; // Check for normal slew after OFF if(state[2] * state[3] < nlines_tot) { HIFIActiveHK("normal",toffslew); } } if(state[0] == 8) { // OTF integration // Check whether we come from the OFF if((state[2] + n_linesperscan - 1) % n_linesperscan == 0) { HIFIConfigureFSwitchIntegration(data_time,n_perline,band,lo_freq,backendreadoutparms); } HIFIFSwitchOnIntegration(data_time,n_perline,band,lo_freq,onrates); // Check for normal slew towards the OFF if(state[2] % n_linesperscan == 0) { if(ioff % n_loadinterval > 0) { HIFIActiveHK("normal",toffslew); } } } if(state[0] == 9) { // Load slew delay(readoutdead); DoubleLoadMeasurement(band,lo_freq,freq_throw,eff_resolution{0},data_time,backendreadoutparms); } if(state[0] == 5) { delay(readoutdead); HIFICloseObs(); } } } //Set LCU6Ha back to standby status, procedure procedure LCU6Ha_standby_proc_fm { string band = "7a"; // HIFI band double lo_freq = 1700.0 in [1700.0,1800.0]; //LO frequency }{ error("This module is obsolete: use LCU_standby_proc_fm instead"); } //HIFI-COP-2.3-Param-Scan block0: TPF maker procedure TPF_maker_paramscan { int index = 1 in [1,2]; // Test case index as of config_paramscan_COP.config }{ //Read all band+param to perform string tab = "config_paramscan_COP.config"; int total = table_size(tab); string band = slookup(tab,"" + index,"band"); // //Switch-on LO //We use a constant frequency for each band, regardless of the input double lo_freq = 0.0; double[] result_d = CalibrationReader("name_keyfreq",["keyfreq","midfreq","keyfreqwarm","keyfreq_dummy"],band,0.0); lo_freq = result_d[0]; //this is for cold operations //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlcutune = "name_configlcutune_a"; string name_configlotune = "name_configlotune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlcutune = "name_configlcutune_b"; name_configlotune = "name_configlotune_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // result = ConfigurationReader("name_delays",["switch_on_delay","config_lo_delay"],band,lo_freq); int switch_on_delay = iround(result[0]{0}); int config_lo_delay = iround(result[1]{0}); // cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); drain2_v = cresult[0]; // //Generate TPF parameters //Convert into raw: int g1 = convert_to_raw("hifi_HL_Gate1_7B_V",gate1_v); int g2 = convert_to_raw("hifi_HL_Gate2_7B_V",gate2_v); int vd1 = convert_to_raw("hifi_HL_Drain1_7B_V",drain1_v); //convert_to_raw does not work for params defined through TextualCalibrationCurves //The convertion is: if(curlim1 == "1.5") { int curl1 = 0; } if(curlim1 == "1.4") { curl1 = 2; } if(curlim1 == "1.3") { curl1 = 1; } if(curlim1 == "1.22") { curl1 = 3; } // if(curlim2 == "1.5") { int curl2 = 0; } if(curlim2 == "1.4") { curl2 = 2; } if(curlim2 == "1.3") { curl2 = 1; } if(curlim2 == "1.22") { curl2 = 3; } int vd2 = convert_to_raw("hifi_HL_Drain2_7B_V",drain2_v); int mm1 = convert_to_raw("hifi_HL_M1_7B_V",m1_v); int mm2 = convert_to_raw("hifi_HL_M2_7B_V",m2_v); Hifi_HIFI_WBS_Zero(mm1); Hifi_HIFI_WBS_Zero(mm2); Hifi_HIFI_WBS_Zero(g1); Hifi_HIFI_WBS_Zero(g2); Hifi_HIFI_WBS_Zero(vd1); Hifi_HIFI_WBS_Zero(curl1); Hifi_HIFI_WBS_Zero(vd2); Hifi_HIFI_WBS_Zero(curl2); message("" + m1_v); message("" + m2_v); message("" + gate1_v); message("" + gate2_v); message("" + drain1_v); message("" + curlim1); message("" + drain2_v); message("" + curlim2); // //Parameters from LO_tuning_w_M1M2_block_fm(band,lo_freq,m1,m2) //Read all band+param to perform lo_freq = dlookup(tab,"" + index,"lofreq"); cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); gate1_v = cresult[0]; gate2_v = cresult[1]; drain1_v = cresult[2]; drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset resu = ComputeLSU_A_M_R(band,lo_freq); lsu_main = resu[0]; lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); curlim1 = result[0]{1}; curlim2 = result[1]{1}; // result = ConfigurationReader(name_configlotune,["step_drain2_v","nsteps","step_time"],band,lo_freq); double step_drain2_v = result[0]{0}; int nsteps = iround(result[1]{0}); double step_time = result[2]{0}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); // //For all bands, scan will be done with decreasing drain2 voltages //The best guess is taken from look-up table double tune_range = 0.1; result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lo_freq); //The automatic tuning shall use the min of the nominal best-guess and Vd2max - 100mV double middle_d2 = min(result[0]{0},drain2_bluemax - 0.1); double drain2_v_start = min(middle_d2 * (1.0 + tune_range / 2.0),drain2_bluemax); //Convert into raw: g1 = convert_to_raw("hifi_HL_Gate1_7B_V",gate1_v); g2 = convert_to_raw("hifi_HL_Gate2_7B_V",gate2_v); vd1 = convert_to_raw("hifi_HL_Drain1_7B_V",drain1_v); //convert_to_raw does not work for params defined through TextualCalibrationCurves //The convertion is: if(curlim1 == "1.5") { curl1 = 0; } if(curlim1 == "1.4") { curl1 = 2; } if(curlim1 == "1.3") { curl1 = 1; } if(curlim1 == "1.22") { curl1 = 3; } // if(curlim2 == "1.5") { curl2 = 0; } if(curlim2 == "1.4") { curl2 = 2; } if(curlim2 == "1.3") { curl2 = 1; } if(curlim2 == "1.22") { curl2 = 3; } vd2 = convert_to_raw("hifi_HL_Drain2_7B_V",drain2_v_start); //Read all band+param to perform double m1_min = dlookup(tab,"" + index,"m1_1"); double m1_max = dlookup(tab,"" + index,"m1_2"); double m1_step = dlookup(tab,"" + index,"m1_step"); double m2_min = dlookup(tab,"" + index,"m2_1"); double m2_max = dlookup(tab,"" + index,"m2_2"); double m2_step = dlookup(tab,"" + index,"m2_step"); double bias_min = dlookup(tab,"" + index,"bias_1"); double bias_max = dlookup(tab,"" + index,"bias_2"); double bias_step = dlookup(tab,"" + index,"bias_step"); double imix_min = dlookup(tab,"" + index,"imix_1"); double imix_max = dlookup(tab,"" + index,"imix_2"); double imix_step = dlookup(tab,"" + index,"imix_step"); double m1 = 0.0; double m2 = 0.0; //Phase 1 measurement: loop on M1 and M2 m1 = m1_max; //Loop on M1 double margin = 1.0E-7; while(m1 >= m1_min - margin) { //Loop on m2: cancelled for the moment - SCR-2460 m2 = m2_max; //while (m2>=m2_min) { // mm1 = convert_to_raw("hifi_HL_M1_7B_V",m1); mm2 = convert_to_raw("hifi_HL_M2_7B_V",m2); //Implementation of SCR-2460: for the time being, M2 is fixed to its nominal value - no scan result = ConfigurationReader(name_configlcu,["m2_v"],band,lo_freq); m2 = result[0]{0}; mm2 = convert_to_raw("hifi_HL_M2_7B_V",m2); // //Values for pre-amble Hifi_HIFI_WBS_Zero(mm1); Hifi_HIFI_WBS_Zero(mm2); Hifi_HIFI_WBS_Zero(g1); Hifi_HIFI_WBS_Zero(g2); Hifi_HIFI_WBS_Zero(vd1); Hifi_HIFI_WBS_Zero(curl1); Hifi_HIFI_WBS_Zero(vd2); Hifi_HIFI_WBS_Zero(curl2); message("" + m1); message("" + m2); message("" + gate1_v); message("" + gate2_v); message("" + drain1_v); message("" + curlim1); message("" + drain2_v_start); message("" + curlim2); //Values for vector scan Hifi_HIFI_WBS_Zero(mm1); Hifi_HIFI_WBS_Zero(mm2); Hifi_HIFI_WBS_Zero(g1); Hifi_HIFI_WBS_Zero(g2); Hifi_HIFI_WBS_Zero(vd1); Hifi_HIFI_WBS_Zero(curl1); Hifi_HIFI_WBS_Zero(vd2); Hifi_HIFI_WBS_Zero(curl2); // //message(band+", "+lo_freq+", "+m1+", "+m2); message("" + m1); message("" + m2); message("" + gate1_v); message("" + gate2_v); message("" + drain1_v); message("" + curlim1); message("" + drain2_v_start); message("" + curlim2); // //m2 = m2+m2_step; //} //end loop m2 m1 = m1 + m1_step; } //end loop m1 } //LO parameter scan without HotCold measurement //for Band 1a procedure LCU1a_power_scan_without_Tsys { string band = "1a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4 double lo_freq = 500.0 in [488.0,552.0]; //LO frequency double param_min = 1.0; //Min. of scanned parameter double param_max = 2.0; //Max. of scanned parameter double step_size = 0.1; //Step size string param_name = "D2"; //Code of scanned parameter: M1,M2,G1,G2,D1,D2. }{ error("This module is obsolete: use LCU_power_scan_without_Tsys instead"); } // LO settling time for a LO sub-band change, procedure. // Measures series of spectra while switching from // one sub-band to another procedure LO_Settling_time_proc_fm { string band_a = "1a" in ["1a","2a","3a","4a","5a","6a","7a"]; // HIFI band a string band_b = "1b" in ["1b","2b","3b","4b","5b","6b","7b"]; // HIFI band a int int_time1 = 3600; //Integration time after first tuning int int_time2 = 600; //Integration time after first and second switch double lo_freq_a = 500.0; //LO frequency in sub-band a double lo_freq_b = 600.0; //LO frequency in sub-band b string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ // //Get cold position {double,string}[] result_d = ConfigurationReader("name_confilfpu",["chop_cold"],band_a,0.0); double chop = result_d[0]{0}; // //WBS calibration if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band_a); } //Set up mixer for lo_freq_a Init_MSA_fm(band_a,"CLOSE",lo_freq_a,"ON"); LO_Settling_time_first_tuning_fm(band_a,int_time1,lo_freq_a,backend); // Init_MSA_fm(band_b,"CLOSE",lo_freq_b,"ON"); LO_Settling_time_second_tuning_fm(band_b,int_time2,lo_freq_b,backend); // Init_MSA_fm(band_a,"CLOSE",lo_freq_a,"ON"); LO_Settling_time_third_tuning_fm(band_a,int_time2,lo_freq_a,backend); // } {int,double,double,double,double,double} obs HifiMappingModeFSwitchOTFNoRef { string modeName = "fs-raster"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // chunk size given by the data rates and optimum speed int n_switch_on = 1 in [1,1800]; // Supersamplingfactor int n_cycles = 1 in [1,1200]; // Number of map coverages int load_interval = 1800 in [10,7200]; // load period defines number of lines between two loads }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode OpenMessages("HIFI Mapping - OTF Map Frequency Switch noRef",{data_time,0,0,n_switch_on,0,0,0,0,n_cycles,load_interval}); // Auxiliary routine for API parameter correction {double,double,int} mapused = ValidMapSize(band,lo_freq,lineDistance,nlines,stepsize,npoints,2 * data_time * n_switch_on); double line_used = mapused{0}; double scanvelocity = mapused{1}; int npoints_used = mapused{2}; // Call first part of the timing computer {int,int,int,int,bool,int,int} pre_timing = OTFFSwitchNoRef_pre_timing(nlines,npoints_used,band,lo_freq,freq_throw,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_switch_on,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,double,double,int,int,int} tpar = OTFDoubleChopNoRef_telescope(naifid,onPosition,lineDistance,nlines,line_used,scanvelocity,band,lo_freq,n_cycles,pre_timing); // Dummy call to spacecraft command int[] telescopetimes = line_scan_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17}); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,bool,int,int},double,double} post_timing = OTFDoubleChopNoRef_post_timing(pre_timing,telescopetimes,nlines,data_time,n_cycles); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = OTFDoubleChopNoRef_telescope(naifid,onPosition,lineDistance,nlines,line_used,scanvelocity,band,lo_freq,n_cycles,post_timing{1}); // Call telescope command telescopetimes = line_scan_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17}); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{0}; bool end_load_on = post_timing{1}{4}; int n_loadinterval = post_timing{1}{2}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { OTFFSwitchNoRef_commanding(band,lo_freq,freq_throw,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,npoints_used * n_switch_on,n_loadinterval,nlines * n_cycles,end_load_on,startobs,telescopetimes,loadlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double} tact = SingleChop_deadtimes("fs",band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,npoints_used * n_switch_on); double tscan = 2.0 * (tact{1} + tact{2}); double tdead = 2.0 * tact{2}; // // Call noise computer {double,double,double,double,double} noisevalues = FSwitchNoRef_noisecomputer(band,lo_freq,effResolution,oneGHzReference,n_switch_on * n_cycles,tscan,tdead); // Evaluate performance OTFDoubleChopNoRef_performance(band,lo_freq,effResolution,noisevalues,timeTaken,nlines,npoints_used,n_switch_on * n_cycles,true,tscan,tdead); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } //Get diplexer setting using "real" frequencies double[] procedure Get_Diplexer_setting { string band = "3a" in ["3a","3b","4a","4b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 810.0; //LO frequency }{ //Compute real frequency double real_lo_freq = Compute_Real_Freq(band,lo_freq); {double,string}[] result_d = ConfigurationReader("name_confildipl",["diplex_h_a","diplex_v_a","diplex_h_b","diplex_v_b"],band,lo_freq); if(band == "3a" || band == "4a" || band == "6a" || band == "7a") { double[] final_setting = [result_d[0]{0},result_d[1]{0}]; } else { final_setting = [result_d[2]{0},result_d[3]{0}]; } return final_setting; } // Normal combination of zero and comb measurement // 1s integration time, only WBS, maximum windows // Inherited from blocks 3604 and 3605 // // Returns dangling transmission time // int block WBS_Zero_Comb HIFI 6004 { string band = "4a"; // HIFI band (needed to estimate stabilization) double lo_freq = 978200.0; // LO frequency }{ // Get delays {double,string}[] result = ConfigurationReader("name_delays",["wbs_comb_delay"],band,lo_freq); int wbs_comb_delay = iround(result[0]{0}); // data frame transmission time (always 2 spectra) int data_time = wbs_comb_delay / 2; int rest_delay = wbs_comb_delay - 2 * data_time; wbs_comb_delay = wbs_comb_delay - rest_delay; // Data rate computation // The HIFI command is restricted to always read out both full WBS {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} fullreadoutparms = FrequencyCalibrationParms(true,true,false,false); // data rate and read-out time {int,double[]} fdataparms = AllDataRates(fullreadoutparms,data_time,false); int readout = fdataparms{0}; // Get attenuators for comb measurement {double,string}[] result_d = ConfigurationReader("name_configwbs",["hwh_att_band4_comb","hwh_att_band3_comb","hwh_att_band2_comb","hwh_att_band1_comb","hwh_att_in_comb","hwv_att_band4_comb","hwv_att_band3_comb","hwv_att_band2_comb","hwv_att_band1_comb","hwv_att_in_comb"],band,0.0); int hwh_att_band4 = iround(result_d[0]{0}); int hwh_att_band3 = iround(result_d[1]{0}); int hwh_att_band2 = iround(result_d[2]{0}); int hwh_att_band1 = iround(result_d[3]{0}); int hwh_att_in = iround(result_d[4]{0}); int hwv_att_band4 = iround(result_d[5]{0}); int hwv_att_band3 = iround(result_d[6]{0}); int hwv_att_band2 = iround(result_d[7]{0}); int hwv_att_band1 = iround(result_d[8]{0}); int hwv_att_in = iround(result_d[9]{0}); // // set data rates non_ess_hk_data_rate(fdataparms{1}[2] / 1024.0); data_rate(fdataparms{1}[0] / 1024.0); // Insert a Noop because previous command could have been issued in second bus slot Hifi_HIFI_noop(); // Call command Hifi_HIFI_WBS_Comb($BBID,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // Currently I ignore that the COMB ends with ZERO=on (SCR 618) delay(wbs_comb_delay); // reset data rates non_ess_hk_data_rate(fdataparms{1}[1] / 1024.0); data_rate(0.0); delay(rest_delay); // // additional delay for packet transmission before next zero depends // on zero duration - needs to be introduced on higher level return readout; } // Configuration for frequency-switch integration block HIFIConfigureFSwitchIntegration HIFI 6037 { int data_time = 4; // Integration time between two data readouts int n_cycle = 1; // chop cycle number string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // HRS1/2 {used,resolution,subbands used}, WBS1/2 {used, channel windows} }{ // Call procedure doing the work ConfigureSpectroscopy(data_time,2 * n_cycle,"fs",band,lo_freq,backendreadoutparms); } // HRS partial configuration, procedure // Configures the LO and attenuators procedure HRS_config_att_lo_fm { string band = "1a"; // HIFI band string[] hrs_mode = ["mr","mr"]; //HRS resolution code }{ // Fetch HRS configuration parameters //=================================== //H-polar string hrs_filename_h = "name_confighrs_" + hrs_mode[0]; {double,string}[] result = ConfigurationReader(hrs_filename_h,["hrh_switch","hrh_1u_att","hrh_1l_att","hrh_2u_att","hrh_2l_att","hrh_3u_att","hrh_3l_att","hrh_4u_att","hrh_4l_att","hrh_up_ol1","hrh_up_ol2","hrh_up_ol3","hrh_up_ol4","hrh_down_ol5","hrh_down_ol6","hrh_down_ol7"],band,0.0); string hrs_polarization_h = result[0]{1}; double hrsH_ATT_U1 = result[1]{0}; double hrsH_ATT_L1 = result[2]{0}; double hrsH_ATT_U2 = result[3]{0}; double hrsH_ATT_L2 = result[4]{0}; double hrsH_ATT_U3 = result[5]{0}; double hrsH_ATT_L3 = result[6]{0}; double hrsH_ATT_U4 = result[7]{0}; double hrsH_ATT_L4 = result[8]{0}; double[] hrsH_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; //V-polar string hrs_filename_v = "name_confighrs_" + hrs_mode[1]; result = ConfigurationReader(hrs_filename_v,["hrv_switch","hrv_1u_att","hrv_1l_att","hrv_2u_att","hrv_2l_att","hrv_3u_att","hrv_3l_att","hrv_4u_att","hrv_4l_att","hrv_up_ol1","hrv_up_ol2","hrv_up_ol3","hrv_up_ol4","hrv_down_ol5","hrv_down_ol6","hrv_down_ol7"],band,0.0); string hrs_polarization_v = result[0]{1}; double hrsV_ATT_U1 = result[1]{0}; double hrsV_ATT_L1 = result[2]{0}; double hrsV_ATT_U2 = result[3]{0}; double hrsV_ATT_L2 = result[4]{0}; double hrsV_ATT_U3 = result[5]{0}; double hrsV_ATT_L3 = result[6]{0}; double hrsV_ATT_U4 = result[7]{0}; double hrsV_ATT_L4 = result[8]{0}; double[] hrsV_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; // result = ConfigurationReader("name_delays",["hrs_config_delay"],band,0.0); int hrs_config_delay = iround(result[0]{0}); //Convert IF frequencies into A and M parameters //Truncate wb or hr keyword: string[] output_hrs_mode = GetHrsMode_proc_fm(hrs_mode); string hrs_mode_h = output_hrs_mode[0]; string hrs_mode_v = output_hrs_mode[1]; // int[] a_m_parameter = ComputeA_M_parameters([hrs_mode_h,hrs_mode_v],hrsH_LO[0],hrsH_LO[1],hrsH_LO[2],hrsH_LO[3],hrsH_LO[4],hrsH_LO[5],hrsH_LO[6],hrsV_LO[0],hrsV_LO[1],hrsV_LO[2],hrsV_LO[3],hrsV_LO[4],hrsV_LO[5],hrsV_LO[6]); //H-polar int hrsH_LO1_M = a_m_parameter[1]; int hrsH_LO1_A = a_m_parameter[0]; int hrsH_LO2_M = a_m_parameter[3]; int hrsH_LO2_A = a_m_parameter[2]; int hrsH_LO3_M = a_m_parameter[5]; int hrsH_LO3_A = a_m_parameter[4]; int hrsH_LO4_M = a_m_parameter[7]; int hrsH_LO4_A = a_m_parameter[6]; int hrsH_LO5_M = a_m_parameter[9]; int hrsH_LO5_A = a_m_parameter[8]; int hrsH_LO6_M = a_m_parameter[11]; int hrsH_LO6_A = a_m_parameter[10]; int hrsH_LO7_M = a_m_parameter[12]; Hifi_HIFI_Config_HRS_H_att_lo($BBID,hrs_polarization_h,hrsH_ATT_U1,hrsH_ATT_L1,hrsH_ATT_U2,hrsH_ATT_L2,hrsH_ATT_U3,hrsH_ATT_L3,hrsH_ATT_U4,hrsH_ATT_L4,hrsH_LO1_M,hrsH_LO1_A,hrsH_LO2_M,hrsH_LO2_A,hrsH_LO3_M,hrsH_LO3_A,hrsH_LO4_M,hrsH_LO4_A,hrsH_LO5_M,hrsH_LO5_A,hrsH_LO6_M,hrsH_LO6_A,hrsH_LO7_M); // //delay(hrs_config_delay); //V-polar int hrsV_LO1_M = a_m_parameter[14]; int hrsV_LO1_A = a_m_parameter[13]; int hrsV_LO2_M = a_m_parameter[16]; int hrsV_LO2_A = a_m_parameter[15]; int hrsV_LO3_M = a_m_parameter[18]; int hrsV_LO3_A = a_m_parameter[17]; int hrsV_LO4_M = a_m_parameter[20]; int hrsV_LO4_A = a_m_parameter[19]; int hrsV_LO5_M = a_m_parameter[22]; int hrsV_LO5_A = a_m_parameter[21]; int hrsV_LO6_M = a_m_parameter[24]; int hrsV_LO6_A = a_m_parameter[23]; int hrsV_LO7_M = a_m_parameter[25]; Hifi_HIFI_Config_HRS_V_att_lo($BBID,hrs_polarization_v,hrsV_ATT_U1,hrsV_ATT_L1,hrsV_ATT_U2,hrsV_ATT_L2,hrsV_ATT_U3,hrsV_ATT_L3,hrsV_ATT_U4,hrsV_ATT_L4,hrsV_LO1_M,hrsV_LO1_A,hrsV_LO2_M,hrsV_LO2_A,hrsV_LO3_M,hrsV_LO3_A,hrsV_LO4_M,hrsV_LO4_A,hrsV_LO5_M,hrsV_LO5_A,hrsV_LO6_M,hrsV_LO6_A,hrsV_LO7_M); // delay(hrs_config_delay); } // Functional test with pumped mixer, procedure procedure FT_pumped { string band = "1a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4,etc int integ_time = 4; //Integration time string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast double lo_freq = 500.0; //LO frequency }{ // //WBS calibration. Attenuators are set later in the magnet tuning if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_config_block_fm(band); WBS_calib_fm(band); } if(backend == "hrs" || backend == "both") { HRS_config_block_fm(band,hrs_mode); } // //Re-Configure spectrometer integration Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); // IVcurve_pumped_fm(band,lo_freq); // //Does a magnet tuning: only up to band 5 since band6-7 have no magnets if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { Magnet_tuning_block_fm(band,lo_freq,"HRS",40); } // //Go on hot load Chopper_Rotation_block_fm(band,"chop_M3_ang","chop_hot_ang"); //Tune backends on the hot load if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_tune_proc_fm(band); } if(backend == "hrs" || backend == "both") { HRS_tune_block_fm(band); } //Reconfigure spectrometer integration after tuning int[] res = Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); //Radiometry on internal loads Hot_cold(band,hrs_mode,backend,res[0] * res[1],"tp",0,0); //Back to middle of M3 Chopper_Rotation_block_fm(band,"chop_hot_ang","chop_M3_ang"); } ///////////////////////////////////////////////////////////////// // Procedure to filter only those attenuator settings that are used double[][] procedure GetSScanLevelGrid { string band = "4a"; // HIFI band {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} double[] freqgrid = [978053.7,978301.8,978381.1]; // frequency grid int groupnumber = 1; // Number of frequency groups int[][] grouporder = [[0],[0]]; // Sequence to trace frequency points in groups }{ // Reduce frequency field - select center frequency of groups only if(groupnumber < length(freqgrid)) { int nfreq = length(freqgrid); double[] redfreq = []; int oldindex = 0; int groupsize = nfreq / groupnumber; // It is not clear whether grouporder[0,0] or grouporder[1,0] // is the better point. First better for DBS, second for NoRef. for(int j1 = 0 .. groupnumber - 1) { oldindex = j1 * groupsize + grouporder[0][0]; redfreq[j1] = freqgrid[oldindex]; } } else { redfreq = freqgrid; } // Make field of subbands that are used int idest = 0; int[] usedsubbands = []; for(int i = 0 .. 3) { if(wbs1{0} && wbs1{1}[i][1] - wbs1{1}[i][0] > 0) { usedsubbands[idest] = i; idest = idest + 1; } } for(int ii = 0 .. 3) { if(wbs2{0} && wbs2{1}[ii][1] - wbs2{1}[ii][0] > 0) { usedsubbands[idest] = ii + 4; idest = idest + 1; } } // Create dB grid needed for backend retuning double[][] retunegrid = GetSScanLevels(band,redfreq,usedsubbands); return retunegrid; } // Initialisation, block with all IF set ON but unpumped mixers block Init_all_IF_fm HIFI 3215 { string band = "1a"; // HIFI band string mixer_polarization = "B" in ["H","V","B"]; //Polarization: H, V, or both (B) }{ Start_block(); //Get parameters {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,0.0); int band_nb = iround(result_d[0]{0}); // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // Check whether H-polar is requested if(mixer_polarization == "V") { result_d = ConfigurationReaderWarm("name_confilfpu",["fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],"0",0.0); // volt_H_FIF_1 = result_d[0]{0}; curr_H_FIF_1 = result_d[1]{0}; volt_H_FIF_2 = result_d[2]{0}; curr_H_FIF_2 = result_d[3]{0}; // volt_H_SIF_1 = result_d[4]{0}; curr_H_SIF_1 = result_d[5]{0}; volt_H_SIF_2 = result_d[6]{0}; curr_H_SIF_2 = result_d[7]{0}; volt_H_SIF_3 = result_d[8]{0}; curr_H_SIF_3 = result_d[9]{0}; } // result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,0.0); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // Check whether H-polar is requested if(mixer_polarization == "H") { result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],"0",0.0); // volt_V_FIF_1 = result_d[0]{0}; curr_V_FIF_1 = result_d[1]{0}; volt_V_FIF_2 = result_d[2]{0}; curr_V_FIF_2 = result_d[3]{0}; // volt_V_SIF_1 = result_d[4]{0}; curr_V_SIF_1 = result_d[5]{0}; volt_V_SIF_2 = result_d[6]{0}; curr_V_SIF_2 = result_d[7]{0}; volt_V_SIF_3 = result_d[8]{0}; curr_V_SIF_3 = result_d[9]{0}; } // string chop_sine_s = "ON"; string chop_loop = "CLOSE"; //Chopper is not used anyway result_d = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current_on"],band,0.0); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // double calibcurrent = result_d[7]{0}; // //Junctions do not need to be biased, nor should diplexers be moved double bias_H = 0.5; double magnetcurrent_H = 0.0; double bias_V = 0.5; double magnetcurrent_V = 0.0; double diplex_H = 0.0; double diplex_V = 0.0; int diplex_h_ctrl_mode = 0; int diplex_v_ctrl_mode = 0; // double chopper = 0.0; // // chopper = Check_Chopper_Prime_Redundant(chopper); HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result_d = ConfigurationReader("name_delays",["config_fpu_delay"],band,0.0); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // } //////////////////////////////////// // Functions for two dimensional vectors, e.g. coordinates on the sky // Multiply a vector defined as a tuple with a scaler defined as a double {double,double} procedure MultiplyScalarVector { double scalar = 1.0; {double,double} vector = {1.0,1.0}; }{ return {vector{0} * scalar,vector{1} * scalar}; } //HIFI-COP-2.1-DPL-RespTime //Check diplexer response time for all diplexer bands obs HifiEng_Diplexer_Response_time_COP { string band = "3a" in ["3a","4a","6a","7a"]; //Mixer diplexer band: 3a, 4a, 6a or 7a string mixer_polarization = "H"; //mixer polarization: H or V }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Diplexer_Response_time_COP_proc_ops(band,mixer_polarization)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Diplexer_Response_time_COP_proc_ops(band,mixer_polarization); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } //////////////////////////////////// // OTF observing mode // // Combination of four modules implementing the new structure // // Return time and noise levels {int,double,double,double,double,double} obs HifiMappingProcOTF { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the map center double dec = 0.0; // DEC coordinate of the map center double raoff = 0.0; // RA coordinate of the OFF position double decoff = 0.0; // DEC coordinate of the OFF position bool refSelected = true; // Dummy parameter required by HSPOT {double,double} lineDistance = {0.0050,0.0050}; // Distance between subsequent rows int nlines = 1 in [1,240]; // Number of rows in the map double stepsize = 0.0050 in [0.0,0.13333]; // Distance between subsequent points in the OTF line int npoints = 10 in [1,720]; // Number of data dumps per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,5]; // chunk size given by the data rates and optimum speed int n_int_on = 1 in [1,1800]; // Supersamplingfactor int n_linesperscan = 1 in [1,32]; // Number of lines between two OFFs int n_switch_off = 3 in [1,3600]; // Number of data dumps for the OFF integration time int n_cycles = 1 in [1,1200]; // Number of map coverages int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Mapping - OTF Map Position Switch",{data_time,0,n_int_on,0,n_switch_off,n_linesperscan,0,0,n_cycles,load_interval}); // Auxiliary routine for API parameter correction {double,double,int} mapused = ValidMapSize(band,lo_freq,lineDistance,nlines,stepsize,npoints,data_time * n_int_on); double line_used = mapused{0}; double scanvelocity = mapused{1}; int npoints_used = mapused{2}; // Call first part of the timing computer {int,int,int,int,int,int,int,int} pre_timing = OTFmap_pre_timing(nlines,npoints_used,band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_linesperscan,n_switch_off,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {double,double} refPosition = {raoff,decoff}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,double,double,int,int,double,double,int,int,int,int,int} tpar = OTFmap_telescope(naifid,onPosition,lineDistance,nlines,line_used,refPosition,scanvelocity,band,lo_freq,n_linesperscan,n_cycles,pre_timing); // Dummy call to spacecraft command int[] telescopetimes = line_scan_with_off_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23}); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int},double,double} post_timing = OTFmap_post_timing(pre_timing,telescopetimes,data_time,n_linesperscan,n_cycles,load_interval); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = OTFmap_telescope(naifid,onPosition,lineDistance,nlines,line_used,refPosition,scanvelocity,band,lo_freq,n_linesperscan,n_cycles,post_timing{1}); // Call telescope command telescopetimes = line_scan_with_off_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23}); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int n_pp = post_timing{1}{0}; int n_scans = post_timing{1}{1}; int loadlength = post_timing{1}{4}; int n_loadinterval = post_timing{1}{5}; double tscan = post_timing{2}; double tdead = post_timing{3}; // telescope time int slewtime = telescopetimes[6]; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { OTFmap_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,nlines * n_cycles,n_linesperscan,n_switch_off,n_pp,n_loadinterval,startobs,telescopetimes,loadlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check]) int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double} tact = OTFmap_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_linesperscan,n_switch_off,n_pp,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = OTFmap_noisecomputer(band,lo_freq,effResolution,oneGHzReference,nlines,npoints_used,n_int_on,n_linesperscan,n_cycles,slewtime,tscan,tact); // Evaluate performance OTF_performance(band,lo_freq,effResolution,noisevalues,timeTaken,nlines,npoints_used,n_scans,n_cycles,tscan,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } //Procedure to store currently tuned frequency, procedure procedure HIFI_HL_store_tm_proc_fm { }{ Hifi_HIFI_HL_store_tm($BBID); //This commands sends a request to get FSW1/2 into non-periodic HK //Removed as of SPR-1747 //Hifi_HIFI_LCU_macro_buffers(); delay(1); } ////////////////////////////////////////////////////////////////////////// // Procedure to compute detailed timing of DBS-raster observing mode {int,{int,int,int,int,int,int,int,int,int,int,int,int,int},bool,double,double} procedure DBSRaster_post_timing { {int,int,int,int,int,int,int,int,int,int,int,int,int} pre_timing = {4,10,4,21,1,1800,0,10,1,1,1,50,0}; // pre timing parameter list int[] telescopetimes = [300,180,10,0,10,20,21,0,0,0]; int nlines_tot = 1; // Number of rows in the map int npoints = 10; // Number of points per row int n_chop = 2; // number of half sky1-sky0-sky0-sky1 cycles per pointing int n_cycles = 1; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800; // load period = f(band,lo_freq,eff_resolution{1}) bool fastchop = false; // whether fast-chop is used instead of slow-chop }{ // Get all values from the pre_timing section int inttime = pre_timing{0}; int pointing = pre_timing{1}; int readouttime = pre_timing{2}; int loadlength = pre_timing{3}; int jitterdead = pre_timing{4}; int load_spacing = pre_timing{5}; int n_load = pre_timing{6}; int n_loadinterval = pre_timing{7}; int n_seq = pre_timing{8}; int n_scans = pre_timing{9}; int scansize = pre_timing{10}; int initlength = pre_timing{11}; int dangling = pre_timing{12}; // Get all values from the telescope section int telinit = telescopetimes[1]; // Initial slew time int slewtime = telescopetimes[2]; // Slew time to next point if(scansize > 1) { int nodtime = telescopetimes[4]; // Slew time to second nod int slewline = telescopetimes[3]; // Slew between lines int longslew = telescopetimes[5]; // Actual slew time for load slew int returntime = telescopetimes[6]; // Idle time between two phases int tend = telescopetimes[7]; // Final deceleration time } else { nodtime = telescopetimes[5]; slewline = telescopetimes[4]; longslew = telescopetimes[6]; returntime = telescopetimes[3]; tend = telescopetimes[9]; } int shortmove = imin(slewtime,slewline); shortmove = imin(shortmove,returntime); // Total number of scans int n_tot = n_scans * n_cycles; /////////////////////// // Long computation for scansize > 1 to obtain all slew durations {int,int} alldeadtimes = Raster_slewtimes(nlines_tot,npoints,n_cycles,scansize,nodtime,slewtime,slewline,returntime); int tinscandead = alldeadtimes{0}; int toutscandead = alldeadtimes{1}; // Compute total duration of measurement and average scan length int totalscantime = n_tot * (2 * pointing * scansize) + tinscandead; // approximate scan time for load comparison int scan_time = iceil(double(totalscantime) / double(2 * n_tot)); if(load_spacing > 2 * scan_time) { n_seq = n_chop; pointing = inttime + jitterdead; bool end_load = false; } else { // It could happen that the slew extends the scan too much - catch if(scansize > 1) { SError("Number of points in one scan too large for load period."); } n_load = n_load + 1; n_seq = n_chop / n_load; if(n_seq < 1) { SError("Transfer cycle too long relative to load period."); } // adjust pointing time to include load measurements int loadappend = imax(loadlength - shortmove,0); end_load = true; // Computation for slow-chop or fast-chop if(fastchop) { inttime = n_seq * n_load * readouttime; } else { inttime = 2 * n_seq * n_load * readouttime; } pointing = inttime + loadappend + (n_load - 1) * loadlength + jitterdead; } totalscantime = n_tot * (2 * pointing * scansize) + tinscandead + toutscandead; scan_time = iceil(double(totalscantime) / double(2 * n_tot)); // compute the load interval in case of short scan_time n_loadinterval = imax((load_interval - loadlength + nodtime) / (2 * scan_time),1); // Special treatment for nodding_raster due to limitations in API // Split into loads per point or per multiple points if(scansize == 1 && n_loadinterval > n_cycles) { n_loadinterval = n_cycles * (n_loadinterval / n_cycles); // Translate load waiting time into a hold after the point int holdlength = imax(loadlength - nodtime,0); longslew = nodtime + holdlength; } else { holdlength = 0; } // Special treatment for loads per point to compensate counter reset if(scansize == 1 && n_loadinterval < n_cycles) { int dangling_period = n_cycles % n_loadinterval; while((dangling_period + n_loadinterval) * 2 * scan_time > load_interval - loadlength + nodtime) { n_loadinterval = n_loadinterval - 1; dangling_period = n_cycles % n_loadinterval; } // Consistency check if(n_loadinterval < 1) { CError("Too short load period computed."); } int n_long = n_scans * (n_cycles / n_loadinterval); } else { n_long = n_tot / n_loadinterval; } // Compute total duration of measurement, correct for load nods totalscantime = n_tot * (2 * pointing * scansize) + tinscandead + n_long * (longslew - nodtime); // Average dead and scan time for drift estimate double tscan = double(totalscantime) / double(n_tot); double tdead = tscan - double(2 * inttime * scansize); // Count integration times of other points of one nod as dead time // Other points in the second nod are excluded from the scan double othertime = double((scansize - 1) * inttime); tdead = tdead + othertime; // Reduce scan time by the other points in the second nod phase tscan = tscan - othertime; // Determine need for final load measurement double rest = double(n_tot % n_loadinterval) + 0.5; bool final_load = rest > 0.5001 * double(n_loadinterval); // Compute total duration // The initial time is no longer contained in the total time // int totaltime=imax(initlength,telinit); int totaltime = totalscantime + toutscandead; // Add dangling load time if not included in pointing // they are mutually exclusive, otherwise the readoutdelay applies if(final_load) { dangling = loadlength; } if(end_load) { dangling = loadlength - loadappend; } int closelength = duration(HIFICloseObs()); dangling = imax(dangling + closelength - tend,0); totaltime = totaltime + dangling + tend; // show gyro-propagation messages if(scansize > 1) { GCPMessages(0,totalscantime,tend); } else { GCPMessages(pointing,totalscantime,tend); } // Return all the times needed in the observing mode modules return {totaltime,{inttime,pointing,readouttime,loadlength,holdlength,load_spacing,n_load,n_loadinterval,n_seq,n_scans,scansize,initlength,dangling},final_load,tscan,tdead}; } //HIFI-COP-1.2-LO_FT procedure COP_LO_FT_TPF_maker { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ // double[] cresult_d = CalibrationReader("name_keyfreq",["keyfreq"],band,0.0); double lo_freq = cresult_d[0]; //applies to cold LO // //Get diplexer settings at this frequency int diplh = convert_to_raw("hifi_HF_CH1_DPACT_C",0.0); int diplv = convert_to_raw("hifi_HF_CV1_DPACT_C",0.0); if(band == "3a" || band == "3b" || band == "4a" || band == "4b" || band == "6a" || band == "6b" || band == "7a" || band == "7b") { double[] result_dip = Get_Diplexer_setting(band,lo_freq); diplh = convert_to_raw("hifi_HF_CH1_DPACT_C",result_dip[0]); diplv = convert_to_raw("hifi_HF_CV1_DPACT_C",result_dip[1]); } Hifi_HIFI_WBS_Zero(diplh); Hifi_HIFI_WBS_Zero(diplv); //Switch on with safe Vd2 //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlcutune = "name_configlcutune_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1_v = result[0]{1}; string curlim2_v = result[1]{1}; // cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); drain2_v = cresult[0]; //Note: check that Vd2 is within the blue limits drain2_v = Check_BLUE_LIMIT_D2_proc_fm(band,lo_freq,drain2_v); //Send command: expect that we have already switched to NOMINAL //We set D2 to best guess and wait some time to stabilize chain temperature int bbid = 237043713; if(band == "1a") { //Band 1a Hifi_HIFI_Conf_safe_LCU_ch1a(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "1b") { //Band 1b Hifi_HIFI_Conf_safe_LCU_ch1b(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "2a") { //Band 2a Hifi_HIFI_Conf_safe_LCU_ch2a(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "2b") { //Band 2b Hifi_HIFI_Conf_safe_LCU_ch2b(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "3a") { //Band 3a Hifi_HIFI_Conf_safe_LCU_ch3a(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "3b") { //Band 3b Hifi_HIFI_Conf_safe_LCU_ch3b(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "4a") { //Band 4a Hifi_HIFI_Conf_safe_LCU_ch4a(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "4b") { //Band 4b Hifi_HIFI_Conf_safe_LCU_ch4b(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "5a") { //Band 5a Hifi_HIFI_Conf_nom_LCU_ch5a(bbid,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "5b") { //Band 5b Hifi_HIFI_Conf_nom_LCU_ch5b(bbid,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "6a") { //Band 6a Hifi_HIFI_Conf_nom_LCU_ch6a(bbid,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "6b") { //Band 6b Hifi_HIFI_Conf_nom_LCU_ch6b(bbid,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "7a") { //Band 7a Hifi_HIFI_Conf_nom_LCU_ch7a(bbid,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "7b") { //Band 7b Hifi_HIFI_Conf_nom_LCU_ch7b(bbid,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } // //Set heater to their switch-on value bbid = 236912641; string context = "nominal"; cresult = CalibrationReader("name_loheater",["heater_nominal","heater_stby"],band,0.0); double hifi_HL_heater = cresult[0]; if(context == "stby") { hifi_HL_heater = cresult[1]; } Hifi_HIFI_HL_heater(bbid,hifi_HL_heater); //LO_SFT_proc_cop //Send command: expect that we have already switched to NOMINAL //We set D2 to best guess and wait some time to stabilize chain temperature bbid = 237043714; if(band == "1a") { //Band 1a Hifi_HIFI_Conf_safe_LCU_ch1a(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "1b") { //Band 1b Hifi_HIFI_Conf_safe_LCU_ch1b(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "2a") { //Band 2a Hifi_HIFI_Conf_safe_LCU_ch2a(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "2b") { //Band 2b Hifi_HIFI_Conf_safe_LCU_ch2b(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "3a") { //Band 3a Hifi_HIFI_Conf_safe_LCU_ch3a(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "3b") { //Band 3b Hifi_HIFI_Conf_safe_LCU_ch3b(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "4a") { //Band 4a Hifi_HIFI_Conf_safe_LCU_ch4a(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "4b") { //Band 4b Hifi_HIFI_Conf_safe_LCU_ch4b(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "5a") { //Band 5a Hifi_HIFI_Conf_nom_LCU_ch5a(bbid,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "5b") { //Band 5b Hifi_HIFI_Conf_nom_LCU_ch5b(bbid,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "6a") { //Band 6a Hifi_HIFI_Conf_nom_LCU_ch6a(bbid,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "6b") { //Band 6b Hifi_HIFI_Conf_nom_LCU_ch6b(bbid,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "7a") { //Band 7a Hifi_HIFI_Conf_nom_LCU_ch7a(bbid,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "7b") { //Band 7b Hifi_HIFI_Conf_nom_LCU_ch7b(bbid,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } // //Set heater to their switch-on value bbid = 236912642; context = "nominal"; cresult = CalibrationReader("name_loheater",["heater_nominal","heater_stby"],band,0.0); hifi_HL_heater = cresult[0]; if(context == "stby") { hifi_HL_heater = cresult[1]; } Hifi_HIFI_HL_heater(bbid,hifi_HL_heater); //Send best-guess Vd2 for SFT cresult_d = CalibrationReader("name_keyfreq",["key_d2v_P","key_d2v_R"],band,0.0); //Check what d2_v to use depending on test circumstances drain2_v = cresult_d[0]; //Value for prime case, and fm H/W if(prime_or_redundant == "redundant") { drain2_v = cresult_d[1]; } // //Note: check that Vd2 is within the blue limits drain2_v = Check_BLUE_LIMIT_D2_proc_fm(band,lo_freq,drain2_v); bbid = 237043715; if(band == "1a") { //Band 1a Hifi_HIFI_Conf_safe_LCU_ch1a(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "1b") { //Band 1b Hifi_HIFI_Conf_safe_LCU_ch1b(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "2a") { //Band 2a Hifi_HIFI_Conf_safe_LCU_ch2a(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "2b") { //Band 2b Hifi_HIFI_Conf_safe_LCU_ch2b(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "3a") { //Band 3a Hifi_HIFI_Conf_safe_LCU_ch3a(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "3b") { //Band 3b Hifi_HIFI_Conf_safe_LCU_ch3b(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "4a") { //Band 4a Hifi_HIFI_Conf_safe_LCU_ch4a(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "4b") { //Band 4b Hifi_HIFI_Conf_safe_LCU_ch4b(bbid,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "5a") { //Band 5a Hifi_HIFI_Conf_nom_LCU_ch5a(bbid,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "5b") { //Band 5b Hifi_HIFI_Conf_nom_LCU_ch5b(bbid,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "6a") { //Band 6a Hifi_HIFI_Conf_nom_LCU_ch6a(bbid,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "6b") { //Band 6b Hifi_HIFI_Conf_nom_LCU_ch6b(bbid,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "7a") { //Band 7a Hifi_HIFI_Conf_nom_LCU_ch7a(bbid,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "7b") { //Band 7b Hifi_HIFI_Conf_nom_LCU_ch7b(bbid,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } // } // Take slow chop spectra, block block Spectro_slow_chop_block_fm HIFI 3607 { string band = "1a"; // HIFI band double[] chop_angle = [-1.0,+1.0]; //The two angles to chop between int[] timing_parms = [4,2]; //single readout time in sec. and n_wbs_start string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); int integ_time = timing_parms[0] * timing_parms[1]; //Compute data-rate double[] rates = ILT_datarate_proc_fm(band,backend,"slowchop",integ_time); //Take spectrum // set data rates non_ess_hk_data_rate(rates[2] / 1024.0); data_rate(rates[0] / 1024.0); // HIFI_Spectr_slow_chop_proc_fm(chop_angle[0],chop_angle[1]); //This probably needs to be adapted Apply_Slow_Chop_delay(integ_time,band,backend); // reset data rates non_ess_hk_data_rate(rates[1] / 1024.0); data_rate(0.0); } // Switch HIFI off, mode // Assumed to be in rescue mode when starting this mode // mode HifiManCmd_HIFI_Rescue_to_switched_off { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ Mode_status_check_rescue("failure"); mois_comment("Switch from HIFI rescue to switch off: switches off the ICU"); //Here ICU is not working properly so no obsid or HK handling //StartMode_block_ops(); string icu_subsys = "ICU_Prime"; if(prime_or_redundant == "Red") { icu_subsys = "ICU_Red"; } PDU_switch_off_block_ops(icu_subsys); //Here, HIFI is idle: the switch back to obsid = 0 is done just before ICU switched off //StopMode_block_ops () ; Mode_status_check_switched_off(); } // LCU3b configuration and tuning, procedure procedure LCU3b_config_tune_proc_fm { string band = "3b"; // HIFI band double lo_freq = 900.0 in [852.0,953.0]; //LO frequency double drain_2_factor = 100.0; //Percentage factor of the targetted drain voltage }{ error("This module is obsolete: use LO_tuning_block_fm instead"); } // Stability test, procedure // Measurement of internal cold in FSW mode // In COP, look at the sky procedure Proc_stability_freqswitch_COP { string band = "1a"; // HIFI band double lo_freq = 522.0; //The LO frequency double freq_throw = 50.0; //The frequency throw in MHz int n = 100; //Number of load pairs to be measured string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int integ_time = 4; //Total (co-added) integration time of a phase in sec. string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast int freq_index = 1; //Frequency index to be applied }{ // //Tune to the two frequencies: the first frequency is the one //used to tune the backends // //Set Diplexer to the frequency used for the standing wave test //Implementation of SCR-2348 string tabstwv = "config_stwvfreq.config"; double bandnb = GetBandCode(band); double stwvfreq = dlookup(tabstwv,"" + iceil(bandnb),"freq" + freq_index); Set_Diplexer_current_FSW_block_fm(band,stwvfreq); //Old approach: diplexer at middle freq between FSW1 and FSW2 //Set_Diplexer_current_FSW_block_fm(band,lo_freq+freq_throw/2000.); // //Set to FSW1 LO_tuning_FSW_block_fm(band,lo_freq,lo_freq + freq_throw / 2000.0,true); //The frequency settings are automatically stored in register FSW1 // //Configure backends if(backend == "hrs" || backend == "both" || backend == "hrsFast") { HRS_config_block_fm(band,hrs_mode); HRS_tune_block_fm(band); } if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { //WBS calibration WBS_calib_fm(band); WBS_tune_proc_fm(band); } // //set to FSW2 LO_tuning_FSW_block_fm(band,lo_freq + freq_throw / 1000.0,lo_freq + freq_throw / 2000.0,false); //The frequency settings are automatically stored in register FSW2 // //Configure spectrometers integration after tuning: done later //Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); // Chopper_Rotation_block_fm(band,"chop_M3_ang","chop_M3_ang"); //Look at M3 for stability measurement // Stability_freqswitch_fm(band,n,integ_time,hrs_mode,backend); //Configure spectrometers integration back to default in tp mode Configure_Spectrometer_proc_fm(band,4,hrs_mode,backend); //2 sec. integration } // Rotate angle by -90 deg double procedure RotateRight { double angle = 0.0; // Original angle }{ double fullcircle = 360.0; return (angle + fullcircle * 0.75) % fullcircle; } // WBS configuration with minimum attenuation, block // Laser can be chosen block WBS_config_min_att_w_laser_block_fm HIFI 3642 { string band = "1a"; // HIFI band string laser_H = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-V laser to be set ON }{ //Start_block(); //H-Polarization // {double,string}[] result_d = ConfigurationReader("name_configwbs",["hwh_laser1_s","hwh_laser2_s","hwh_heater","hwh_latchup_s"],band,0.0); string hwh_laser1_s = "OFF"; string hwh_laser2_s = "OFF"; if(laser_H == "Laser1") { hwh_laser1_s = "ON"; } if(laser_H == "Laser2") { hwh_laser2_s = "ON"; } int hwh_heater = iround(result_d[2]{0}); string hwh_latchup_s = result_d[3]{1}; int hwh_att_band4 = 0; int hwh_att_band3 = 0; int hwh_att_band2 = 0; int hwh_att_band1 = 0; int hwh_att_in = 0; // result_d = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result_d[0]{0}); //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); //delay(wbs_config_delay); //V-Polarization //Get configuration parameters // result_d = ConfigurationReader("name_configwbs",["hwv_laser1_s","hwv_laser2_s","hwv_heater","hwv_latchup_s"],band,0.0); string hwv_laser1_s = "OFF"; string hwv_laser2_s = "OFF"; if(laser_V == "Laser1") { hwv_laser1_s = "ON"; } if(laser_V == "Laser2") { hwv_laser2_s = "ON"; } int hwv_heater = iround(result_d[2]{0}); string hwv_latchup_s = result_d[3]{1}; int hwv_att_band4 = 0; int hwv_att_band3 = 0; int hwv_att_band2 = 0; int hwv_att_band1 = 0; int hwv_att_in = 0; //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // //Wait delay to allow all setting to be configured delay(wbs_config_delay); } //TM check when in Primary mode procedure Mode_status_check_primary { string laser_H = "Laser1" in ["Laser1","Laser2"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2"]; //WBS-V laser to be set ON string chopper_loop = "OPEN" in ["OPEN","CLOSE"]; //chopper loop status }{ mois_comment("Checking instrument status in primary mode"); //General checks: not needed here as we won't be at that stage otherwise //FCU checks {double,string}[] result_d = ConfigurationReader("name_confilfpu",["calibrator_current_on"],"0",0.0); double calibcurrent = result_d[0]{0}; //mois_tmcheck("Check that parameter HF_APR_CS_C is set to " + calibcurrent + " mA"); //mois_tmcheck("Check that parameter HF_DPR_CHLOOP_S is set to " + chopper_loop); //WBS checks: not applicable: status unchanged //HRS Checks: not applicable: status unchanged //LOU Checks mois_tmcheck("Check that parameter HL_MODE_S is normal"); mois_tmcheck("Check that parameter HL_Channel_S is Off"); } // Treat each line separately - no optimization of consecutive lines {int,int[]}[] procedure LcuGetMemoryRuns_ops { string section = "P" in ["P","R"]; // select prime or redundant LCU }{ string tab = "LcuMemoryPatch_" + section + ".config"; int total = table_size(tab); {int,int[]}[] result = []; for(int line = 1 .. total) { string look = "" + line; int loc = ilookup(tab,look,"location"); int val = ilookup(tab,look,"value"); int[] value = []; value[0] = val; result[line - 1] = {loc,value}; } return result; } ///////////////////////////////////////////////////////////////// // Auxiliary routine to determine the two loop phase durations and // the OFF resolution for all load-chop modes {double,double,double,double} procedure LoadChopPhaseLengths { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF }{ // limits from noise section // resolution of OFF phase double sw_resolution = GetLoadChopSWResolution(band,lo_freq); sw_resolution = max(effResolution{1},sw_resolution); // Get the drift parameters to compute the drift noise // System Allan variance double[] allanparms = InterpolateSpecAllan(band,lo_freq,oneGHzReference); // rescale to frequency resolution double alpha = allanparms[1]; double binningexp = 1.0 / allanparms[2]; double allan_time_lores = allanparms[0] * pow(1.0 / effResolution{1},binningexp); double allan_time_off = allanparms[0] * pow(1.0 / sw_resolution,binningexp); // Differential Allan variance allanparms = InterpolateSpecLChopAllan(band,lo_freq,oneGHzReference); // rescale to frequency resolution double dalpha = allanparms[1]; binningexp = 1.0 / allanparms[2]; double dallan_time_lores = allanparms[0] * pow(1.0 / effResolution{1},binningexp); // phase lengths double main_phase = 0.3 * dallan_time_lores; double chop_phase = 0.3 * allan_time_lores; double chop_phase_off = 0.3 * allan_time_off; // Constrain by load period int loadper = LoadPeriod(band,lo_freq,effResolution{0}); main_phase = min(main_phase,0.4 * double(loadper)); return {main_phase,chop_phase,chop_phase_off,sw_resolution}; } //////////////////////////////////// // Peakup observing mode // obs HifiEngPeakup { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source double stepsize = 0.0050 in [5.5556E-4,0.13333]; // Distance between subsequent points in the raster line string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz string backend = "WBS" in ["WBS","HRS"]; // backend to use - resolution string polarization = "H" in ["H","V"]; // backend to use - polarization }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = PeakupBackendSettings(backend,polarization,band,lo_freq,1); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; // Call first part of the timing computer {int,int,int,int,int,double,int,int} pre_timing = Peakup_pre_timing(3,3,band,lo_freq,hr1,hr2,wb1,wb2); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,bool,double,double,double,int,int,double,double,int,int,int,double,double} tpar = Peakup_telescope(naifid,onPosition,stepsize,3,3,band,lo_freq,pre_timing); int[] telescopetimes = basic_raster_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19}); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,double,int,int}} post_timing = Peakup_post_timing(pre_timing,telescopetimes,3,3); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = Peakup_telescope(naifid,onPosition,stepsize,3,3,band,lo_freq,post_timing{1}); telescopetimes = basic_raster_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19}); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{3}; int data_time = post_timing{1}{2}; int n_int = post_timing{1}{4}; double eff_resolution = post_timing{1}{5}; int initlength = post_timing{1}{6}; int dangling = post_timing{1}{7}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); /////////////////////////////////////////////////////////////////////// // Call instrument commands Peakup_commanding(band,lo_freq,hr1,hr2,wb1,wb2,data_time,n_int,eff_resolution,stepsize,startobs,telescopetimes,loadlength); // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } } //Check consistency between band and frequency inputs //Should be invoked at the beginning of every mode ! bool procedure Check_Band_vs_Freq_proc_fm { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency }{ bool go_ahead = true; bool go_ahead_a = true; bool go_ahead_b = true; // //Fetch LO limits {double,string}[] result = ConfigurationReader("name_configlo_a",["lo_a_low","lo_a_high"],band,lo_freq); double lo_a_low = result[0]{0}; double lo_a_high = result[1]{0}; result = ConfigurationReader("name_configlo_b",["lo_b_low","lo_b_high"],band,lo_freq); double lo_b_low = result[0]{0}; double lo_b_high = result[1]{0}; // if(band == "0" && (lo_freq < lo_a_low || lo_freq > lo_a_high)) { go_ahead_a = false; } if(band == "1a" && (lo_freq < lo_a_low || lo_freq > lo_a_high)) { go_ahead_a = false; } if(band == "1b" && (lo_freq < lo_b_low || lo_freq > lo_b_high)) { go_ahead_b = false; } if(band == "2a" && (lo_freq < lo_a_low || lo_freq > lo_a_high)) { go_ahead_a = false; } if(band == "2b" && (lo_freq < lo_b_low || lo_freq > lo_b_high)) { go_ahead_b = false; } if(band == "3a" && (lo_freq < lo_a_low || lo_freq > lo_a_high)) { go_ahead_a = false; } if(band == "3b" && (lo_freq < lo_b_low || lo_freq > lo_b_high)) { go_ahead_b = false; } if(band == "4a" && (lo_freq < lo_a_low || lo_freq > lo_a_high)) { go_ahead_a = false; } if(band == "4b" && (lo_freq < lo_b_low || lo_freq > lo_b_high)) { go_ahead_b = false; } if(band == "5a" && (lo_freq < lo_a_low || lo_freq > lo_a_high)) { go_ahead_a = false; } if(band == "5b" && (lo_freq < lo_b_low || lo_freq > lo_b_high)) { go_ahead_b = false; } if(band == "6a" && (lo_freq < lo_a_low || lo_freq > lo_a_high)) { go_ahead_a = false; } if(band == "6b" && (lo_freq < lo_b_low || lo_freq > lo_b_high)) { go_ahead_b = false; } if(band == "7a" && (lo_freq < lo_a_low || lo_freq > lo_a_high)) { go_ahead_a = false; } if(band == "7b" && (lo_freq < lo_b_low || lo_freq > lo_b_high)) { go_ahead_b = false; } if(go_ahead_a == false) { //debug_print("go_ahead is: " + go_ahead); error("LO frequency not within allowed range (" + lo_a_low + " to " + lo_a_high + " GHz) for band " + band); go_ahead = go_ahead_a; } if(go_ahead_b == false) { //debug_print("go_ahead is: " + go_ahead); error("LO frequency not within allowed range (" + lo_b_low + " to " + lo_b_high + " GHz) for band " + band); go_ahead = go_ahead_b; } // //Extra check for warm operations with dummies: only limited amount of frequencies allowed in config files //bool go_ahead_warm = Check_Band_vs_WarmFreq_proc_fm(band,lo_freq); //bool go_ahead_warm = Check_Band_vs_WarmKeyFreq_proc_fm(band,lo_freq); //if (go_ahead_warm == false) { // go_ahead = go_ahead_warm; // } return go_ahead; } //////////////////////////////////////////////////// // Building blocks used in general observations // // They call procedures which should be common between ILT and space // Actual building blocks possible when numbers are // assigned. // // Currently, these blocks contain the data rate computations. ///////////////////////////////////////////////////////////////////////////// // Collection of identical procedures for continuous data read out // calling different building blocks to make data distinguisable // Set observation ID for the current observation - start of every obs block HIFIInitObs HIFI 6000 { }{ // new delay to allow for insertion of BUSCONFIG by MPS // email from Larry, October 19, 2007 // applies only to RMS and SOVT - removed again in HSPOT version // delay(1); // Set ObsId as very first step Hifi_HIFI_Set_OBS_ID($BBID,$OBSID); } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // CUS scripts for FPU. // FPU FT scripts are found under fm_FT_FPU.cus // // DT - 17-Feb-06 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // The modes //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //See fm_testmodes.cus //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // The procedures //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //Procedure checking and, if applicable, converting //prime chopper sent voltage into redundant chopper sent voltage double procedure Check_Chopper_Prime_Redundant { double chopper_angle = 0.0; //prime chopper voltage }{ //Check prime or redundant status {double,string}[] result_d = ConfigurationReader("name_chopper",["prime_or_redundant","p_to_r_coeff_0","p_to_r_coeff_1","p_to_r_coeff_2","prime_endstop_min","prime_endstop_max","red_endstop_min","red_endstop_max"],"0",0.0); double chop = chopper_angle; double prime_endstop_min = result_d[4]{0}; double prime_endstop_max = result_d[5]{0}; double red_endstop_min = result_d[6]{0}; double red_endstop_max = result_d[7]{0}; //Change chopper voltage if necessary if(result_d[0]{1} == "redundant") { chop = result_d[3]{0} * pow(chop,2.0) + result_d[2]{0} * chop + result_d[1]{0}; } //Now check the chopper angle is within the ranges if(result_d[0]{1} == "prime") { if(chop > prime_endstop_max || chop < prime_endstop_min) { error("The chopper voltage (requested is " + chop + " V) in " + result_d[0]{1} + " mode has to be between " + prime_endstop_min + " and " + prime_endstop_max + " V."); } } if(result_d[0]{1} == "redundant") { if(chop > red_endstop_max || chop < red_endstop_min) { error("The chopper voltage (requested is " + chop + " V) in " + result_d[0]{1} + " mode has to be between " + red_endstop_min + " and " + red_endstop_max + " V."); } } return chop; } //HIFI-COP-X-IF-FBk-Dip obs HifiEng_IF_FBk_Dip_COP { string band = "3a" in ["3a","3b","4a","4b","6a","6b","7a","7b"]; // HIFI band int testtime = 3600; //total test time in seconds }{ //General parameters in use string backend = "both"; string[] hrs_mode = ["wb1","wb1"]; double[] result_d = CalibrationReader("name_keyfreq",["keyfreq"],band,0.0); double lo_freq = result_d[0]; //For bands 6 and 7, use wb8 if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { hrs_mode = ["wb8","wb8"]; } // //Avoid high data-rates if(testtime % 3 == 0 && testtime % 4 == 0) { testtime = testtime + 4; } // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(IF_FBk_Dip_COP_proc_ops(band,lo_freq,hrs_mode,testtime,backend)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution IF_FBk_Dip_COP_proc_ops(band,lo_freq,hrs_mode,testtime,backend); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } //HIFI-COP-3-FTP procedure FT_pumped_COP_proc_ops { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band int integ_time = 4; string backend = "both"; string[] hrs_mode = ["wb1","wb1"]; }{ // //Get list of frequencies for given band double[] cresult = CalibrationReader("name_keyfreq",["keyfreq","minfreq","maxfreq","midfreq","badfreq"],band,0.0); // string current_subband = "0"; //Loop on key frequencies per LO band for(int i = 0 .. 4) { // //Wait an extra delay of 1 min for short term stabilization delay(60); Init_MSA_HBB_fm(band,"CLOSE",cresult[i],"ON"); LO_tuning_block_fm(band,cresult[i]); // FT_pumped(band,hrs_mode,integ_time,backend,cresult[i]); // //switch-off LO LCU_switch_off_block_fm(); // FT_unpumped(band,hrs_mode,integ_time,backend); } // } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the observing mode procedure FastSScanDBS_commanding { string band = "4a"; // HIFI band double reffreq = 978300.0; // Reference characteristic LO frequency {double,double} eff_resolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int grouplen = 1; // Number of frequency steps per nodding phase int[][] grouporder = [[0],[0]]; // Sequence to trace frequency points in both phases double[] freqgrid = [978053.7,978301.8,978381.1]; // Table of frequency points bool retuning = false; // need for WBS retuning double[] targetlevels = [1.0,1.0,1.0]; // WBS tuning levels int data_time = 10; // data dump interval int n_int = 20; // number chop cycles to integrate in ICU before transfer int n_cycles = 1; // Number of half OFF-ON-ON-OFF cycles at one frequency int allsteps = 4; // Total number of frequency pointing periods int n_bchop = 1; // Normal number of chop cycles per frequency and pointing int n_long = 1; // Chop cycles per frequency and pointing without retuning int n_loadinterval = 1; // number of nods before a load measurement int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,20,1,21,0]; // Timing of the observation from telescope int shiftlength = 10; // Shift of the loop start relative to the pointing }{ // Auxiliary variables // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time int tnodslew = telescopetimes[2]; // slew dead time between points // First frequency double runningfreq = freqgrid[grouporder[0][0]]; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time / 2); double[] rates = dataparms{1}; int hkduration = HkReadoutTime(band,reffreq,backendreadoutparms,true); int readoutdead = FastChopReadoutDelay(band,reffreq,backendreadoutparms); // recompute load duration for initial load measurement int load_datatime = GetStdLoadReadout(band,reffreq); int loadlength = duration(SScanLoadMeasurement(band,runningfreq,reffreq,true,eff_resolution{0},load_datatime,backendreadoutparms)); loadlength = loadlength + readoutdead; bool retuneload = n_loadinterval > 1; // Tuning levels string[] targetnames = TargetNames(band,reffreq,retuning,targetlevels); string target = targetnames[0]; // All commands with a duration possibly depending on the frequency // are taken at the reference frequency to guarantee synchonization // Declare auxiliary variables to be used in the loops int i_freqcycles = 0; int i_group = 0; int i_phase = 0; int[] choppars = [1,0]; // variables storing the configuration setting bool islong = false; bool isinvalid = true; //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; bool runintostate = false; while(state[0] >= 0) { if(runintostate) { state = next_state_no_check(); } else { state = next_state(); } if(state[0] == 1) { // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // HIFIInitObs(); TuneHIFI(band,runningfreq,hrs1,hrs2,wbs1{0},wbs2{0},target); delay(tinitslew - (time() - startobs) - loadlength + shiftlength - hkduration); // First load measurement HIFISetHK("normal",false); SScanLoadMeasurement(band,runningfreq,reffreq,true,eff_resolution{0},load_datatime,backendreadoutparms); if(shiftlength > 0) { runintostate = true; } else { runintostate = false; } } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 3) { // First nodding position i_phase = (state[2] + 1) % 2; // Reset group counter i_group = 0; runintostate = false; // long integrations not possible in last and first nod cycle if(n_cycles > 1 && state[2] % n_cycles != state[2] % 2) { if(isinvalid || !islong) { choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_long,band,reffreq,backendreadoutparms); islong = true; isinvalid = false; } HIFIFastChopOnIntegration(data_time,n_long,band,reffreq,choppars,rates); } else { if(isinvalid || islong) { choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_bchop,band,reffreq,backendreadoutparms); islong = false; isinvalid = false; } while(i_group < grouplen - 1) { HIFIFastChopOnIntegration(data_time,n_bchop,band,reffreq,choppars,rates); // retune i_group = i_group + 1; runningfreq = freqgrid[grouporder[i_phase][i_group] + i_freqcycles * grouplen]; HIFIChangeFreq(band,runningfreq); } HIFIFastChopOnIntegration(data_time,n_bchop,band,reffreq,choppars,rates); // Now we switch to the next frequency group or repeat the cycle if(state[2] % n_cycles == 0 && i_phase == 1) { // Big tuning step, but not at end of observation if(state[2] < allsteps) { i_freqcycles = i_freqcycles + 1; runningfreq = freqgrid[grouporder[0][0] + i_freqcycles * grouplen]; target = targetnames[i_freqcycles]; HIFIRetuneFreq(band,runningfreq,target); runintostate = true; } } } // Active WBS HK if we have a nod slew without calibration if(state[2] % 2 == 1 && state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } if(state[0] == 7) { // second nod position i_phase = state[2] % 2; // First nodding position // Reset group counter i_group = 0; runintostate = false; // long integrations not possible in last and first nod cycle if(n_cycles > 1 && state[2] % n_cycles != (state[2] % 2 + 1) % 2) { if(isinvalid || !islong) { choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_long,band,reffreq,backendreadoutparms); islong = true; isinvalid = false; } HIFIFastChopOffIntegration(data_time,n_long,band,reffreq,choppars,rates); } else { if(isinvalid || islong) { choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_bchop,band,reffreq,backendreadoutparms); islong = false; isinvalid = false; } while(i_group < grouplen - 1) { HIFIFastChopOffIntegration(data_time,n_bchop,band,reffreq,choppars,rates); // retune i_group = i_group + 1; runningfreq = freqgrid[grouporder[i_phase][i_group] + i_freqcycles * grouplen]; HIFIChangeFreq(band,runningfreq); } HIFIFastChopOffIntegration(data_time,n_bchop,band,reffreq,choppars,rates); // Now we switch to the next frequency group or repeat the cycle if(state[2] % n_cycles == 0 && i_phase == 1) { // Big tuning step, but not at end of observation if(state[2] < allsteps) { i_freqcycles = i_freqcycles + 1; runningfreq = freqgrid[grouporder[0][0] + i_freqcycles * grouplen]; target = targetnames[i_freqcycles]; HIFIRetuneFreq(band,runningfreq,target); runintostate = true; } } } // Active WBS HK if we have a nod slew without calibration if(state[2] % 2 == 0 && state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } if(state[0] == 9) { // Load nod delay(readoutdead); SScanLoadMeasurement(band,runningfreq,reffreq,retuneload,eff_resolution{0},load_datatime,backendreadoutparms); isinvalid = true; runintostate = false; } if(state[0] == 5) { // The instrument stops halftunelength before the telescope // but I have to wait to close the observation HIFICloseObs(); } } } //Set LCU5a back to standby status, procedure procedure LCU5a_standby_proc_fm { string band = "5a"; // HIFI band double lo_freq = 1150.0 in [1127.0,1178.0]; //LO frequency }{ error("This module is obsolete: use LCU_standby_proc_fm instead"); } //LO disable in manual commanding mode HifiManCmd_LO_disable { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! }{ mois_comment("Procedure to disable the LOU S/S"); StartMode_block_ops(); // mois_step("Disable LOU"); LCU_disable_all_bands_block_fm(); // StopMode_block_ops(); // -> to issue last obsd/bbid } //HIFI LO tuning only for M1 and M2 investigation in 7b, block //Target current is read from look-up table block LO_tuning_w_M1M2_block_fm HIFI 3718 { string band = "7b"; // HIFI band double lo_freq = 1890.0; //LO frequency double m1 = -5.0; //M1 multiplier voltage double m2 = -11.0; //M2 multiplier voltage }{ //Clear potential failure mode Set_LO_Nominal_proc_fm(); // //Start_block(); {double,string}[] result = ConfigurationReader("name_confpolar4lotune",[band],band,lo_freq); string mixer_polarization = result[0]{1}; // //Get target mixer current result = ConfigurationReader("name_confilmix",["target_mx_c_h","target_mx_c_v"],band,lo_freq); double target_current = result[0]{0}; if(mixer_polarization == "V") { target_current = result[1]{0}; } if(mixer_polarization == "B") { target_current = 0.5 * (result[1]{0} + result[0]{0}); } // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; name_configlcutune = "name_configlcutune_b"; } // result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = m1; //result[1]{0}; double m2_v = m2; //result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // result = ConfigurationReader(name_configlotune,["step_drain2_v","nsteps","step_time"],band,lo_freq); double step_drain2_v = result[0]{0}; int nsteps = iround(result[1]{0}); double step_time = result[2]{0}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // //Adjust scan cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); double drain2_safe = cresult[0]; // double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); // //For all bands, scan will be done with decreasing drain2 voltages //The best guess is taken from look-up table double tune_range = 0.1; result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lo_freq); //The automatic tuning shall use the min of the nominal best-guess and Vd2max - 100mV double middle_d2 = min(result[0]{0},drain2_bluemax - 0.1); double drain2_v_start = min(middle_d2 * (1.0 + tune_range / 2.0),drain2_bluemax); double drain2_v_end = (1.0 - tune_range / 2.0) / (1.0 + tune_range / 2.0) * middle_d2; //drain2_v_start; step_drain2_v = (drain2_v_end - drain2_v_start) / double(nsteps - 1); // result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); // //Send command if(band == "3b") { Hifi_HIFI_Conf_nom_LCU_ch3b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,macro_checksum); //Send command: specific to M3 in 3b delay(config_lo_delay); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } else { // //General command HIFI_Configure_LCU_proc_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,macro_checksum,config_lo_delay); } // //delay(5); //to settle at this value // //Load vector scan //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Load_vector_safe_1a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "1b") { //Band 1b Hifi_HIFI_Load_vector_safe_1b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2a") { //Band 2a Hifi_HIFI_Load_vector_safe_2a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2b") { //Band 2b Hifi_HIFI_Load_vector_safe_2b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3a") { //Band 3a Hifi_HIFI_Load_vector_safe_3a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3b") { //Band 3b Hifi_HIFI_Load_vector_nom_3b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "4a") { //Band 4a Hifi_HIFI_Load_vector_safe_4a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "4b") { //Band 4b Hifi_HIFI_Load_vector_safe_4b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "5a") { //Band 5a Hifi_HIFI_Load_vector_nom_5a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "5b") { //Band 5b Hifi_HIFI_Load_vector_nom_5b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6a") { //Band 6a Hifi_HIFI_Load_vector_nom_6a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6b") { //Band 6b Hifi_HIFI_Load_vector_nom_6b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7a") { //Band 7a Hifi_HIFI_Load_vector_nom_7a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7b") { //Band 7b Hifi_HIFI_Load_vector_nom_7b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } // delay(1); // //Execute tuning: check which mixer is to be used if(mixer_polarization == "V") { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCV($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCV($BBID,target_current); } } else { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCH($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCH($BBID,target_current); } } // double time_needed = double(nsteps) * step_time; delay(iround(time_needed + 2.0 + 0.5)); //0.5s added for completion of load_vector // //Store settings into available register HIFI_HL_store_tm_only_proc_fm(); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // The blocks //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Diplexer scan, fast, block. // Mixer current as function of diplexer current. Takes 1 seconds per point // IT IS THE OBSOLETE VERSION NOT MAKING USE OF THE DEDICATED OBS TC block Diplexer_scan_fast_fm HIFI 3251 { string band = "3a"; // HIFI band double diplexer_current_min_h = -2.24; //minimum diplexer current H double diplexer_current_max_h = 2.24; //maximum diplexer current H double diplexer_current_min_v = -2.24; //minimum diplexer current V double diplexer_current_max_v = 2.24; //maximum diplexer current V int n_steps = 100; //number of steps }{ Start_block(); int steps = 0; int steps_done = 0; int steps_wanted = n_steps; if(steps_wanted < 1) { steps_wanted = 1; } double diplexer_current_h = 0.0; double diplexer_current_v = 0.0; double stepsize_h = 0.0; double stepsize_v = 0.0; // if(steps_wanted > 1) { stepsize_h = (diplexer_current_max_h - diplexer_current_min_h) / (double(steps_wanted) - 1.0); stepsize_v = (diplexer_current_max_v - diplexer_current_min_v) / (double(steps_wanted) - 1.0); } while(steps_done < steps_wanted) { steps = steps_wanted - steps_done; if(steps > n_steps) { steps = n_steps; } diplexer_current_h = diplexer_current_min_h + double(steps_done) * stepsize_h; Hifi_HIFI_CH1_DPACT_C($BBID,diplexer_current_h); //Sets H diplexer current diplexer_current_v = diplexer_current_min_v + double(steps_done) * stepsize_v; Hifi_HIFI_CV1_DPACT_C($BBID,diplexer_current_v); //Sets V diplexer current // delay(1); steps_done = steps_done + 1; } } // HRS linearity check, loop on individual attenuators, mode // This is the COP version where no WBS is considered // ======================================================= block HRS_linearity_indiv_block_cop HIFI 3960 { string band = "1a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int integ_time = 4; //Total integration time in sec. string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); //Fetch resistive bias {double,string}[] result = ConfigurationReader("name_confilfpu",["bias_high_resistive_h","bias_high_resistive_v","bias_medium_resistive_h","bias_medium_resistive_v"],band,0.0); // double bias_high_h = result[0]{0}; double bias_high_v = result[1]{0}; double bias_medium_h = result[2]{0}; double bias_medium_v = result[3]{0}; int repeats = 32; double hrsH_attenuators_value = 15.5; double hrsV_attenuators_value = 15.5; //Test will be done in WB mode for both polar string hrsh_blocks_configuration = "corr_wide"; string hrsv_blocks_configuration = "corr_wide"; // Configure spectroscopy Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); // // Configure blocks //================= //H-polar Hifi_HIFI_Config_HRS_H_blocks($BBID,hrsh_blocks_configuration,hrsh_blocks_configuration,hrsh_blocks_configuration,hrsh_blocks_configuration,hrsh_blocks_configuration,hrsh_blocks_configuration,hrsh_blocks_configuration,hrsh_blocks_configuration); // //delay(1); //V-polar Hifi_HIFI_Config_HRS_V_blocks($BBID,hrsv_blocks_configuration,hrsv_blocks_configuration,hrsv_blocks_configuration,hrsv_blocks_configuration,hrsv_blocks_configuration,hrsv_blocks_configuration,hrsv_blocks_configuration,hrsv_blocks_configuration); // delay(1); // Fetch internal LO settings //=========================== //H-polar string hrs_filename_h = "name_confighrs_" + hrs_mode[0]; result = ConfigurationReader(hrs_filename_h,["hrh_switch","hrh_up_ol1","hrh_up_ol2","hrh_up_ol3","hrh_up_ol4","hrh_down_ol5","hrh_down_ol6","hrh_down_ol7"],band,0.0); double[] hrsH_LO = [result[1]{0},result[2]{0},result[3]{0},result[4]{0},result[5]{0},result[6]{0},result[7]{0}]; string hrs_polarization_h = result[0]{1}; //V-polar string hrs_filename_v = "name_confighrs_" + hrs_mode[1]; result = ConfigurationReader(hrs_filename_v,["hrv_switch","hrv_up_ol1","hrv_up_ol2","hrv_up_ol3","hrv_up_ol4","hrv_down_ol5","hrv_down_ol6","hrv_down_ol7"],band,0.0); double[] hrsV_LO = [result[1]{0},result[2]{0},result[3]{0},result[4]{0},result[5]{0},result[6]{0},result[7]{0}]; string hrs_polarization_v = result[0]{1}; // //Convert IF frequencies into A and M parameters //Truncate wb or hr keyword: string[] output_hrs_mode = GetHrsMode_proc_fm(hrs_mode); string hrs_mode_h = output_hrs_mode[0]; string hrs_mode_v = output_hrs_mode[1]; // int[] a_m_parameter = ComputeA_M_parameters([hrs_mode_h,hrs_mode_v],hrsH_LO[0],hrsH_LO[1],hrsH_LO[2],hrsH_LO[3],hrsH_LO[4],hrsH_LO[5],hrsH_LO[6],hrsV_LO[0],hrsV_LO[1],hrsV_LO[2],hrsV_LO[3],hrsV_LO[4],hrsV_LO[5],hrsV_LO[6]); // //H-polar int hrsH_LO1_M = a_m_parameter[1]; int hrsH_LO1_A = a_m_parameter[0]; int hrsH_LO2_M = a_m_parameter[3]; int hrsH_LO2_A = a_m_parameter[2]; int hrsH_LO3_M = a_m_parameter[5]; int hrsH_LO3_A = a_m_parameter[4]; int hrsH_LO4_M = a_m_parameter[7]; int hrsH_LO4_A = a_m_parameter[6]; int hrsH_LO5_M = a_m_parameter[9]; int hrsH_LO5_A = a_m_parameter[8]; int hrsH_LO6_M = a_m_parameter[11]; int hrsH_LO6_A = a_m_parameter[10]; int hrsH_LO7_M = a_m_parameter[12]; //V-polar int hrsV_LO1_M = a_m_parameter[14]; int hrsV_LO1_A = a_m_parameter[13]; int hrsV_LO2_M = a_m_parameter[16]; int hrsV_LO2_A = a_m_parameter[15]; int hrsV_LO3_M = a_m_parameter[18]; int hrsV_LO3_A = a_m_parameter[17]; int hrsV_LO4_M = a_m_parameter[20]; int hrsV_LO4_A = a_m_parameter[19]; int hrsV_LO5_M = a_m_parameter[22]; int hrsV_LO5_A = a_m_parameter[21]; int hrsV_LO6_M = a_m_parameter[24]; int hrsV_LO6_A = a_m_parameter[23]; int hrsV_LO7_M = a_m_parameter[25]; // /////////////////////////////////////// // // Loops on the different configurations of the HRS attenuators //=============================================== //Magnets shall be set to 0 since high biases will be used Set_Magnet_current_proc_fm(0.0,0.0); // for(int i = 0 .. repeats - 1) { // Configure attenuators and LO //============================= Hifi_HIFI_Config_HRS_H_att_lo($BBID,hrs_polarization_h,hrsH_attenuators_value,hrsH_attenuators_value,hrsH_attenuators_value,hrsH_attenuators_value,hrsH_attenuators_value,hrsH_attenuators_value,hrsH_attenuators_value,hrsH_attenuators_value,hrsH_LO1_M,hrsH_LO1_A,hrsH_LO2_M,hrsH_LO2_A,hrsH_LO3_M,hrsH_LO3_A,hrsH_LO4_M,hrsH_LO4_A,hrsH_LO5_M,hrsH_LO5_A,hrsH_LO6_M,hrsH_LO6_A,hrsH_LO7_M); // //delay(2); Hifi_HIFI_Config_HRS_V_att_lo($BBID,hrs_polarization_v,hrsH_attenuators_value,hrsV_attenuators_value,hrsV_attenuators_value,hrsV_attenuators_value,hrsV_attenuators_value,hrsV_attenuators_value,hrsV_attenuators_value,hrsV_attenuators_value,hrsV_LO1_M,hrsV_LO1_A,hrsV_LO2_M,hrsV_LO2_A,hrsV_LO3_M,hrsV_LO3_A,hrsV_LO4_M,hrsV_LO4_A,hrsV_LO5_M,hrsV_LO5_A,hrsV_LO6_M,hrsV_LO6_A,hrsV_LO7_M); // delay(1); // //Set the shot noise to high resistive bias Mixerbias(bias_high_h,bias_high_v); // Take spectrum //============== HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // // //Set the shot noise to medium resistive bias Mixerbias(bias_medium_h,bias_medium_v); // Take spectrum //============== HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // // Change the value of the 8 attenuators //====================================== hrsH_attenuators_value = hrsH_attenuators_value - 0.5; hrsV_attenuators_value = hrsV_attenuators_value - 0.5; } // } // Compute the integration time required on the thermal loads int procedure LoadIntegrationTime { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency double deltanu = 1.0; // minimum effective resolution of the calibrated data }{ // get load temperatures {double,double} loadtemp = LoadTemperatures(band,lo_freq); double t_hot = loadtemp{0}; double t_cold = loadtemp{1}; double t_sys = InterpolateTsys(band,lo_freq); // compare to load period int loadperiod = LoadPeriod(band,lo_freq,deltanu); // exception handling for zero frequency resolutions if(deltanu < 0.01) { int intload = loadperiod / 8; } else { // estimator equation guaranteeing only 1% error from load calibration double tload = 0.01 / deltanu * ((t_hot + t_sys) * (t_hot + t_sys) + (t_cold + t_sys) * (t_cold + t_sys)) / ((t_hot - t_cold) * (t_hot - t_cold)); intload = iceil(tload); // never exceed half of the load period, even for FSwitch intload = imin(intload,loadperiod / 8); } return intload; } ///////////////////////////////////////////////////////////////// // Procedure to compute total dead times for the mode // {double,double,double,double,double} procedure SScanDoubleChop_deadtimes { string chopmode = "chop" in ["chop","lchop","fs"]; // chop mode string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int grouplen = 1; // Number of frequency steps per nodding phase int data_time = 4; // data dump interval on ON int data_time_off = 4; // data dump interval on OFF int n_chop_on = 3; // number of chop cycles in one integration on ON int n_chop_off = 3; // number of chop cycles in one integration on OFF int n_long_on = 3; // number of chop cycles for long integration on ON int n_long_off = 3; // number of chop cycles for long integration on OFF int n_cycles = 1; // Number of half OFF-ON-ON-OFF cycles at one frequency double avnumchop_on = 1.0; // Average number of ON chop cycles per frequency double avnumchop_off = 1.0; // Average number of OFF chop cycles per frequency double tscan = 10.0; // Dead time from telescope }{ ////////////////////////////////////////////////////////////////////// // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Compute parameters for the instrument timing in normal phases // Four different cases involved {double,double} tinst = GetInstDeadSlowChop(data_time,2 * n_chop_on,chopmode,band,lo_freq,backendreadoutparms); // dead time double tdeadint_on = double(data_time * 2 * n_chop_on) - tinst{0}; // subtract dead times in switches // keep dead times between A-A and B-B in total dead time tdeadint_on = tdeadint_on - double(n_chop_on) * tinst{1}; // treat integration times of other frequencies as dead time double tdeadother = double(data_time * 2 * n_chop_on); // Store double tswitch_on = tinst{1}; // Integration time double tphaseint_on = tinst{0}; // Correcton in case of cycles with longer integrations if(n_cycles > 1) { tinst = GetInstDeadSlowChop(data_time,2 * n_long_on,chopmode,band,lo_freq,backendreadoutparms); // dead time double tdeadlong = double(data_time * 2 * n_long_on) - tinst{0}; // subtract dead times in switches tdeadlong = tdeadlong - double(n_long_on) * tinst{1}; // weigh int numlong_on = 2 * (n_cycles / 2); double wlong = double(numlong_on) / double(grouplen * n_cycles); double wshort = double(n_cycles * grouplen - numlong_on) / double(grouplen * n_cycles); tdeadint_on = wlong * tdeadlong + wshort * tdeadint_on; tphaseint_on = (wlong * tinst{0} + wshort * tphaseint_on) / (2.0 * avnumchop_on); tdeadother = wshort * tdeadother + double(data_time * 2 * n_long_on) * wlong; } else { tphaseint_on = tphaseint_on / (2.0 * avnumchop_on); } // OFF phase tinst = GetInstDeadSlowChop(data_time_off,2 * n_chop_off,chopmode,band,lo_freq,backendreadoutparms); // dead time double tdeadint_off = double(data_time_off * 2 * n_chop_off) - tinst{0}; // subtract dead times in switches // keep dead times between A-A and B-B in total dead time tdeadint_off = tdeadint_off - double(n_chop_off) * tinst{1}; // Store double tswitch_off = tinst{1}; // Integration time double tphaseint_off = tinst{0}; // Correcton in case of cycles with longer integrations if(n_cycles > 1) { tinst = GetInstDeadSlowChop(data_time_off,2 * n_long_off,chopmode,band,lo_freq,backendreadoutparms); // dead time tdeadlong = double(data_time_off * 2 * n_long_off) - tinst{0}; // subtract dead times in switches tdeadlong = tdeadlong - double(n_long_off) * tinst{1}; // weigh int numlong_off = 2 * ((n_cycles - 1) / 2); wlong = double(numlong_off) / double(n_cycles); wshort = double(n_cycles - numlong_off) / double(n_cycles); tdeadint_off = wlong * tdeadlong + wshort * tdeadint_off; tphaseint_off = (wlong * tinst{0} + wshort * tphaseint_off) / (2.0 * avnumchop_off); } else { tphaseint_off = tphaseint_off / (2.0 * avnumchop_off); } // Total dead time per cycle double tdead = tscan - double(grouplen * 2 * data_time) * avnumchop_on - double(2 * data_time_off) * avnumchop_off; double tdead_tot = tdead + tdeadint_on + tdeadint_off; // Add integration times of other frequencies as dead time tdead_tot = tdead_tot + double(grouplen - 1) * tdeadother; // Return total dead time and the dead times in the two chops return {tdead_tot,tphaseint_on,tphaseint_off,tswitch_on,tswitch_off}; } ///////////////////////////////////////////////////////////////// // Procedure to derive the backend settings for spectral scans {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} procedure SScanBackendSettings { string band = "4a"; // HIFI band int redundancy = 4; // Frequency scan redundancy bool wbs1_used = true; // whether WBS1 is used bool wbs2_used = true; // whether WBS2 is used int data_time = 4; // data dump interval }{ // Standard configuration of the backends // Get appropriate settings for selected HIFI band double[] x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,0.0); int[][] stdWbsWindows = [[iround(x[0]),iround(x[1])],[iround(x[2]),iround(x[3])],[iround(x[4]),iround(x[5])],[iround(x[6]),iround(x[7])]]; {bool,int[][]} wbs1 = {wbs1_used,stdWbsWindows}; {bool,int[][]} wbs2 = {wbs2_used,stdWbsWindows}; // WBS parameters ={used, channel windows} // Check whether we can use the HRS in parallel // Get fixed HRS parameters {{bool,int,double[],bool[]},{bool,int,double[],bool[]}} hrsparms = GetSpectralScanHRS(redundancy,band); {bool,int,double[],bool[]} hrs1 = hrsparms{0}; {bool,int,double[],bool[]} hrs2 = hrsparms{1}; string[] resolstring = ["high-resolution","nominal-resolution","low-resolution","wide-resolution"]; // Create a composite readout structure {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Compute chunk size given by the data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); // Test whether HRS can be used if(dataparms{0} > data_time) { // No HRS possible // HRS parameters when not used hrs1 = {false,1,[-110.0,110.0,0.0,0.0],[false,false,false,false]}; hrs2 = {false,1,[-110.0,110.0,0.0,0.0],[false,false,false,false]}; message("No parallel HRS usage due to short chop phase length.
"); // Create a composite readout structure backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Check chunk size given by the data rates CheckDataTaking(backendreadoutparms,data_time); } else { message("HRS running parallel in " + resolstring[hrs1{1}] + " mode.
"); } return {hrs1,hrs2,wbs1,wbs2}; } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the observing mode procedure SScanFSwitchNoRef_commanding { string band = "4a"; // HIFI band double reffreq = 978300.0; // Reference characteristic LO frequency double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} eff_resolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int grouplen = 1; // Number of frequency steps per nodding phase int[][] grouporder = [[0],[0]]; // Sequence to trace frequency points in both phases double[] freqgrid = [978053.7,978301.8,978381.1]; // Table of frequency points bool retuning = false; // need for WBS retuning double[] targetlevels = [1.0,1.0,1.0]; // WBS tuning levels int data_time = 4; // chunk size int n_per_on = 1; // number of half load-sky-sky-load cycles on ON int n_load_on = 0; // additional load measurements in ON pointing phase int groupnumber = 4; // Total number of frequency groups int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,0]; // Timing of observation from telescope int loadlength = 50; // Load duration }{ // Auxiliary variables // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] rates = dataparms{1}; int hkduration = HkReadoutTime(band,reffreq,backendreadoutparms,false); int readoutdead = SlowChopReadoutDelay(band,reffreq,backendreadoutparms); // First frequency double runningfreq = freqgrid[grouporder[0][0]]; string[] targetnames = TargetNames(band,reffreq,retuning,targetlevels); string target = targetnames[0]; // All commands with a duration possibly depending on the frequency // are taken at the reference frequency to guarantee synchonization //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 1) { // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // HIFIInitObs(); TuneHIFIFsw(band,runningfreq,freq_throw,hrs1,hrs2,wbs1{0},wbs2{0},target); delay(tinitslew - (time() - startobs) - loadlength - hkduration); // First load measurement HIFISetHK("normal",false); SScanDoubleLoadMeasurement(band,runningfreq,reffreq,freq_throw,true,eff_resolution{0},data_time,backendreadoutparms); } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 3) { for(int i_freq = 0 .. groupnumber - 1) { // First frequency // Loop over load cycles for(int i1 = 1 .. n_load_on) { // Actual measurement HIFIConfigureFSwitchIntegration(data_time,n_per_on,band,reffreq,backendreadoutparms); HIFIFSwitchOnIntegration(data_time,n_per_on,band,reffreq,rates); // Perform load calibration delay(readoutdead); SScanDoubleLoadMeasurement(band,runningfreq,reffreq,freq_throw,false,eff_resolution{0},data_time,backendreadoutparms); } if(n_load_on == 0) { // This is the only measurement executed with nload=0 HIFIConfigureFSwitchIntegration(data_time,n_per_on,band,reffreq,backendreadoutparms); HIFIFSwitchOnIntegration(data_time,n_per_on,band,reffreq,rates); } // Other frequencies // Reset group counter for(int i_group = 1 .. grouplen - 1) { // retune runningfreq = freqgrid[grouporder[0][i_group] + i_freq * grouplen]; HIFIChangeFreqFsw(band,runningfreq,freq_throw); if(n_load_on > 0) { // First load SScanDoubleLoadMeasurement(band,runningfreq,reffreq,freq_throw,false,eff_resolution{0},data_time,backendreadoutparms); } else { // This is the only measurement executed with nload=0 HIFIConfigureFSwitchIntegration(data_time,n_per_on,band,reffreq,backendreadoutparms); HIFIFSwitchOnIntegration(data_time,n_per_on,band,reffreq,rates); } // Loop over load cycles for(int i2 = 1 .. n_load_on) { // Actual measurement HIFIConfigureFSwitchIntegration(data_time,n_per_on,band,reffreq,backendreadoutparms); HIFIFSwitchOnIntegration(data_time,n_per_on,band,reffreq,rates); // Perform load calibration delay(readoutdead); SScanDoubleLoadMeasurement(band,runningfreq,reffreq,freq_throw,false,eff_resolution{0},data_time,backendreadoutparms); } } // Now we switch to the next frequency group or repeat the cycle // Big tuning step, but not at end of observation if(i_freq < groupnumber - 1) { runningfreq = freqgrid[grouporder[0][0] + (i_freq + 1) * grouplen]; target = targetnames[i_freq + 1]; HIFIRetuneFsw(band,runningfreq,freq_throw,target); // first load or main load for n_load=0 SScanDoubleLoadMeasurement(band,runningfreq,reffreq,freq_throw,false,eff_resolution{0},data_time,backendreadoutparms); } } } if(state[0] == 5) { if(n_load_on == 0) { delay(readoutdead); } HIFICloseObs(); } } } {int,double,double,double,double,double} obs HifiPointModeFSwitchNoRef { string modeName = "fs"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rates int n_cycles = 2 in [1,3600]; // number of half nu1-nu2-nu2-nu1 cycles on ON int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode OpenMessages("HIFI Single Point - Frequency Switch noRef",{data_time,0,0,0,0,0,0,0,n_cycles,load_interval}); // Two cases: fine pointing or position switch // Call first part of the timing computer {int,int,int,int,int,int,bool,int,int} pre_timing_f = FSwitchNoRef_pre_timing(band,lo_freq,freq_throw,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_cycles,load_interval,docommands); // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,double,double,int} tpar_f = Fine_telescope(naifid,onPosition,band,lo_freq,pre_timing_f); // Dummy call to spacecraft command int[] telescopetimes = basic_fine_pointing(false,tpar_f{0},tpar_f{1},tpar_f{2},tpar_f{3},tpar_f{4},tpar_f{5},tpar_f{6},tpar_f{7},tpar_f{8},tpar_f{9}); // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,bool,int,int},double,double} post_timing_f = SingleChopNoRef_post_timing(pre_timing_f,telescopetimes); // Now the actual observation starts // Prepare telescope command tpar_f = Fine_telescope(naifid,onPosition,band,lo_freq,post_timing_f{1}); // Call telescope command telescopetimes = basic_fine_pointing(true,tpar_f{0},tpar_f{1},tpar_f{2},tpar_f{3},tpar_f{4},tpar_f{5},tpar_f{6},tpar_f{7},tpar_f{8},tpar_f{9}); // Consistency check int totaltime = post_timing_f{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following ////////////////////////////////////////////////////////////////////// // standard parameters for fine pointing int loadlength = post_timing_f{1}{2}; int n_per_on = post_timing_f{1}{4}; int n_load_on = post_timing_f{1}{5}; bool end_load_on = post_timing_f{1}{6}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands ////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { FSwitchNoRef_commanding(band,lo_freq,freq_throw,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_per_on,n_load_on,end_load_on,startobs,telescopetimes,loadlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double} tact = SingleChop_deadtimes("fs",band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_per_on); double tscan = 2.0 * (tact{1} + tact{2}); double tdead = 2.0 * tact{2}; // // Call noise computer {double,double,double,double,double} noisevalues = FSwitchNoRef_noisecomputer(band,lo_freq,effResolution,oneGHzReference,n_per_on * (n_load_on + 1),tscan,tdead); // Evaluate performance SingleChopNoRef_performance(band,lo_freq,effResolution,noisevalues,timeTaken,n_per_on * (n_load_on + 1),true,tscan,tdead); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // Vector scan calibration for a given LO band // Ues domains of frequencies to be scanned for each LO sub-band procedure Vecscan_calibration_proc_fm_COP { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band }{ // LCU_switchon_proc_fm(band); //Wait an extra delay of 1 min for short term stabilization delay(60); // //Get the list of frequencies to be used for the scan string tab = "config_vecscan.config"; double bandnb = GetBandCode(band); double lofreqlow = dlookup(tab,"" + iceil(bandnb),"lofreqlow"); double lofreqhigh = dlookup(tab,"" + iceil(bandnb),"lofreqhigh"); double lofreqstep = dlookup(tab,"" + iceil(bandnb),"lofreqstep"); // double current_LO = lofreqlow; bool endreached = false; //Loop on key frequencies per LO band while(current_LO <= lofreqhigh && endreached == false) { //Configure FPU at that frequency //SPR-2463: look at HBB Init_MSA_HBB_fm(band,"CLOSE",current_LO,"ON"); // //Perform vector scan within BLUE limits at that frequency Vector_scan_BLUE_LIMIT_block_fm(band,current_LO); //LCU_CLEAR_ERROR_block_fm(); // //sanity check //double[] result_dip = Get_Diplexer_setting(band,current_LO); //message("LO freq " + current_LO + " " + result_dip[0] + " " + result_dip[1]); //Check last LO freq done if(current_LO == lofreqhigh && endreached == false) { endreached = true; } //Increase LO freq: truncate if step too high current_LO = current_LO + lofreqstep; if(current_LO > lofreqhigh && endreached == false) { current_LO = lofreqhigh; } } // } ///////////////////////////////////////////////////////////////// // Procedure to compute detailed timing for a // Spectral Scan Frequency-Switch observing mode // {{int,int,int,int,int,int,bool,int,int},{int,double,double[],int[][],bool,double[],int,bool}} procedure SScanFSwitchNoRef_pre_timing { string band = "4a"; // HIFI band double lo_freq_low = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz int redundancy = 4; // Frequency scan redundancy double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} eff_resolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_chop_on = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles per frequency and pointing int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Create composite readout structure for backends {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Get frequency grid characteristic parameters {int,double,double[],int[][],int,bool} fqparms = MakeFreqGrid(band,lo_freq_low,lo_freq_up,redundancy,freq_throw,n_freq_point); int groupnumber = fqparms{0}; double reffreq = fqparms{1}; double[] freqgrid = fqparms{2}; int[][] grouporder = fqparms{3}; // Process tuning level grid double[][] levelgrid = GetSScanLevelGrid(band,wbs1,wbs2,freqgrid,fqparms{0},grouporder); {bool,double[]} targets = TargetLevels(band,reffreq,levelgrid); bool retuning = targets{0}; double[] targetgrid = targets{1}; string reftarget = ""; if(retuning) { reftarget = "sscan_normal"; } {int,double,double[],int[][],bool,double[],int,bool} spectralparms = {fqparms{0},reffreq,freqgrid,grouporder,retuning,targetgrid,fqparms{4},fqparms{5}}; ////////////////////////////////////////////////////////////////////// // Get timing within the normal frequency-switch observations int readoutdead = SlowChopReadoutDelay(band,reffreq,backendreadoutparms); int jitterdead = GetMaxTimeJitter(band,reffreq); // Integration time per frequency and pointing int on_inttime = 2 * n_chop_on * data_time; // Tuning delays int bigtunestep = duration(HIFIRetuneFsw(band,reffreq,freq_throw,reftarget)); // Correct for variation within the band int tunediff = ComputeLOTimeDifference(band,lo_freq_low,lo_freq_up,reffreq); bigtunestep = bigtunestep + 2 * tunediff; // A step within a group could be faster than a large step if(n_freq_point > 1) { int smallstep = duration(HIFIChangeFreqFsw(band,reffreq,freq_throw)); } else { smallstep = bigtunestep; } int grouptime = n_freq_point * on_inttime + (n_freq_point - 1) * smallstep; // Duration of initial set up // Staying at the same frequency makes no sense here. // First frequency point double runningfreq = freqgrid[grouporder[0][0]]; // Compute load integration time int loadlength = duration(SScanDoubleLoadMeasurement(band,runningfreq,reffreq,freq_throw,true,eff_resolution{0},data_time,backendreadoutparms)); loadlength = loadlength + readoutdead; // determine exact duration only in case of full commanding if(docommands) { int initlength = duration(HIFIInitObs()); initlength = initlength + duration(TuneHIFIFsw(band,runningfreq,freq_throw,hrs1,hrs2,wbs1{0},wbs2{0},"sscan_normal")); // Add time for HK readout int hkduration = HkReadoutTime(band,reffreq,backendreadoutparms,false); initlength = initlength + hkduration; } else { initlength = GetRoughInitLength(band,runningfreq,true); } initlength = initlength + loadlength; int initloadlength = loadlength; // recompute load length during slews - no retuning loadlength = duration(SScanDoubleLoadMeasurement(band,reffreq,reffreq,freq_throw,false,eff_resolution{0},data_time,backendreadoutparms)); loadlength = loadlength + readoutdead; // Compare load interval with duration of the observation int load_spacing = CheckedLoadSpacing(load_interval - loadlength,8); if(load_spacing < grouptime && n_freq_point > 1) { SError("Load period too short for frequency group size."); } // Here we bracket each cycle by loads, this leads to a grace period int n_load_on = on_inttime / load_spacing; // In the following the definition of n_load_on is higher by 1 relative to // that used in normal frequency switch! // This determines the order of the loops if(n_load_on == 0) { int n_per_on = n_chop_on; bool end_load_on = false; } else { // grace condition if(double(on_inttime) > 1.2 * double(load_spacing)) { n_load_on = n_load_on + 1; } n_per_on = n_chop_on / n_load_on; if(n_per_on < 1) { SError("FS phase length on source too long relative to load period."); } end_load_on = true; on_inttime = 2 * n_per_on * n_load_on * data_time; // This cannot happen for n_freq_point > 1 grouptime = on_inttime + n_load_on * loadlength; } int on_pointing = groupnumber * (grouptime + bigtunestep + loadlength) - bigtunestep - loadlength + jitterdead; // dangling time given by readout dead time int dangling = readoutdead; // Return all the times needed for telescope call and post_timing processing return {{on_inttime,on_pointing,initloadlength,load_spacing,n_per_on,n_load_on,end_load_on,initlength,dangling},spectralparms}; } //////////////////////////////////////// // Standing wave on the Imix // no-spectra version procedure Standing_wave_nospectra_fm_COP { string band = "1a"; // HIFI band double[] lo_freq_input = [500.0,500.15,0.02]; //Start, end and step lo_freq for the LO scan }{ // Initial LO tuning at centre frequency of scan // double lo_freq_ref = (lo_freq_input[0] + lo_freq_input[1]) / 2.0; LO_tuning_block_fm(band,lo_freq_ref); double lo_freq = lo_freq_input[0]; //Loop on LO frequencies. It is assumed that the LO is tuned at the middle frequency of the scan // int nbstep = 0; //For freq above 1THz rounding makes miss the last step. double margin = 0.1 / 1.0E9; //0.1Hz while(lo_freq <= lo_freq_input[1] + margin) { //Set synthesizer to new LO freq. LCU_config_nominal_noretune_block_fm(band,lo_freq,lo_freq_ref); // //Increase lo_freq lo_freq = lo_freq + lo_freq_input[2]; nbstep = nbstep + 1; } message("LO freq: " + lo_freq_ref + "Nb of steps: " + nbstep); } // Spectrometer configuration for slow chop, low level procedure int[] procedure Configure_Spectrometer_slow_chop_proc_fm { string band = "1a"; // HIFI band int integ_time = 8; //Total integration time in sec. for the two phases ! string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4,wb5 string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //First derive backend setting codes as expected by VO's routine //Build up backend parameter tupple: {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = BackendSettings(band,0.0,hrs_mode,backend); // Readout parameters for HRS1,HRS2, WBS1,WBS2 //Compute data_time and n_switch use the wrapper int[] res = ConfigSlowChop(integ_time,"chop",band,0.0,backendreadoutparms); int data_time = res[0]; int n_switch = res[1]; // Now call the spectroscopy setup: it is common to ILT and AOT CUS. // The deadtimes output is not used at ILT level. {double,double} dtimes = ConfigSpectroscopySlowChop_IST(data_time,n_switch,"chop",band,0.0,backendreadoutparms,true); // return res; } ////////////////////////////////////////////////////////////////////// // Compatibility procedure to provide the same API as used in // the previous versions // // Returns the actual integration time and the dead time per phase {{double,double,double},{int,int}} procedure ConfigSpectroscopyFastChop_IST { /* Integration time */ double data_chop = 0.5 in [0.1,2.0]; // Length of a single chop phase int n_int = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_data = 2; // Integration time counter /* Parameters determining the delays - used in calibration reader */ string band = "1a"; // HIFI band double lo_freq = 522000.0; // LO frequency /* Backend settings */ {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // HRS1/2 {used,resolution,subbands used}, WBS1/2 {used,channel windows} }{ // Translate data_chop into new parameter data_time (approximate) // Get auxiliary quantities {double,string}[] result = ConfigurationReader("name_delays",["add_wbs","add_jitter","wbs_readout","wbs_init"],band,lo_freq); int add_wbs = iround(result[0]{0}); int add_jitter = iround(result[1]{0}); int wbs_readout = iround(result[2]{0}); int wbs_init = iround(result[3]{0}); int tdead_data = 2 * (wbs_readout + add_jitter) + add_wbs - add_jitter; int totaltime = (iceil(1000.0 * data_chop) * 2 * n_int + tdead_data) * n_data + wbs_init; totaltime = iceil(double(totaltime) / 1000.0); int data_time = (totaltime + n_data - 1) / n_data; // Check CheckFastChopFrequency(band,lo_freq,data_time,n_int,n_data); // Get timing parameters bool wbs_used = backendreadoutparms{2}{0} || backendreadoutparms{3}{0}; {int,int,int,int,int,int,int,int,int,int,int,int,int} timing = FastConfigureSpectroscopyParams_IST(data_time,n_int,n_data,band,lo_freq,wbs_used); int n_wbs_start = timing{0}; int r_hrs = timing{1}; int n_wbs_integr = timing{2}; int n_hrs_integr = timing{3}; int del_hrs = timing{4}; int del_wbs = timing{5}; int t_acc_wbs = timing{6}; int t_acc_hrs = timing{7}; int n_wbs1 = timing{8}; int n_hrs_trans = timing{9}; int tdead_chop = timing{10}; tdead_data = timing{11}; int tint_act = timing{12}; {int,int,int,int,int[],int[],string} backendconfigure = ConfigSpectroscopyBackends(data_time,backendreadoutparms); int wbs_rshift = backendconfigure{0}; int hrs_rshift = backendconfigure{1}; int hrsh_sel = backendconfigure{2}; int hrsv_sel = backendconfigure{3}; int[] wbsh_par = backendconfigure{4}; int[] wbsv_par = backendconfigure{5}; string packing = backendconfigure{6}; // Now call the command Hifi_HIFI_config_spectroscopy($BBID,n_wbs_start,r_hrs,n_wbs_integr,n_hrs_integr,del_hrs,del_wbs,t_acc_wbs,t_acc_hrs,wbsh_par[0],wbsh_par[1],wbsh_par[2],wbsh_par[3],wbsh_par[4],wbsh_par[5],wbsh_par[6],wbsh_par[7],wbsv_par[0],wbsv_par[1],wbsv_par[2],wbsv_par[3],wbsv_par[4],wbsv_par[5],wbsv_par[6],wbsv_par[7],hrs_rshift,wbs_rshift,hrsh_sel,hrsv_sel,packing); // // Return dead times and comand parameters return {{double(tint_act) / 1000.0,double(tdead_chop) / 1000.0,double(data_time * n_data)},{n_wbs1,n_hrs_trans}}; } //HIFI-COP-3-Stab-1 //This one should be use for preparation via XHSpot //It assumes one obsid per band/stab_category/freq obs HifiEng_Stab_COP { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string stab = "sys" in ["sys","lsw","int","dbs","fsw","stab"]; //category of stability measurement int freq_index = 1; //Frequency index to be applied int throw_index = 1; //FSW throw index to be applied }{ //General parameters in use string[] hrs_mode = ["wb1","wb1"]; int integ_time = 4; double chop_phase = 1.0; string shutter = "open"; //For bands 6 and 7, use wb8 if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { hrs_mode = ["wb8","wb8"]; } // // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Stab_COP_proc_ops(band,stab,freq_index,throw_index,hrs_mode,integ_time,chop_phase,shutter)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Stab_COP_proc_ops(band,stab,freq_index,throw_index,hrs_mode,integ_time,chop_phase,shutter); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } {string,double,double}[] procedure HifiPointModeLoadChopSequencerInit { string modeName = "load"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rates int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 2 in [1,900]; // number of half load-sky-sky-load cycles on ON int n_switch_off = 2 in [1,900]; // number of half load-sky-sky-load cycles on OFF int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF calibration cycles int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode // limit on data rate {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // limits from noise section {double,double,double,double} phaselengths = LoadChopPhaseLengths(band,lo_freq,effResolution,oneGHzReference); // Compute derived quantities int data_time_guess = imin(imax(iceil(phaselengths{1}),datalimit),20); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } int n_switch_on_guess = imax(iceil(phaselengths{0} / (2.0 * double(data_time_guess))),1); int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } // OFF phase int data_time_off_guess = imin(imax(iceil(phaselengths{2}),datalimit),20); int data_time_off_range = datalimit - data_time_off_guess; if(data_time_off_range == 0) { data_time_off_range = 1; } int n_switch_off_guess = imax(iceil(double(data_time_guess * n_switch_on_guess) / (double(data_time_off_guess) * sqrt(phaselengths{3} / effResolution{1}))),1); int n_switch_off_range = 1 - n_switch_off_guess; if(n_switch_off_range == 0) { n_switch_off_range = 1; } // Add pointing requirements condition: >=10s {int,int} new_data_time = MatchMinPointing(data_time_guess,data_time_range,2 * n_switch_on_guess); data_time_guess = new_data_time{0}; data_time_range = new_data_time{1}; new_data_time = MatchMinPointing(data_time_off_guess,data_time_off_range,2 * n_switch_off_guess); data_time_off_guess = new_data_time{0}; data_time_off_range = new_data_time{1}; // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"data_time_off",double(data_time_off_guess),double(data_time_off_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)},{"n_switch_off",double(n_switch_off_guess),double(n_switch_off_range)}]; return retvalues; } // Procedure to get timing in a spectroscopy measurement {double,double} procedure GetInstDeadSlowChop { /* Integration time */ int data_time = 4; // Integration time between two data readouts int n_int = 2; // Integration time counter string chopmode = "chop" in ["chop","lchop","fs","hot-cold","tp"]; // Chop mode determining the modulation dead time /* Parameters determining the delays - used in calibration reader */ string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency /* Backend settings */ {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // HRS1/2 {used,resolution,subbands used}, WBS1/2 {used,channel windows} }{ // Get timing parameters {int,int,int,int,int,int,int,int,int,int} timing = ConfigureSpectroscopyParams(data_time,n_int,chopmode,band,lo_freq,backendreadoutparms); int tdead = timing{8}; int tint = timing{9}; // Return dead time per full integration double tintall = double(tint) / 1000.0; double tdeadphase = double(tdead) / 1000.0; return {tintall,tdeadphase}; } // Combine radiometric and drift noise from an OTF observation // Normalized to mapping without overhead // {double,double} procedure OtfNoiseValues { double n = 10.0; // number of points in one scan double[] parameters = [0.02,0.4,0.05,0.667,2.5]; // Parameters: integration time, delay, slew from OFF relative to Allan time, ratio of t_off time to sqrt(n)*t_on, drift exponent }{ // Assign parameters double npoints = double(ifloor(n)); double x = parameters[0]; double d = parameters[1]; double doff = parameters[2]; double qval = parameters[3]; double alpha = parameters[4]; if(npoints > 0.0) { // OFF integration time double xr = qval * sqrt(npoints) * x; // Total delay double dtot = (npoints - 1.0) * x + d; // Try two points at the edge and the center of a scan to get the extremes double[] pp = [0.0,0.5]; double[] yn = [0.0,0.5]; double[] yd = [0.0,0.5]; double[] yy = [0.0,0.5]; double p = 0.0; for(int ip = 0 .. 1) { p = pp[ip]; // Delay length before measured point double d1 = doff + double(ifloor(p * npoints)) * x + p * (d - 2.0 * doff); // Remaining delay double d2 = dtot - d1; // add radiometric and drift noise yn[ip] = OtfRadioNoise(x,xr,d1,d2); yd[ip] = OtfDrift(x,xr,d1,d2,alpha); yy[ip] = yn[ip] + yd[ip]; } // Normalization - relative to mapping without overhead double norm = (x + xr + dtot) / npoints; // Get worst case if(yy[0] > yy[1]) { double ynm = yn[0] * norm; double ydm = yd[0] * norm; } else { ynm = yn[1] * norm; ydm = yd[1] * norm; } // Artificially forbid OTF scans much longer than the Allan time double driftadd = max(dtot + x - 10.0,0.0) * 0.1; ydm = ydm + driftadd * ynm; } else { // forbid negative point numbers ynm = 1.0E11; ydm = 1.0E11; } return {ynm,ydm}; } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the observing mode procedure SScanLoadChopNoRef_commanding { string band = "4a"; // HIFI band double reffreq = 978300.0; // Reference characteristic LO frequency {double,double} eff_resolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int grouplen = 1; // Number of frequency steps per nodding phase int[][] grouporder = [[0],[0]]; // Sequence to trace frequency points in both phases double[] freqgrid = [978053.7,978301.8,978381.1]; // Table of frequency points bool retuning = false; // need for WBS retuning double[] targetlevels = [1.0,1.0,1.0]; // WBS tuning levels int data_time = 4; // chunk size int n_per_on = 1; // number of half load-sky-sky-load cycles on ON int n_load_on = 0; // additional load measurements in ON pointing phase int groupnumber = 4; // Total number of frequency groups int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,0]; // Timing of observation from telescope int loadlength = 50; // Load duration }{ // Auxiliary variables // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] rates = dataparms{1}; int hkduration = HkReadoutTime(band,reffreq,backendreadoutparms,false); int readoutdead = SlowChopReadoutDelay(band,reffreq,backendreadoutparms); bool retuneload = n_load_on > 0; // First frequency double runningfreq = freqgrid[grouporder[0][0]]; string[] targetnames = TargetNames(band,reffreq,retuning,targetlevels); string target = targetnames[0]; // All commands with a duration possibly depending on the frequency // are taken at the reference frequency to guarantee synchonization //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 1) { // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // HIFIInitObs(); TuneHIFI(band,runningfreq,hrs1,hrs2,wbs1{0},wbs2{0},target); delay(tinitslew - (time() - startobs) - loadlength - hkduration); // First load measurement HIFISetHK("normal",false); SScanLoadMeasurement(band,runningfreq,reffreq,true,eff_resolution{0},data_time,backendreadoutparms); } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 3) { for(int i_freq = 0 .. groupnumber - 1) { // First frequency // Loop over load cycles for(int i1 = 1 .. n_load_on) { // Actual measurement HIFIConfigureLoadChopIntegration(data_time,n_per_on,band,reffreq,backendreadoutparms); HIFILoadChopOnIntegration(data_time,n_per_on,band,reffreq,rates); // Perform load calibration delay(readoutdead); SScanLoadMeasurement(band,runningfreq,reffreq,true,eff_resolution{0},data_time,backendreadoutparms); } if(n_load_on == 0) { // This is the only measurement executed with nload=0 HIFIConfigureLoadChopIntegration(data_time,n_per_on,band,reffreq,backendreadoutparms); HIFILoadChopOnIntegration(data_time,n_per_on,band,reffreq,rates); } // Other frequencies // Reset group counter for(int i_group = 1 .. grouplen - 1) { // retune runningfreq = freqgrid[grouporder[0][i_group] + i_freq * grouplen]; HIFIChangeFreq(band,runningfreq); if(retuneload) { // First load SScanLoadMeasurement(band,runningfreq,reffreq,true,eff_resolution{0},data_time,backendreadoutparms); } else { // This is the only measurement executed with nload=0 HIFIConfigureLoadChopIntegration(data_time,n_per_on,band,reffreq,backendreadoutparms); HIFILoadChopOnIntegration(data_time,n_per_on,band,reffreq,rates); } // Loop over load cycles for(int i2 = 1 .. n_load_on) { // Actual measurement HIFIConfigureLoadChopIntegration(data_time,n_per_on,band,reffreq,backendreadoutparms); HIFILoadChopOnIntegration(data_time,n_per_on,band,reffreq,rates); // Perform load calibration delay(readoutdead); SScanLoadMeasurement(band,runningfreq,reffreq,true,eff_resolution{0},data_time,backendreadoutparms); } } // Now we switch to the next frequency group or repeat the cycle // Big tuning step, but not at end of observation if(i_freq < groupnumber - 1) { runningfreq = freqgrid[grouporder[0][0] + (i_freq + 1) * grouplen]; target = targetnames[i_freq + 1]; HIFIRetuneFreq(band,runningfreq,target); // first load or main load for n_load=0 SScanLoadMeasurement(band,runningfreq,reffreq,retuneload,eff_resolution{0},data_time,backendreadoutparms); } } } if(state[0] == 5) { if(n_load_on == 0) { delay(readoutdead); } HIFICloseObs(); } } } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // The procedures //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Mode initialisation procedure StartMode { }{ BroadcastOBSID(); //Get applicable HK rate {double,string}[] result_d = ConfigurationReader("name_delays",["hk_rate"],"0",0.0); double hk_rate = result_d[0]{0}; HKrate(hk_rate); } // BLOCK : Functional Test No 1 (HRS Master Reset) block HRS_functional_test_No_1_block_fm HIFI 3611 { }{ //Start_block(); // //Use new command implemented in SCR-859 Hifi_HIFI_HRS_functional_test($BBID,1,"BOTH"); delay(5); // } // Total noise from an asymmetric double difference observation // This is still to be scaled by a factor 1.0/(B_fluct*T_obs) double procedure DoubleDifferenceNoise { double x = 0.1; // value for integration time relative to Allan time double[] parameters = [1.0,1.0,0.8,0.8,0.05,0.3,2.5,5.0,2.5]; // Parameters: ratio of integration times, ratio of effective resolutions, delay in phase1, in phase 2, between phases relative to Allan time, drift exponents }{ // Assign parameters double tpa = parameters[2]; // total length of A pointing phase double tpb = parameters[3]; // total length of B pointing phase double d = parameters[5]; // position switch dead time relative to differential Allan {double,double} noisevalues = DoubleDifferenceNoiseValues(x,parameters); // Add and normalize with respect to total observing time double y = (noisevalues{0} + noisevalues{1}) * (tpa + tpb + d); return y; } // Perform load chop integration at OFF position ON-OFF-OFF-ON... block HIFILoadChopOffIntegration HIFI 6036 { int data_time = 4; // Integration time between two data readouts int n_cycle = 1; // chop cycle number string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double[] rates = [120.0,1.0,2.0]; // Data rates between and during integrations }{ HIFI_Spectr_slow_chop_proc_aot(data_time,n_cycle,band,lo_freq,["chop_cold","chop_M3"],rates); } // Give sequence of frequency steps in a spectral scan mode within one group double[][] procedure SpreadHRS { string band = "4a"; // HIFI band int[] resolution = [1,1]; // Frequency resolution double[] offset = [0.0,0.0]; // Center offsets }{ // Define using the values for resolution=0 double[][] settings = [[offset[0],0.0,0.0,0.0],[offset[1],0.0,0.0,0.0]]; // set up individually for the two HRS's for(int i = 0 .. 1) { int res = resolution[i]; double off = offset[i]; // create settings if(res == 0) { double[] subset = [off,0.0,0.0,0.0]; } else { // Set subband width double singlewidth = GetBackendBandwidth(band,0.0,res); // Arrange with some overlap double hrsgranularity = 20.0; double doff = 0.5 * (singlewidth - hrsgranularity); if(res == 1) { subset = [off - doff,off + doff,0.0,0.0]; } else { subset = [off - 3.0 * doff,off - doff,off + doff,off + 3.0 * doff]; } } settings[i] = subset; } return settings; } // Change of HK rate - setting of corresponding data rates block HIFISetHK HIFI 6001 { string speed = "normal" in ["fast","normal","slow"]; // Select HK rate bool active = false; // Whether to actively query the spectrometers }{ // Get parameters {string,int,double,double,double,double} hkparms = PeriodicHKParms(speed); non_ess_hk_data_rate(hkparms{3} / 1024.0); ess_hk_data_rate(hkparms{5} / 1024.0); // Subsystems to be queried string[] pattern = QueryHKPattern(active); Hifi_HIFI_Housekeeping_on(hkparms{0},pattern[0],pattern[1],pattern[2],pattern[3],pattern[4],pattern[5]); delay(1); } // Initialisation of FPU, block with both MSA in use // It is for cold context ! // It can control the diplexer filter block Init_MSA_DipFilter_fm HIFI 3954 { string band = "1a"; // HIFI band string chop_loop = "CLOSE"; double lo_freq = 522.0; //LO frequency string hbb_heater = "ON" in ["ON","OFF"]; //hot source on/off int diplex_h_ctrl_mode = 227; //Diplexer filter }{ Start_block(); //Get parameters {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,lo_freq); int band_nb = iround(result_d[0]{0}); double diplex_H = 0.0; double diplex_V = 0.0; //int diplex_h_ctrl_mode = 0; int diplex_v_ctrl_mode = diplex_h_ctrl_mode; // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,lo_freq); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // string chop_sine_s = "ON"; // string chop_loop = "CLOSE" ; result_d = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,lo_freq); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // double calibcurrent = result_d[7]{0}; if(hbb_heater == "ON") { result_d = ConfigurationReader("name_confilfpu",["calibrator_current_on"],band,lo_freq); calibcurrent = result_d[0]{0}; } // //Get biases result_d = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); double bias_H = result_d[0]{0}; double bias_V = result_d[1]{0}; //For bands 6 and 7, first set to 4mV if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { result_d = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,lo_freq); bias_H = result_d[0]{0}; bias_V = result_d[1]{0}; } // //Get magnets: not applicable to bands 6 and 7 double magnetcurrent_H = 0.0; double magnetcurrent_V = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,lo_freq); magnetcurrent_H = result_d[0]{0}; magnetcurrent_V = result_d[1]{0}; } //Diplexer is interpolated from a table for Bands 3, 4, 6L and 6H if(band_nb <= 2 || band_nb == 5) { diplex_H = 0.0; //For bands 1, 2 and 5 diplex_V = 0.0; diplex_h_ctrl_mode = 0; diplex_v_ctrl_mode = 0; } else { //Get diplexer currents result_d = ConfigurationReader("name_confilfpu",["diplex_h_ctrl_mode","diplex_v_ctrl_mode"],band,lo_freq); //diplex_h_ctrl_mode = iround(result_d[0]{0}); //diplex_v_ctrl_mode = iround(result_d[1]{0}); double[] result_dip = Get_Diplexer_setting(band,lo_freq); diplex_H = result_dip[0]; diplex_V = result_dip[1]; } // result_d = ConfigurationReader("name_chopper",["chop_startup_cold"],band,0.0); if(chop_loop == "OPEN") { result_d = ConfigurationReader("name_chopper",["chop_startup_warm"],band,0.0); } double chopper = result_d[0]{0}; //For this configuration we won't convert prime chopper voltage into redundant voltage //Just checking we are in range. //chopper = Check_Chopper_Prime_Redundant(chopper); chopper = Check_Chopper_Range(chopper); // //Switch on upconverter, assuming chopper and mixers are also ON Hifi_HIFI_Configure_FCU_Power($BBID,"ON","ON","ON","ON","ON"); // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result_d = ConfigurationReader("name_delays",["config_fpu_delay"],band,lo_freq); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // //In case of band 6 or 7, bias have been set to 4mV. Now set to nominal if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { {double,string}[] result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); Mixerbias(result[0]{0},result[1]{0}); } // //Magnet are so far at maximum value. Now set to nominal if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); Hifi_HIFI_CH1_MX_MG_C($BBID,result_d[0]{0}); Hifi_HIFI_CV1_MX_MG_C($BBID,result_d[1]{0}); delay(1); } // //Hifi_HIFI_non_periodic_hk_FCU (); } //Filler procedure to generate TPF for Spurious tests //We use a TC that calls only the BBID, pass the currents //frequency param, and Vd2 //Its value will corrected after IPF generation procedure COP_Spur_TPF_maker { string band = "3b" in ["3b","7b"]; // HIFI band int testblock = 1 in [0,3]; //Test block for 3b }{ int bbid = 1; string name_confindex = "name_confindex_b"; //We will loop on tabulated frequencies //For each we will tune LO power and do diplexer scans //for 5-8 M1 settings //1. Get the list of frequencies to be used for the scan string tab1 = "config_M1calib_" + band + "_" + testblock + ".config"; if(testblock == 0) { tab1 = "config_M1calib_" + band + "_COP.config"; string tab2 = "config_M2calib_" + band + "_COP.config"; } int total = table_size(tab1); double[] freq = []; double[] m1_1 = []; double[] m1_2 = []; double[] m1_3 = []; double[] m1_4 = []; double[] m1_5 = []; double[] m1_6 = []; double[] m1_7 = []; double[] m1_8 = []; double[] m2 = []; double[] m3 = []; for(int j = 1 .. total) { if(band == "7b") { freq[j] = dlookup(tab1,"" + j,"frequency"); m1_1[j] = dlookup(tab1,"" + j,"m1_1"); m1_2[j] = dlookup(tab1,"" + j,"m1_2"); m1_3[j] = dlookup(tab1,"" + j,"m1_3"); m1_4[j] = dlookup(tab1,"" + j,"m1_4"); m1_5[j] = dlookup(tab1,"" + j,"m1_5"); //Get frequency parameters {double,string}[] result = ConfigurationReader(name_confindex,["freq_nx"],band,freq[j]); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,freq[j]); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get max Vd2 double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,freq[j]); //Convert into raw: int vd2 = convert_to_raw("hifi_HL_Drain2_7B_V",drain2_bluemax); int mm1_1 = convert_to_raw("hifi_HL_M1_7B_V",m1_1[j]); int mm1_2 = convert_to_raw("hifi_HL_M1_7B_V",m1_2[j]); int mm1_3 = convert_to_raw("hifi_HL_M1_7B_V",m1_3[j]); int mm1_4 = convert_to_raw("hifi_HL_M1_7B_V",m1_4[j]); int mm1_5 = convert_to_raw("hifi_HL_M1_7B_V",m1_5[j]); Hifi_HIFI_WBS_Zero(mm1_1); Hifi_HIFI_WBS_Zero(mm1_1); Hifi_HIFI_WBS_Zero(mm1_1); Hifi_HIFI_WBS_Zero(mm1_2); Hifi_HIFI_WBS_Zero(mm1_2); Hifi_HIFI_WBS_Zero(mm1_2); Hifi_HIFI_WBS_Zero(mm1_3); Hifi_HIFI_WBS_Zero(mm1_3); Hifi_HIFI_WBS_Zero(mm1_3); Hifi_HIFI_WBS_Zero(mm1_4); Hifi_HIFI_WBS_Zero(mm1_4); Hifi_HIFI_WBS_Zero(mm1_4); Hifi_HIFI_WBS_Zero(mm1_5); Hifi_HIFI_WBS_Zero(mm1_5); Hifi_HIFI_WBS_Zero(mm1_5); } if(band == "3b") { freq[j] = dlookup(tab1,"" + j,"frequency"); m1_1[j] = dlookup(tab1,"" + j,"m1_1"); m1_2[j] = dlookup(tab1,"" + j,"m1_2"); m1_3[j] = dlookup(tab1,"" + j,"m1_3"); m1_4[j] = dlookup(tab1,"" + j,"m1_4"); m1_5[j] = dlookup(tab1,"" + j,"m1_5"); m1_6[j] = dlookup(tab1,"" + j,"m1_6"); m1_7[j] = dlookup(tab1,"" + j,"m1_7"); //m1_8[j] = dlookup(tab1,"" + j,"m1_8"); if(testblock > 0) { m2[j] = dlookup(tab1,"" + j,"m2_" + testblock); m3[j] = dlookup(tab1,"" + j,"m3_" + testblock); } else { m2[j] = dlookup(tab2,"" + j,"m2_1"); m3[j] = dlookup(tab2,"" + j,"m3_1"); } //Get frequency parameters result = ConfigurationReader(name_confindex,["freq_nx"],band,freq[j]); freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset resu = ComputeLSU_A_M_R(band,freq[j]); lsu_main = resu[0]; lsu_offset = resu[1]; //Get gates and drain1 double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v"],band,freq[j]); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; //Get curlims result = ConfigurationReader("name_configlo_b",["curlim1_v","curlim2_v"],band,freq[j]); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; //Get max Vd2 drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,freq[j]); //Convert into raw: int g1 = convert_to_raw("hifi_HL_Gate1_3B_V",gate1_v); int g2 = convert_to_raw("hifi_HL_Gate2_3B_V",gate2_v); int vd1 = convert_to_raw("hifi_HL_Drain1_3B_V",drain1_v); //convert_to_raw does not work for params defined through TextualCalibrationCurves //The convertion is: if(curlim1 == "1.5") { int curl1 = 0; } if(curlim1 == "1.4") { curl1 = 2; } if(curlim1 == "1.3") { curl1 = 1; } if(curlim1 == "1.22") { curl1 = 3; } // if(curlim2 == "1.5") { int curl2 = 0; } if(curlim2 == "1.4") { curl2 = 2; } if(curlim2 == "1.3") { curl2 = 1; } if(curlim2 == "1.22") { curl2 = 3; } vd2 = convert_to_raw("hifi_HL_Drain2_3B_V",drain2_bluemax); mm1_1 = convert_to_raw("hifi_HL_M1_3B_V",m1_1[j]); mm1_2 = convert_to_raw("hifi_HL_M1_3B_V",m1_2[j]); mm1_3 = convert_to_raw("hifi_HL_M1_3B_V",m1_3[j]); mm1_4 = convert_to_raw("hifi_HL_M1_3B_V",m1_4[j]); mm1_5 = convert_to_raw("hifi_HL_M1_3B_V",m1_5[j]); int mm1_6 = convert_to_raw("hifi_HL_M1_3B_V",m1_6[j]); int mm1_7 = convert_to_raw("hifi_HL_M1_3B_V",m1_7[j]); //int mm1_8 = convert_to_raw("hifi_HL_M1_3B_V",m1_8[j]); int mm2 = convert_to_raw("hifi_HL_M2_3B_V",m2[j]); int mm3 = convert_to_raw("hifi_HL_M3_3B_V",m3[j]); int mm2_generic = mm2; if(testblock == 2) { mm2_generic = mm2; } if(testblock == 3) { mm2_generic = mm2; } //Hifi_HIFI_WBS_Zero(freq_nx); //Hifi_HIFI_WBS_Zero(lsu_main); //Hifi_HIFI_WBS_Zero(lsu_offset); Hifi_HIFI_WBS_Zero(mm1_1); Hifi_HIFI_WBS_Zero(mm2_generic); Hifi_HIFI_WBS_Zero(mm3); Hifi_HIFI_WBS_Zero(g1); Hifi_HIFI_WBS_Zero(g2); Hifi_HIFI_WBS_Zero(vd1); Hifi_HIFI_WBS_Zero(curl1); Hifi_HIFI_WBS_Zero(vd2); Hifi_HIFI_WBS_Zero(curl2); //Hifi_HIFI_WBS_Zero(freq_nx); //Hifi_HIFI_WBS_Zero(lsu_main); //Hifi_HIFI_WBS_Zero(lsu_offset); Hifi_HIFI_WBS_Zero(mm1_2); Hifi_HIFI_WBS_Zero(mm2_generic); Hifi_HIFI_WBS_Zero(mm3); Hifi_HIFI_WBS_Zero(g1); Hifi_HIFI_WBS_Zero(g2); Hifi_HIFI_WBS_Zero(vd1); Hifi_HIFI_WBS_Zero(curl1); Hifi_HIFI_WBS_Zero(vd2); Hifi_HIFI_WBS_Zero(curl2); //Hifi_HIFI_WBS_Zero(freq_nx); //Hifi_HIFI_WBS_Zero(lsu_main); //Hifi_HIFI_WBS_Zero(lsu_offset); Hifi_HIFI_WBS_Zero(mm1_3); Hifi_HIFI_WBS_Zero(mm2_generic); Hifi_HIFI_WBS_Zero(mm3); Hifi_HIFI_WBS_Zero(g1); Hifi_HIFI_WBS_Zero(g2); Hifi_HIFI_WBS_Zero(vd1); Hifi_HIFI_WBS_Zero(curl1); Hifi_HIFI_WBS_Zero(vd2); Hifi_HIFI_WBS_Zero(curl2); //Hifi_HIFI_WBS_Zero(freq_nx); //Hifi_HIFI_WBS_Zero(lsu_main); //Hifi_HIFI_WBS_Zero(lsu_offset); Hifi_HIFI_WBS_Zero(mm1_4); Hifi_HIFI_WBS_Zero(mm2_generic); Hifi_HIFI_WBS_Zero(mm3); Hifi_HIFI_WBS_Zero(g1); Hifi_HIFI_WBS_Zero(g2); Hifi_HIFI_WBS_Zero(vd1); Hifi_HIFI_WBS_Zero(curl1); Hifi_HIFI_WBS_Zero(vd2); Hifi_HIFI_WBS_Zero(curl2); //Hifi_HIFI_WBS_Zero(freq_nx); //Hifi_HIFI_WBS_Zero(lsu_main); //Hifi_HIFI_WBS_Zero(lsu_offset); Hifi_HIFI_WBS_Zero(mm1_5); Hifi_HIFI_WBS_Zero(mm2_generic); Hifi_HIFI_WBS_Zero(mm3); Hifi_HIFI_WBS_Zero(g1); Hifi_HIFI_WBS_Zero(g2); Hifi_HIFI_WBS_Zero(vd1); Hifi_HIFI_WBS_Zero(curl1); Hifi_HIFI_WBS_Zero(vd2); Hifi_HIFI_WBS_Zero(curl2); //Hifi_HIFI_WBS_Zero(freq_nx); //Hifi_HIFI_WBS_Zero(lsu_main); //Hifi_HIFI_WBS_Zero(lsu_offset); Hifi_HIFI_WBS_Zero(mm1_6); Hifi_HIFI_WBS_Zero(mm2_generic); Hifi_HIFI_WBS_Zero(mm3); Hifi_HIFI_WBS_Zero(g1); Hifi_HIFI_WBS_Zero(g2); Hifi_HIFI_WBS_Zero(vd1); Hifi_HIFI_WBS_Zero(curl1); Hifi_HIFI_WBS_Zero(vd2); Hifi_HIFI_WBS_Zero(curl2); //Hifi_HIFI_WBS_Zero(freq_nx); //Hifi_HIFI_WBS_Zero(lsu_main); //Hifi_HIFI_WBS_Zero(lsu_offset); Hifi_HIFI_WBS_Zero(mm1_7); Hifi_HIFI_WBS_Zero(mm2_generic); Hifi_HIFI_WBS_Zero(mm3); Hifi_HIFI_WBS_Zero(g1); Hifi_HIFI_WBS_Zero(g2); Hifi_HIFI_WBS_Zero(vd1); Hifi_HIFI_WBS_Zero(curl1); Hifi_HIFI_WBS_Zero(vd2); Hifi_HIFI_WBS_Zero(curl2); } } // } // Chop between internal and external cold loads, block // We take 1 spectrum per phase. block Stability_intcold_extcold_fm HIFI 3424 { string band = "1a"; // HIFI band int n = 100; //The number of integration pairs int integ_time = 4; //Total (co-added) integration time of ONE SINGLE phase in sec. string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string chopmode = "slowchop" in ["slowchop","fastchop"]; //Whether to use slowchop or fastchop double chop_phase = 1.0 in [0.2,2.0]; // Chop phase length }{ Start_block(); //Shutter_rotate_proc_fm("closed"); //Get chopper settings {double,string}[] result = ConfigurationReader("name_confilfpu",["chop_M3","chop_cold"],band,0.0); double chop_middle = result[0]{0}; double chop_cold = result[1]{0}; // //We implement a special slow-chop spectroscopy between //internal cold and external cold if(chopmode == "slowchop") { Slow_chop_spectro_for_Stability_proc_fm(band,n,integ_time * 2,backend,hrs_mode,chop_middle,chop_cold); } else { Fast_chop_spectro_for_Stability_proc_fm(band,n,integ_time * 2,backend,hrs_mode,chop_middle,chop_cold,chop_phase); } } {string,double,double}[] procedure HifiMappingModeFSwitchOTFNoRefSequencerInit { string modeName = "fs-raster"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // chunk size given by the data rates and optimum speed int n_switch_on = 1 in [1,1800]; // Supersamplingfactor int n_cycles = 1 in [1,1200]; // Number of map coverages int load_interval = 1800 in [10,7200]; // load period defines number of lines between two loads }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode // inherit from load-chop mode {string,double,double}[] retvalues = HifiMappingProcLoadChopOTFNoRefSequencerInit(naifid,ra,dec,lineDistance,nlines,stepsize,npoints,band,lo_freq,effResolution,oneGHzReference,hrs1,hrs2,wbs1,wbs2,data_time,n_switch_on,n_cycles,load_interval,docommands); return retvalues; } ///////////////////////////////////////// block FCU_config_mxdp_block_fm HIFI 3990 { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 522.0; //LO frequency }{ {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band"],band,lo_freq); int band_nb = iround(result_d[0]{0}); //Get biases result_d = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); double bias_H = result_d[0]{0}; double bias_V = result_d[1]{0}; //For bands 6 and 7, first set to 4mV if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { result_d = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,lo_freq); bias_H = result_d[0]{0}; bias_V = result_d[1]{0}; } // //Get diplexer currents if(band_nb <= 2 || band_nb == 5) { double diplex_H = 0.0; //For bands 1, 2 and 5 double diplex_V = 0.0; } else { double[] result_dip = Get_Diplexer_setting(band,lo_freq); diplex_H = result_dip[0]; diplex_V = result_dip[1]; } // Hifi_HIFI_Config_mxbias_dpact($BBID,bias_H,bias_V,diplex_H,diplex_V); delay(1); // //In case of band 6 or 7, bias have been set to 4mV. Now set to nominal if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { result_d = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); Mixerbias(result_d[0]{0},result_d[1]{0}); } // } //Band5 //LO parameter scan with HotCold measurement //for Band 5a procedure LCU5a_power_scan_with_Tsys { string band = "5a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4 double lo_freq = 1150.0 in [1127.0,1178.0]; //LO frequency double param_min = 1.0; //Min. of scanned parameter double param_max = 2.0; //Max. of scanned parameter double step_size = 0.1; //Step size string param_name = "D2"; //Code of scanned parameter: M1,M2,M3,G1,G2,D1,D2. int integ_time = 4; //Total integration time in sec. }{ error("This module is obsolete: use LCU_power_scan_with_Tsys instead"); } //PDU switch off of a S/S, block block PDU_switch_off_block_ops HIFI 7659 { string subsystem = "ICU_Prime" in ["ICU_Prime","ICU_Red","LO_Prime","LO_Red","WBS_H","WBS_V","HRS_H","HRS_V"]; }{ if(subsystem != "ICU_Prime" && subsystem != "ICU_Red") { StartBlock_ops(); //This has no delay } ////HifiIltEgse_PDU_switch_off($BBID,subsystem); //The TEI command: WILL BE DONE BY SPACON mois_spacon("Please power OFF Sub-System " + subsystem); //delay(1); } ////////////////////////////////////////////////////////////////// // HRS complete configuration with maximum attenuation, block // Both polarizations are treated block HRS_config_max_att_block_fm HIFI 3634 { string band = "1a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code }{ //Start_block(); // Fetch HRS configuration parameters //=================================== //H-polar string hrs_filename_h = "name_confighrs_" + hrs_mode[0]; {double,string}[] result = ConfigurationReader(hrs_filename_h,["hrh_switch","hrh_1u_att","hrh_1l_att","hrh_2u_att","hrh_2l_att","hrh_3u_att","hrh_3l_att","hrh_4u_att","hrh_4l_att","hrh_up_ol1","hrh_up_ol2","hrh_up_ol3","hrh_up_ol4","hrh_down_ol5","hrh_down_ol6","hrh_down_ol7"],band,0.0); string hrs_polarization_h = result[0]{1}; double[] hrsH_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; //V-polar string hrs_filename_v = "name_confighrs_" + hrs_mode[1]; result = ConfigurationReader(hrs_filename_v,["hrv_switch","hrv_1u_att","hrv_1l_att","hrv_2u_att","hrv_2l_att","hrv_3u_att","hrv_3l_att","hrv_4u_att","hrv_4l_att","hrv_up_ol1","hrv_up_ol2","hrv_up_ol3","hrv_up_ol4","hrv_down_ol5","hrv_down_ol6","hrv_down_ol7"],band,0.0); string hrs_polarization_v = result[0]{1}; double[] hrsV_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; // result = ConfigurationReader("name_delays",["hrs_config_delay"],band,0.0); int hrs_config_delay = iround(result[0]{0}); //Convert IF frequencies into A and M parameters //Truncate wb or hr keyword: string[] output_hrs_mode = GetHrsMode_proc_fm(hrs_mode); string hrs_mode_h = output_hrs_mode[0]; string hrs_mode_v = output_hrs_mode[1]; // int[] a_m_parameter = ComputeA_M_parameters([hrs_mode_h,hrs_mode_v],hrsH_LO[0],hrsH_LO[1],hrsH_LO[2],hrsH_LO[3],hrsH_LO[4],hrsH_LO[5],hrsH_LO[6],hrsV_LO[0],hrsV_LO[1],hrsV_LO[2],hrsV_LO[3],hrsV_LO[4],hrsV_LO[5],hrsV_LO[6]); //H-polar int hrh_up_ol1_m = a_m_parameter[1]; int hrh_up_ol1_a = a_m_parameter[0]; int hrh_up_ol2_m = a_m_parameter[3]; int hrh_up_ol2_a = a_m_parameter[2]; int hrh_up_ol3_m = a_m_parameter[5]; int hrh_up_ol3_a = a_m_parameter[4]; int hrh_up_ol4_m = a_m_parameter[7]; int hrh_up_ol4_a = a_m_parameter[6]; int hrh_down_ol5_m = a_m_parameter[9]; int hrh_down_ol5_a = a_m_parameter[8]; int hrh_down_ol6_m = a_m_parameter[11]; int hrh_down_ol6_a = a_m_parameter[10]; int hrh_down_ol7_m = a_m_parameter[12]; //V-polar int hrv_up_ol1_m = a_m_parameter[14]; int hrv_up_ol1_a = a_m_parameter[13]; int hrv_up_ol2_m = a_m_parameter[16]; int hrv_up_ol2_a = a_m_parameter[15]; int hrv_up_ol3_m = a_m_parameter[18]; int hrv_up_ol3_a = a_m_parameter[17]; int hrv_up_ol4_m = a_m_parameter[20]; int hrv_up_ol4_a = a_m_parameter[19]; int hrv_down_ol5_m = a_m_parameter[22]; int hrv_down_ol5_a = a_m_parameter[21]; int hrv_down_ol6_m = a_m_parameter[24]; int hrv_down_ol6_a = a_m_parameter[23]; int hrv_down_ol7_m = a_m_parameter[25]; //Attenuators are fixed //H-polar double hrh_1u_att = 15.5; double hrh_1l_att = 15.5; double hrh_2u_att = 15.5; double hrh_2l_att = 15.5; double hrh_3u_att = 15.5; double hrh_3l_att = 15.5; double hrh_4u_att = 15.5; double hrh_4l_att = 15.5; //V-polar double hrv_1u_att = 15.5; double hrv_1l_att = 15.5; double hrv_2u_att = 15.5; double hrv_2l_att = 15.5; double hrv_3u_att = 15.5; double hrv_3l_att = 15.5; double hrv_4u_att = 15.5; double hrv_4l_att = 15.5; //Configure HRS-H Hifi_HIFI_Config_HRS_H_att_lo($BBID,hrs_polarization_h,hrh_1u_att,hrh_1l_att,hrh_2u_att,hrh_2l_att,hrh_3u_att,hrh_3l_att,hrh_4u_att,hrh_4l_att,hrh_up_ol1_m,hrh_up_ol1_a,hrh_up_ol2_m,hrh_up_ol2_a,hrh_up_ol3_m,hrh_up_ol3_a,hrh_up_ol4_m,hrh_up_ol4_a,hrh_down_ol5_m,hrh_down_ol5_a,hrh_down_ol6_m,hrh_down_ol6_a,hrh_down_ol7_m); //delay(hrs_config_delay); // //Configure HRS-V Hifi_HIFI_Config_HRS_V_att_lo($BBID,hrs_polarization_v,hrv_1u_att,hrv_1l_att,hrv_2u_att,hrv_2l_att,hrv_3u_att,hrv_3l_att,hrv_4u_att,hrv_4l_att,hrv_up_ol1_m,hrv_up_ol1_a,hrv_up_ol2_m,hrv_up_ol2_a,hrv_up_ol3_m,hrv_up_ol3_a,hrv_up_ol4_m,hrv_up_ol4_a,hrv_down_ol5_m,hrv_down_ol5_a,hrv_down_ol6_m,hrv_down_ol6_a,hrv_down_ol7_m); delay(hrs_config_delay); // //Now Configure blocks HRS_config_resol_fm(band,hrs_mode); } {string,double,double}[] procedure HifiMappingModeFastDBSCrossSequencerInit { string modeName = "cross"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 10 in [4,80]; // data dump interval int n_int_on = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_switch_on = 1 in [1,1800]; // number of data transfer cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode // inherit from dbs-raster mode {string,double,double}[] retvalues = HifiMappingProcFastDBSRasterSequencerInit(naifid,ra,dec,{0.0,double(npoints / 2) * stepsize},2,stepsize,npoints,band,lo_freq,effResolution,continuumDetection,oneGHzReference,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_switch_on,n_pointsperscan,n_cycles,load_interval,docommands); return retvalues; } // OBS SFT, mode mode HifiManCmd_OBS_SFT { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! }{ Mode_status_check_intermediate(); StartMode_block_ops(); mois_comment("Start On-Board Software SFT"); OBS_SFT_block_ops(); StopMode_block_ops(); } //Set LCU2b back to standby status, procedure procedure LCU2b_standby_proc_fm { string band = "2b"; // HIFI band double lo_freq = 750.0 in [724.0,793.0]; //LO frequency }{ error("This module is obsolete: use LCU_standby_proc_fm instead"); } //Compute "real" frequencies double procedure Compute_Real_Freq { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978.2; //LO frequency }{ //Read parameters double[] result = CalibrationReader("name_lsu_convertion",["multiplier","f_offset","n10","n20"],band,lo_freq); double multiplier = result[0]; double f_offset = result[1]; int n10 = iround(result[2]); int n20 = iround(result[3]); // //Compute LSU frequency IN MHZ double f_lsu = lo_freq * 1000.0 / multiplier; //Compute total frequency double f_total = f_lsu + f_offset; //Compute parameter n int n = ifloor(15.0 * (f_total / 1.875 - double(ifloor(f_total / 1.875)))); //Compute main and offset loop parameters int n1 = n10 + n; // offset loop int d1 = 15; //offset loop int n2 = iround(abs(double(n20 - ifloor(f_total / 1.875) + n))); //main loop int d2 = 16; // //Compute A,M and R parameters for main and offset loop int m1 = ifloor(double(n1) / 10.0) - 1; // offset loop int a1 = n1 - 10 * ifloor(double(n1) / 10.0); // offset loop int r1 = d1 - 1; // offset loop int m2 = ifloor(double(n2) / 10.0) - 1; // main loop int a2 = n2 - 10 * ifloor(double(n2) / 10.0); // main loop int r2 = d2 - 1; // main loop // int[] lsu_a_m_r_parameter = [0,0,0,0,0,0]; lsu_a_m_r_parameter[0] = m1; lsu_a_m_r_parameter[1] = a1; lsu_a_m_r_parameter[2] = r1; lsu_a_m_r_parameter[3] = m2; lsu_a_m_r_parameter[4] = a2; lsu_a_m_r_parameter[5] = r2; // //Conversion into main and offset LSU word int main_word = iround(pow(2.0,18.0) * double(ifloor(double(r2) % pow(2.0,6.0) / pow(2.0,4.0))) + pow(2.0,15.0) * double(ifloor(double(m2) % pow(2.0,9.0) / pow(2.0,7.0))) + pow(2.0,8.0) * (double(m2) % pow(2.0,9.0)) + pow(2.0,4.0) * (double(r2) % pow(2.0,6.0) % pow(2.0,4.0)) + double(a2) % pow(2.0,4.0)); int offset_word = iround(pow(2.0,18.0) * double(ifloor(double(r1) % pow(2.0,6.0) / pow(2.0,4.0))) + pow(2.0,15.0) * double(ifloor(double(m1) % pow(2.0,9.0) / pow(2.0,7.0))) + pow(2.0,8.0) * (double(m1) % pow(2.0,9.0)) + pow(2.0,4.0) * (double(r1) % pow(2.0,6.0) % pow(2.0,4.0)) + double(a1) % pow(2.0,4.0)); // //debug_print("LSU conversion result " + lsu_a_m_r_parameter); //debug_print("main: " + main_word + ", offset: " + offset_word); // //Compute real LO frequency set by A,M,R combination double nn1 = double(10 * (m1 + 1) + a1); double dd1 = double(r1 + 1); double nn2 = double(10 * (m2 + 1) + a2); double dd2 = double(r2 + 1); double flsu_back = 24000.0 + 30.0 * (nn1 / dd1 + nn2 / dd2); if(band == "2a" || band == "3b") { flsu_back = 24000.0 + 30.0 * (nn1 / dd1 - nn2 / dd2); } double flo_back = flsu_back * multiplier; //debug_print("Real tuned frequency: " + flo_back); // return flo_back; } ////////////////////////////////////////////////////////// // Nominal configuration ///////////////////////// // LCU configuration AT START-UP into NOMINAL mode, procedure procedure LCU_switchon_proc_fm { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band }{ //Clear potential failure mode Set_LO_Nominal_block_fm(); // //We use a constant frequency for each band, regardless of the input double lo_freq = 0.0; double[] result_d = CalibrationReader("name_keyfreq",["keyfreq","midfreq","keyfreqwarm","keyfreq_dummy"],band,0.0); lo_freq = result_d[0]; //this is for cold operations // lo_freq = result_d[2]; //this is for warm operations // lo_freq = result_d[3]; //this is for dummy operations ////FM_CUS_11.5: replace keyfreq by the only allowed frequency for warm IST //For band 7b, 1723.5 may be problematic. Take mid freq. instead //if (band == "7b") { // lo_freq = result_d[1]; // } // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlcutune = "name_configlcutune_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1_v = result[0]{1}; string curlim2_v = result[1]{1}; // result = ConfigurationReader("name_delays",["switch_on_delay","config_lo_delay"],band,lo_freq); int switch_on_delay = iround(result[0]{0}); int config_lo_delay = iround(result[1]{0}); // cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); drain2_v = cresult[0]; //Send command: expect that we have already switched to NOMINAL //We set D2 to best guess and wait some time to stabilize chain temperature HIFI_Configure_LCU_block_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum,switch_on_delay); // //Set heater to their switch-on value HL_heater_block_fm(band,"nominal"); } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // CUS scripts for HRS. // HRS FT scripts are found under fm_FT_HRS.cus // // DT - 17-Feb-06 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // The modes //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // See fm_testmodes.cus //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // The blocks //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // HRS polar switch test - scenario proposed by NDW, block procedure HRS_polar_switch_proc_fm { string band = "1a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code }{ // //Get biases. No LO freq. given here. {double,string}[] result = ConfigurationReader("name_confilfpu",["bias_low_resistive_h","bias_high_resistive_h","bias_low_resistive_v","bias_high_resistive_v"],band,0.0); double bias_low_h = result[0]{0}; double bias_high_h = result[1]{0}; double bias_low_v = result[2]{0}; double bias_high_v = result[3]{0}; // //some global settings int integ_time = 4; string backend = "hrs"; //Prepare magnets Set_Magnet_current_block_fm(0.0,0.0); //Set biases to 10mV - SPR-2110 Mixerbias_block_fm(bias_high_h,bias_high_v); // //1. Configure HRS with normal switches: HRH on H, HRV on V HRS_config_w_switch_block_fm(band,hrs_mode,["H","V"]); //tune and take IF noise measurement HRS_tune_block_fm(band); Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); //Take 5 and 10mV shot noise spectra Spectra_resistive_low_fm(band,bias_low_h,bias_low_v,integ_time,backend); Spectra_resistive_high_fm(band,bias_high_h,bias_high_v,integ_time,backend); // //2. Configure HRS with new switches: HRH on H, HRV on H HRS_config_w_switch_block_fm(band,hrs_mode,["H","H"]); //tune and take IF noise measurement HRS_tune_block_fm(band); Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); //Take 5 and 10mV shot noise spectra Spectra_resistive_low_fm(band,bias_low_h,bias_low_v,integ_time,backend); Spectra_resistive_high_fm(band,bias_high_h,bias_high_v,integ_time,backend); // //3. Configure HRS with new switches: HRH on V, HRV on V HRS_config_w_switch_block_fm(band,hrs_mode,["V","V"]); //tune and take IF noise measurement HRS_tune_block_fm(band); Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); //Take 5 and 10mV shot noise spectra Spectra_resistive_low_fm(band,bias_low_h,bias_low_v,integ_time,backend); Spectra_resistive_high_fm(band,bias_high_h,bias_high_v,integ_time,backend); // //4. back to standard setting //Need a representative frequency: take keyfreq double[] result_d = CalibrationReader("name_keyfreq",["keyfreq"],band,0.0); double lo_freq = result_d[0]; result = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v","norm_bias_h","norm_bias_v"],band,lo_freq); double magnet_h = result[0]{0}; double magnet_v = result[1]{0}; double bias_h = result[2]{0}; double bias_v = result[3]{0}; HRS_config_w_switch_block_fm(band,hrs_mode,["H","V"]); Mixerbias_block_fm(bias_h,bias_v); Set_Magnet_current_block_fm(magnet_h,magnet_v); } // WBS reset, block // Both polarizations are treated block WBS_reset_block_fm HIFI 3602 { }{ //Fetch applicable HK rate {double,string}[] result_d = ConfigurationReader("name_delays",["hk_rate"],"0",0.0); string hk_rate = result_d[0]{1}; //Switch off HK request on WBS Hifi_HIFI_Housekeeping_on(hk_rate,"ON","ON","OFF","OFF","ON","ON"); delay(1); Hifi_HIFI_reset_WBS_H($BBID); Hifi_HIFI_reset_WBS_V($BBID); delay(1); //Switch back on HK request on WBS Hifi_HIFI_Housekeeping_on(hk_rate,"ON","ON","ON","ON","ON","ON"); delay(1); // } //HIFI-COP-1.2-FPU_FT obs HifiEng_FPU_FT_COP { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b","8"]; // HIFI band double lo_freq = 500.0; //LO frequency string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(FPU_FT_COP_proc_ops(band,lo_freq,prime_or_redundant)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution FPU_FT_COP_proc_ops(band,lo_freq,prime_or_redundant); } if(state[0] == 5) { HIFISetHK("normal",true); StopMode_block_ops(); } } } //HIFI investigation of diplexer with M1, procedure //Perform diplexer scans at a series of M1 values //Frequencies and M1 values to use are pre-tabulated procedure Diplexerscan_M1_proc_fm_TV { string band = "7b" in ["3b","7b"]; // HIFI band int testblock = 1 in [1,3]; //Test block for 3b }{ mois_comment("Start of Diplexer scan investigation in band " + band); mois_comment("For this test, a special LCU safety table should have been uploaded via dedicated TPF files"); //We will loop on tabulated frequencies //For each we will tune LO power and do diplexer scans //for various M1 settings for 7b, and M1/M2 combinations for 3b //1. Get the list of frequencies to be used for the scan string tab1 = "config_M1calib_" + band + "_TV.config"; int total = table_size(tab1); if(band == "3b") { string tab2 = "config_M2calib_" + band + "_TV.config"; } double[] freq = []; double[] m1_1 = []; double[] m1_2 = []; double[] m1_3 = []; double[] m1_4 = []; double[] m1_5 = []; double[] m1_6 = []; double[] m1_7 = []; double[] m1_8 = []; double[] m2_1 = []; double[] m2_2 = []; double[] m2_3 = []; double[] m3_1 = []; for(int j = 1 .. total) { freq[j] = dlookup(tab1,"" + j,"frequency"); m1_1[j] = dlookup(tab1,"" + j,"m1_1"); m1_2[j] = dlookup(tab1,"" + j,"m1_2"); m1_3[j] = dlookup(tab1,"" + j,"m1_3"); m1_4[j] = dlookup(tab1,"" + j,"m1_4"); m1_5[j] = dlookup(tab1,"" + j,"m1_5"); if(band == "3b") { m1_6[j] = dlookup(tab1,"" + j,"m1_6"); m1_7[j] = dlookup(tab1,"" + j,"m1_7"); m1_8[j] = dlookup(tab1,"" + j,"m1_8"); m2_1[j] = dlookup(tab2,"" + j,"m2_1"); m2_2[j] = dlookup(tab2,"" + j,"m2_2"); m2_3[j] = dlookup(tab2,"" + j,"m2_3"); m3_1[j] = dlookup(tab2,"" + j,"m3_1"); } //Check whether this combination of band+freq is allowed in the current CUS Check_Band_vs_Freq_proc_fm(band,freq[j]); } // mois_step("Switch-on LO band"); //Only if first testblock if(testblock == 1) { LCU_switchon_proc_fm(band); //Wait an extra delay of 10 min for mid term stabilization delay(600); // } mois_step("Loop on frequencies and multiplier settings"); //Start loop on diplexer scans double[] m1_array = []; double[] m2_array = []; for(int i = 1 .. total) { //Configure FPU at that frequency Init_MSA_fm(band,"CLOSE",freq[i],"ON"); // //Loop on M1 settings int nb_m1 = 5; int nb_m2 = 1; if(band == "3b") { m1_array = [m1_1[i],m1_2[i],m1_3[i],m1_4[i],m1_5[i],m1_6[i],m1_7[i],m1_8[i]]; //now work with 3 blocks of 1 M2 m2_array = [m2_1[i]]; if(testblock == 2) { m2_array = [m2_2[i]]; } if(testblock == 3) { m2_array = [m2_3[i]]; } nb_m1 = 8; nb_m2 = 1; //3; //now work with 3 blocks of 1 M2 } if(band == "7b") { m1_array = [m1_1[i],m1_2[i],m1_3[i],m1_4[i],m1_5[i]]; nb_m1 = 5; } // for(int k = 0 .. nb_m1 - 1) { //Band 7b: loop only on M1 if(band == "7b") { //Prepare for diplexer scan //In case of band 6 or 7, use special biases if(band == "7b") { {double,string}[] result = ConfigurationReader("name_confilfpu",["bias_dipscan_h","bias_dipscan_v","bias_max_h","bias_max_v"],band,freq[1]); //First go to 4mV Mixerbias_block_fm(result[2]{0},result[3]{0}); //Then to 3mV Mixerbias_block_fm(result[0]{0},result[1]{0}); } // //Use nominal diplexer values double[] result_dip = Get_Diplexer_setting(band,freq[i]); Set_Diplexer_current_block_fm(result_dip[0],result_dip[1]); //First scan will be done at max Vd2 LCU_config_w_M1_block_fm(band,freq[i],m1_array[k]); //Perform diplexer scan at that frequency and M1 setting double diplexer_current_min_h = -2.24; double diplexer_current_max_h = 2.24; double diplexer_current_step = -0.073; //i.e. approx 4.48/61 int n_steps = 61; double stepTime = 0.1; // Scan_diplexer_block_fm(band,diplexer_current_max_h,diplexer_current_max_h,diplexer_current_step,n_steps,stepTime); //Add delay in order to get 30 sec between first tuning macro and this scan //delay(16); //no delay now since req is 30sec between 2 subsequent TM Scan_diplexer_block_fm(band,diplexer_current_max_h,diplexer_current_max_h,diplexer_current_step,n_steps,stepTime); //Back to nominal diplexer values for next tuning result_dip = Get_Diplexer_setting(band,freq[i]); Set_Diplexer_current_block_fm(result_dip[0],result_dip[1]); //In case of band 6 or 7,go back to nominal bias values for next LO tuning if(band == "7b") { result = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,freq[1]); //First go to 4mV Mixerbias_block_fm(result[0]{0},result[1]{0}); //Then to nominal result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,freq[1]); Mixerbias_block_fm(result[0]{0},result[1]{0}); } //Second diplexer scan at Vd2max - 100mV, or best-guess //Perform LO tuning at that frequency and M1 to get a reasonable pumping level LO_tuning_w_M1_block_fm(band,freq[i],m1_array[k]); //message(band+", "+freq[i]+", "+m1_array[k]); //Now prepare for diplexer scan //In case of band 6 or 7, use special biases if(band == "7b") { result = ConfigurationReader("name_confilfpu",["bias_dipscan_h","bias_dipscan_v","bias_max_h","bias_max_v"],band,freq[1]); //First go to 4mV Mixerbias_block_fm(result[2]{0},result[3]{0}); //Then to 3mV Mixerbias_block_fm(result[0]{0},result[1]{0}); } // Scan_diplexer_block_fm(band,diplexer_current_max_h,diplexer_current_max_h,diplexer_current_step,n_steps,stepTime); // } if(band == "3b") { for(int l = 0 .. nb_m2 - 1) { //Prepare for diplexer scan //Use nominal diplexer values result_dip = Get_Diplexer_setting(band,freq[i]); Set_Diplexer_current_block_fm(result_dip[0],result_dip[1]); //Set the maximum Vd2 available LCU_config_w_M1M2M3_block_fm(band,freq[i],m1_array[k],m2_array[l],m3_1[i]); //message(band+", "+freq[i]+", "+m1_array[k]+", "+m2_array[l]+", "+m3_1[i]); //Perform diplexer scan at that frequency and M1 setting diplexer_current_min_h = -2.24; diplexer_current_max_h = 2.24; diplexer_current_step = -0.073; //i.e. approx 4.48/61 n_steps = 61; stepTime = 0.1; // //Perform 2 diplexer scans: one immediately after, and one X sec after the tuning macro //so that total time between tuning macros is 1min, or 30sec between tuning macro and 2nd scan Scan_diplexer_block_fm(band,diplexer_current_max_h,diplexer_current_max_h,diplexer_current_step,n_steps,stepTime); // //Add delay: //For one minute between each tuning macro: 25sec more on average //For 30sec between tuning macro and second scan: 16sec more on average //Req. is now: 30sec between 2 tuning macros -> 4sec delay(4); //Second scan Scan_diplexer_block_fm(band,diplexer_current_max_h,diplexer_current_max_h,diplexer_current_step,n_steps,stepTime); } } // } } //In case of band 6 or 7,go back to nominal values at end of loop if(band == "7b") { result = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,freq[1]); //First go to 4mV Mixerbias_block_fm(result[0]{0},result[1]{0}); //Then to nominal result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,freq[1]); Mixerbias_block_fm(result[0]{0},result[1]{0}); } // mois_comment("At the end of this test, the standard LCU safety table should be uploaded again."); } // Standing wave analysis // This is the testmode to loop on all parameters for total time estimate //HIFI-COP-3-StWv1 obs HifiManCmd_standing_wave_noretune_MOIS { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band }{ //General parameters in use string backend = "both"; string[] hrs_mode = ["mr","mr"]; // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Standing_wave_noretune_MOIS_proc_ops(band,backend,hrs_mode)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Standing_wave_noretune_MOIS_proc_ops(band,backend,hrs_mode); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } // Initialisation of FPU, block with both MSA in use // Looks at the hot load ! // It is for cold context ! block Init_MSA_SKY_fm HIFI 3997 { string band = "1a"; // HIFI band string chop_loop = "CLOSE"; double lo_freq = 522.0; //LO frequency string hbb_heater = "ON" in ["ON","OFF"]; //hot source on/off }{ Start_block(); //Get parameters {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,lo_freq); int band_nb = iround(result_d[0]{0}); double diplex_H = 0.0; double diplex_V = 0.0; int diplex_h_ctrl_mode = 0; int diplex_v_ctrl_mode = 0; // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,lo_freq); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // string chop_sine_s = "ON"; // string chop_loop = "CLOSE" ; result_d = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,lo_freq); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // double calibcurrent = result_d[7]{0}; if(hbb_heater == "ON") { result_d = ConfigurationReader("name_confilfpu",["calibrator_current_on"],band,lo_freq); calibcurrent = result_d[0]{0}; } // //Get biases result_d = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); double bias_H = result_d[0]{0}; double bias_V = result_d[1]{0}; //For bands 6 and 7, first set to 4mV if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { result_d = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,lo_freq); bias_H = result_d[0]{0}; bias_V = result_d[1]{0}; } // //Get magnets: not applicable to bands 6 and 7 double magnetcurrent_H = 0.0; double magnetcurrent_V = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,lo_freq); magnetcurrent_H = result_d[0]{0}; magnetcurrent_V = result_d[1]{0}; } //Diplexer is interpolated from a table for Bands 3, 4, 6L and 6H if(band_nb <= 2 || band_nb == 5) { diplex_H = 0.0; //For bands 1, 2 and 5 diplex_V = 0.0; diplex_h_ctrl_mode = 0; diplex_v_ctrl_mode = 0; } else { //Get diplexer currents result_d = ConfigurationReader("name_confilfpu",["diplex_h_ctrl_mode","diplex_v_ctrl_mode"],band,lo_freq); diplex_h_ctrl_mode = iround(result_d[0]{0}); diplex_v_ctrl_mode = iround(result_d[1]{0}); double[] result_dip = Get_Diplexer_setting(band,lo_freq); diplex_H = result_dip[0]; diplex_V = result_dip[1]; } // result_d = ConfigurationReader("name_confilfpu",["chop_M3"],band,0.0); //result_d = ConfigurationReader("name_chopper",["chop_startup_cold"], // band,0.0); if(chop_loop == "OPEN") { result_d = ConfigurationReader("name_chopper",["chop_startup_warm"],band,0.0); } double chopper = result_d[0]{0}; //For this configuration we won't convert prime chopper voltage into redundant voltage //Just checking we are in range. //chopper = Check_Chopper_Prime_Redundant(chopper); chopper = Check_Chopper_Range(chopper); // //Switch on upconverter, assuming chopper and mixers are also ON Hifi_HIFI_Configure_FCU_Power($BBID,"ON","ON","ON","ON","ON"); // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result_d = ConfigurationReader("name_delays",["config_fpu_delay"],band,lo_freq); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // //In case of band 6 or 7, bias have been set to 4mV. Now set to nominal if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { {double,string}[] result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); Mixerbias(result[0]{0},result[1]{0}); } // //Magnet are so far at maximum value. Now set to nominal if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); Hifi_HIFI_CH1_MX_MG_C($BBID,result_d[0]{0}); Hifi_HIFI_CV1_MX_MG_C($BBID,result_d[1]{0}); delay(1); } // //Hifi_HIFI_non_periodic_hk_FCU (); } ///////////////////////////////////////// // Testmodes for handling of LCU safety // tables and memory patches // AdJ - 17-08-2006: initial version // DT - 16-04-2007: reviewed for MOC ///////////////////////////////////////// //Upload of partial LCU safety tables partial mode //Prime/Redundant is handled with the CUS table //Required for flight procedures as total number of command parameters //is limited to 999 mode HifiManCmd_upload_LCU_table_flight_ops { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! string section = "P" in ["P","R"]; int start = 0; int count = 450 in [0,450]; }{ mois_comment("This procedure MUST be performed after the LCU memory patch HIF_CUPM"); string tab = "LcuSafetyTable_" + section + ".config"; int lastline = imin(table_size(tab),start + count); int firstline = start + 1; mois_comment("Start LCU table upload from line " + firstline + " until line " + lastline); mois_tmcheck("Verify that parameter HL_Mode_S is set to standby."); StartMode_block_ops(); mois_step("Perform safety table upload"); LcuSafetyTableUpload_ops(section,start,count); StopMode_block_ops(); } // Measurement done after HRS 0-lag freqscan, procedure // We measure a short stability TP and a long Y-factor in fast-chop procedure Proc_Hotcold_w_stability { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 522.0; //Operative LO freq to be tuned in GHz int n = 100; //Number of TP measurement during stability string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int integ_time = 4; //Total (co-added) integration time of a phase in sec. double chop_phase = 1.0 in [0.2,2.0]; // Chop phase length for Y-factor in fastchop string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ Chopper_Rotation_block_fm(band,"chop_M3_ang","chop_cold_ang"); //Look at CBB // if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band); } //Tune at user input LO frequencies. LO_tuning_block_fm(band,lo_freq); // //Magnet tuning: only up to band 5 since band6-7 have no magnets if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { {double,string}[] result_d = ConfigurationReader("name_configwbs",["tune_target_magnet"],band,lo_freq); int tune_target_magnet = iround(result_d[0]{0}); Magnet_tuning_block_fm(band,lo_freq,"HRS",tune_target_magnet); //HRS is preferred } // //WBS calibration and backend tuning if(backend == "wbs" || backend == "both") { WBS_tune_proc_fm(band); } if(backend == "hrs" || backend == "both" || backend == "hrsFast") { HRS_tune_block_fm(band); } // // //Total power stability measurement: WBS only, 2sec. for B1-5, 1sec for B6-7 TP if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { Stability_intcold_fm(band,n,2,"wbs",hrs_mode,"tp",chop_phase); } else { Stability_intcold_fm(band,n,1,"wbs",hrs_mode,"tp",chop_phase); } //Take Y-factor during ~10 sec. on each load in fastchop //Configure spectrometers integration: this only applies to the Y-factor fastchop //Integ_time expected here is the TOTAL integration time with both phases + residual HRS time int[] res = Configure_Spectrometer_fast_chop_proc_fm(band,integ_time * 2,chop_phase,hrs_mode,backend); integ_time = iceil(chop_phase * double(res[1] * res[2])); //debug_print("Fast chop parameters: n_wbs1 = "+res[2]+", n_hrs_trans = "+res[3]); int n_wbs1 = res[2]; int n_hrs_trans = res[3]; //Y-factor measurement Hot_cold(band,hrs_mode,backend,integ_time,"fastchop",n_wbs1,n_hrs_trans); // } // FPU Standby with HBB ON, block block Band0_hbb_on_block_ops HIFI 7298 { string band = "0"; // HIFI band string chop_loop = "CLOSE"; // Chopper Loop status string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ //Get parameters {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,0.0); int band_nb = iround(result_d[0]{0}); // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,0.0); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // string chop_sine_s = "ON"; // result_d = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current_on"],band,0.0); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // double calibcurrent = result_d[7]{0}; // result_d = ConfigurationReader("name_confilfpu",["bias_standby_h","diplexer_standby_h","bias_standby_v","diplexer_standby_v","diplex_h_ctrl_mode","diplex_v_ctrl_mode","chop_M3right"],band,0.0); // double bias_H = result_d[0]{0}; double diplex_H = result_d[1]{0}; double bias_V = result_d[2]{0}; double diplex_V = result_d[3]{0}; int diplex_h_ctrl_mode = iround(result_d[4]{0}); int diplex_v_ctrl_mode = iround(result_d[5]{0}); double chopper = result_d[6]{0}; // //Retrieve magnets. if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilfpu",["magnet_standby_h","magnet_standby_v"],band,0.0); double magnetcurrent_H = result_d[0]{0}; double magnetcurrent_V = result_d[1]{0}; } // //Upconverter: should be kept ON at this stage. No particular action. // if(prime_or_redundant == "Prime") { Hifi_HIFI_P_Configure_FCU($BBID,band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); } else { Hifi_HIFI_R_Configure_FCU($BBID,band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); } // result_d = ConfigurationReader("name_delays",["config_fpu_delay"],band,0.0); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // Hifi_HIFI_non_periodic_hk_FCU(); // mois_tmcheck("Check that parameter HF_APR_CS_C is set to " + calibcurrent + " mA"); mois_tmcheck("Check that parameter HF_DPR_CHLOOP_S is set to " + chop_loop); mois_tmcheck("Check that parameter HF_DPR_CHSINE_S is set to " + chop_sine_s); } //Check consistency between frequency and M1 choice for 7b bool procedure Check_M1_vs_Freq_proc_fm { string band = "7b" in ["7b","7b"]; // HIFI band double lo_freq = 1800.0; //LO frequency double m1 = -6.0; //M1 multiplier voltage }{ bool go_ahead_m1 = true; string name_configlcu = "name_configlcu_b"; {double,string}[] result = ConfigurationReader(name_configlcu,["m1_v"],band,lo_freq); double m1_v = result[0]{0}; if(m1 > m1_v || m1 < -8.5) { go_ahead_m1 = false; } if(go_ahead_m1 == false) { error("M1 not within allowed range (-8.5 to " + m1_v + " V) for band " + band); } return go_ahead_m1; } //Notify PDU status ON, block //I assume all S/S are present block HIFI_notify_PDU_status_on_block_ops HIFI 7655 { string status_FCU = "ON" in ["ON","OFF"]; //Status of FCU string status_LCU = "ON" in ["ON","OFF"]; //Status of LCU string status_WBSV = "ON" in ["ON","OFF"]; //Status of WBSV string status_WBSH = "ON" in ["ON","OFF"]; //Status of WBSH string status_HRSV = "ON" in ["ON","OFF"]; //Status of HRSV string status_HRSH = "ON" in ["ON","OFF"]; //Status of HRSH string apply_to_subsystem = "FCU" in ["FCU","LCU","WBSH","WBSV","HRSH","HRSV","ALL"]; }{ StartBlock_ops(); //This has no delay Hifi_HIFI_notify_PDU_status(status_FCU,status_LCU,status_WBSV,status_WBSH,status_HRSV,status_HRSH); delay(1); //Prepare message for operator: we will check whether one particular HK is ON if(status_FCU == "ON") { string subsyst_on = "HI_FCU_S"; } if(status_WBSH == "ON") { subsyst_on = "HI_WBSH_S"; } if(status_WBSV == "ON") { subsyst_on = "HI_WBSV_S"; } if(status_HRSH == "ON") { subsyst_on = "HI_HRSH_S"; } if(status_HRSV == "ON") { subsyst_on = "HI_HRSV_S"; } if(status_LCU == "ON") { subsyst_on = "HI_LCU_S"; } mois_tmcheck("Check that the HK parameter " + subsyst_on + " is ON."); //Specific S/S check after switch on if(apply_to_subsystem == "FCU" || apply_to_subsystem == "ALL") { //Nothing in particular } if(apply_to_subsystem == "WBSH" || apply_to_subsystem == "ALL") { //This is now done at end of procedure as instrument mode status check //mois_tmcheck("Check that both parameters HWH_Laser1_S and HWH_Laser2_S are OFF"); //mois_tmcheck("Check that parameter HWH_Zero_S is ON"); //mois_tmcheck("Check that parameter HWH_IN_ATT is set to 15, and parameters HWH_Band_1_ATT, HWH_Band_2_ATT, HWH_Band_3_ATT, HWH_Band_4_ATT are set to 7"); } if(apply_to_subsystem == "WBSV" || apply_to_subsystem == "ALL") { //This is now done at end of procedure as instrument mode status check //mois_tmcheck("Check that both parameters HWV_Laser1_S and HWV_Laser2_S are OFF"); //mois_tmcheck("Check that parameter HWV_Zero_S is ON"); //mois_tmcheck("Check that parameter HWV_IN_ATT is set to 15, and parameters HWV_Band_1_ATT, HWV_Band_2_ATT, HWV_Band_3_ATT, HWV_Band_4_ATT are set to 7"); } if(apply_to_subsystem == "HRSH" || apply_to_subsystem == "ALL") { //This is now done at end of procedure as instrument mode status check //mois_tmcheck("Check that parameters HRH_1U_ATT, HRH_1L_ATT, HRH_2U_ATT, HRH_2L_ATT, HRH_3U_ATT, HRH_3L_ATT, HRH_4U_ATT and HRH_4L_ATT are set to 15.5"); } if(apply_to_subsystem == "HRSV" || apply_to_subsystem == "ALL") { //This is now done at end of procedure as instrument mode status check //mois_tmcheck("Check that parameters HRV_1U_ATT, HRV_1L_ATT, HRV_2U_ATT, HRV_2L_ATT, HRV_3U_ATT, HRV_3L_ATT, HRV_4U_ATT and HRV_4L_ATT are set to 15.5"); } if(apply_to_subsystem == "LCU" || apply_to_subsystem == "ALL") { //This is now done at end of procedure as instrument mode status check //mois_tmcheck("Check that parameter HL_MODE_S is standby"); //mois_tmcheck("Check that parameter HL_Channel_S is OFF"); } } //General script to read TM1, TM2,etc, block block LCU_Read_TM_pages_OLD_block_fm HIFI 3968 { }{ //Re-implement old way to be consistent with MOIS manual procedures // //Get various TM pages. This will clear error flags too //Hifi_HIFI_LCU_all_tuning_hk(); //delay(2); ///////////////////////////////////// //Temporary work-around for TVTB SFT //Get various TM pages Hifi_HIFI_LCU_macro_tuning_hk("HSK_TM1"); delay(2); Hifi_HIFI_LCU_macro_tuning_hk("HSK_TM2"); delay(2); Hifi_HIFI_LCU_macro_tuning_hk("HSK_TM3"); delay(2); Hifi_HIFI_LCU_macro_tuning_hk("HSK_TM"); delay(2); Hifi_HIFI_LCU_macro_tuning_hk("HSK_G"); delay(2); // //Clear error flags Hifi_HIFI_LCU_Single($BBID,"HL_CLR_ERR"); // } // Total noise from an OTF observation // double procedure OtfNoise { double n = 10.0; // number of points in one scan double[] parameters = [0.02,0.4,0.05,0.667,2.5]; // Parameters: integration time, delay, slew from OFF relative to Allan time, ratio of t_off time to sqrt(n)*t_on, drift exponent }{ {double,double} noisevalues = OtfNoiseValues(n,parameters); double y = noisevalues{0} + noisevalues{1}; return y; } //Set LCU2a back to standby status, procedure procedure LCU2a_standby_proc_fm { string band = "2a"; // HIFI band double lo_freq = 700.0 in [647.0,710.0]; //LO frequency }{ error("This module is obsolete: use LCU_standby_proc_fm instead"); } /////////////////////////////////////////////////// // CUS scripts thermal monitoring of the FPU. // Based on SCOE tests initially performed for // the QM by BK. // They are here updated for FM. There will be // independent tests for respective H and V. // // DT - 17/11/04: first draft for FM. Thermal test // new has been removed. // /////////////////////////////////////////////////// //modes: see fm_testmodes.cus ///////////////////////////////////////////// // Blocks for thermal tests ///////////////////////////////////////////// // thermal tests block Thermal_fm HIFI 3280 { string band = "1a"; // HIFI band double lo_freq = 522.0; //LO frequency }{ //Start_block(); //Get band number {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band"],band,lo_freq); int band_nb = iround(result_d[0]{0}); // //Get Targetted values for magnet, mixer bias, heater time and diplexer double[] cresult_d = CalibrationReader("name_configthermal",["dipl_h","magn_h","mbias_h","heat_h","dipl_v","magn_v","mbias_v","heat_v"],band,0.0); double target_dipl_h = cresult_d[0]; double target_magn_h = cresult_d[1]; double target_mbias_h = cresult_d[2]; double target_heat_h = cresult_d[3]; double target_dipl_v = cresult_d[4]; double target_magn_v = cresult_d[5]; double target_mbias_v = cresult_d[6]; double target_heat_v = cresult_d[7]; // int diplex_h_ctrl_mode = 0; // //IF amplifiers should be set to standby values result_d = ConfigurationReader("name_confilfpu",["fif1v_h","fif1c_h","fif2v_h","fif2c_h"],"0",0.0); double volt_H_FIF_1 = result_d[0]{0}; double curr_H_FIF_1 = result_d[1]{0}; double volt_H_FIF_2 = result_d[2]{0}; double curr_H_FIF_2 = result_d[3]{0}; // result_d = ConfigurationReader("name_confilfpu",["sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],"0",0.0); double volt_H_SIF_1 = result_d[0]{0}; double curr_H_SIF_1 = result_d[1]{0}; double volt_H_SIF_2 = result_d[2]{0}; double curr_H_SIF_2 = result_d[3]{0}; double volt_H_SIF_3 = result_d[4]{0}; double curr_H_SIF_3 = result_d[5]{0}; // int diplex_v_ctrl_mode = 0; // result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v"],"0",0.0); double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // result_d = ConfigurationReader("name_confilfpu",["sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],"0",0.0); double volt_V_SIF_1 = result_d[0]{0}; double curr_V_SIF_1 = result_d[1]{0}; double volt_V_SIF_2 = result_d[2]{0}; double curr_V_SIF_2 = result_d[3]{0}; double volt_V_SIF_3 = result_d[4]{0}; double curr_V_SIF_3 = result_d[5]{0}; // string chop_sine_s = "ON"; string chop_loop = "CLOSE"; result_d = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3"],band,lo_freq); int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // result_d = ConfigurationReader("name_confilfpu",["calibrator_current_on"],band,lo_freq); double calibcurrent = result_d[0]{0}; //Initialize settings double bias_H = 0.0; double magnetcurrent_H = 0.0; double diplex_H = 0.0; double bias_V = 0.0; double magnetcurrent_V = 0.0; double diplex_V = 0.0; //Look at CBB at start of test result_d = ConfigurationReader("name_confilfpu",["chop_cold"],band,lo_freq); double chopper = result_d[0]{0}; chopper = Check_Chopper_Prime_Redundant(chopper); // //Start modification of FPU parameters - This is also the 0 of the test clock //1. Initial configuration with the chopper moving to M3 middle // and diplexer_H set to targetted value // //Diplexer is only used for Bands 3, 4, 6L and 6H if(band_nb <= 2 || band_nb == 5) { diplex_H = 0.0; //For bands 1, 2 and 5 diplex_V = 0.0; diplex_h_ctrl_mode = 0; diplex_v_ctrl_mode = 0; } else { diplex_H = target_dipl_h * 1.0; diplex_V = target_dipl_v * 0.0; // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // delay(900); // //Actuate diplexer_V diplex_H = target_dipl_h * 1.0; diplex_V = target_dipl_v * 1.0; // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // delay(900); } // //2. Set IF1 ON // result_d = ConfigurationReader("name_confilfpu",["fif1v_h","fif1c_h","fif2v_h","fif2c_h"],band,lo_freq); volt_H_FIF_1 = result_d[0]{0}; curr_H_FIF_1 = result_d[1]{0}; volt_H_FIF_2 = result_d[2]{0}; curr_H_FIF_2 = result_d[3]{0}; // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(900); // result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v"],band,lo_freq); volt_V_FIF_1 = result_d[0]{0}; curr_V_FIF_1 = result_d[1]{0}; volt_V_FIF_2 = result_d[2]{0}; curr_V_FIF_2 = result_d[3]{0}; // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(900); // //3. Set IF2 ON // result_d = ConfigurationReader("name_confilfpu",["sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,lo_freq); volt_H_SIF_1 = result_d[0]{0}; curr_H_SIF_1 = result_d[1]{0}; volt_H_SIF_2 = result_d[2]{0}; curr_H_SIF_2 = result_d[3]{0}; volt_H_SIF_3 = result_d[4]{0}; curr_H_SIF_3 = result_d[5]{0}; // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(900); // result_d = ConfigurationReader("name_confilfpu",["sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,lo_freq); volt_V_SIF_1 = result_d[0]{0}; curr_V_SIF_1 = result_d[1]{0}; volt_V_SIF_2 = result_d[2]{0}; curr_V_SIF_2 = result_d[3]{0}; volt_V_SIF_3 = result_d[4]{0}; curr_V_SIF_3 = result_d[5]{0}; // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(900); // //5. Magnet current to max., then to dedicated value for thermal test if(band_nb <= 5) { //Set to targetted values magnetcurrent_H = target_magn_h; // //Magnet-H HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(900); magnetcurrent_V = target_magn_v; // //Magnet-V HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(900); } // //6. Bias voltage to dedicated value for thermal test bias_H = target_mbias_h; //H-bias HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(900); //V-bias bias_V = target_mbias_v; HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(900); // //7.Turn everything off bias_H = 0.0; bias_V = 0.0; magnetcurrent_H = 0.0; magnetcurrent_V = 0.0; diplex_H = 0.0; diplex_V = 0.0; // result_d = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],"0",0.0); // volt_H_FIF_1 = result_d[1]{0}; curr_H_FIF_1 = result_d[2]{0}; volt_H_FIF_2 = result_d[3]{0}; curr_H_FIF_2 = result_d[4]{0}; volt_H_SIF_1 = result_d[5]{0}; curr_H_SIF_1 = result_d[6]{0}; volt_H_SIF_2 = result_d[7]{0}; curr_H_SIF_2 = result_d[8]{0}; volt_H_SIF_3 = result_d[9]{0}; curr_H_SIF_3 = result_d[10]{0}; // {double,string}[] result_d2 = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],"0",0.0); // volt_V_FIF_1 = result_d2[0]{0}; curr_V_FIF_1 = result_d2[1]{0}; volt_V_FIF_2 = result_d2[2]{0}; curr_V_FIF_2 = result_d2[3]{0}; // volt_V_SIF_1 = result_d2[4]{0}; curr_V_SIF_1 = result_d2[5]{0}; volt_V_SIF_2 = result_d2[6]{0}; curr_V_SIF_2 = result_d2[7]{0}; volt_V_SIF_3 = result_d2[8]{0}; curr_V_SIF_3 = result_d2[9]{0}; // HIFI_Configure_FCU_proc_fm(0,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(1200); // //12. Check heater current effect on temperature: Let current ON // during the standard deflux time. //First, call same FPU configuration, but specify band to be used to switch on band again //We will bias the junction to check when //the heater effect is effective result_d = ConfigurationReader("name_confilfpu",["bias_very_low_h","bias_very_low_v"],band,lo_freq); bias_H = result_d[0]{0}; bias_V = result_d[1]{0}; // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(3); // //Get time during which one wants to send the pulse double max_heater_time_h = target_heat_h * 1000.0; //in msec double max_heater_time_v = target_heat_v * 1000.0; //in msec //Start to send the pulse //H-heater Hifi_HIFI_HF_CH1_DHTR_C($BBID,max_heater_time_h); //delay(iceil(max_heater_time_h / 1000.0) + 1); delay(600); //V-heater Hifi_HIFI_HF_CV1_DHTR_C($BBID,max_heater_time_v); //delay(iceil(max_heater_time_v / 1000.0) + 1); delay(1200); // //13. Chop to HBB result_d = ConfigurationReader("name_confilfpu",["chop_hot"],band,lo_freq); chopper = result_d[0]{0}; chopper = Check_Chopper_Prime_Redundant(chopper); // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(600); //14. Chop back to CBB result_d = ConfigurationReader("name_confilfpu",["chop_cold"],band,lo_freq); chopper = result_d[0]{0}; chopper = Check_Chopper_Prime_Redundant(chopper); // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(600); // } // Global frequency switch spectroscopy for stability measurement, procedure // We assume it works like fast chop procedure Freqswitch_spectro_for_Stability_proc_fm { string band = "1a"; // HIFI band int n = 100; //The number of integration pairs int integ_time = 8; //Total (co-added) integration time of a phase in sec. string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code }{ //First derive backend setting codes as expected by VO's routine //Build up backend parameter tupple: {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = BackendSettings(band,0.0,hrs_mode,backend); // Readout parameters for HRS1,HRS2, WBS1,WBS2 //Compute data_time and n_switch using the wrapper int[] res = ConfigSlowChop(integ_time,"fs",band,0.0,backendreadoutparms); int data_time = res[0]; int n_switch = n * res[1]; //For stability measurement, the number of loop is a user input // Now call the spectroscopy setup: it is common to ILT and AOT CUS. // The deadtimes output is not used at ILT level. {double,double} dtimes = ConfigSpectroscopySlowChop(data_time,n_switch,"fs",band,0.0,backendreadoutparms,true); //Compute data-rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] rates = dataparms{1}; // set data rates non_ess_hk_data_rate(rates[2] / 1024.0); data_rate(rates[0] / 1024.0); //Now start the long integration Hifi_HIFI_Spectr_freq_switch($BBID); // Apply_Slow_Chop_delay(data_time * n_switch,band,backend); // reset data rates non_ess_hk_data_rate(rates[1] / 1024.0); data_rate(0.0); } ////////////////////////////////////////////////////////////////////// // Procedure to perform the noise level evaluation for the observing mode {double,double,double,double,double} procedure SScanFSwitch_noisecomputer { string band = "4a"; // HIFI band double reffreq = 978300.0; // Reference LO frequency in scan center int nfreq = 4; // Number of frequency points per IF bool dsb = true; // Both sidebands covered {double,double} eff_resolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz int on_inttime = 16; // Integration time per ON phase int off_inttime = 16; // Integration time per OFF phase int n_cycles = 1; // Number of half OFF-ON-ON-OFF cycles at one frequency double tscan = 60.0; // Total average duration of one scan {double,double,double,double,double} tact = {10.0,4.9,4.9,0.05,0.05}; // Field of actual dead and integration times }{ // spectral scans always use the full bandwidth for reference bool oneGHzReference = false; // Call FS noise computer {double,double,double,double,double} noisevalues = FSwitch_noisecomputer(band,reffreq,eff_resolution,oneGHzReference,on_inttime,off_inttime,n_cycles,tscan,tact); // Correct for multiple frequencies double multiplier = sqrt(1.0 / double(nfreq)); noisevalues{0} = noisevalues{0} * multiplier; noisevalues{1} = noisevalues{1} * multiplier; // Check for double sideband coverage if(dsb) { // Combine LSB-USB noise // In spectral scans we have only a combined noise temperature for both // sidebands, so that the USB/LSB separation is not used double[] gssb = InterpolateGssb(band,reffreq); double usbnoise_lores = noisevalues{0} / sqrt(1.0 + gssb[1] / gssb[0] * (gssb[1] / gssb[0])); double usbnoise_hires = noisevalues{1} / sqrt(1.0 + gssb[1] / gssb[0] * (gssb[1] / gssb[0])); double lsbnoise_lores = usbnoise_lores; double lsbnoise_hires = usbnoise_hires; } else { // Get single sideband noise equivalent usbnoise_lores = noisevalues{0}; usbnoise_hires = noisevalues{1}; lsbnoise_lores = noisevalues{2}; lsbnoise_hires = noisevalues{3}; } // Return noise values and the maximum ratio of drift to radiometric noise return {usbnoise_lores,usbnoise_hires,lsbnoise_lores,lsbnoise_hires,noisevalues{4}}; } // Length of a vector in degrees double procedure VectorLength { {double,double} vector = {1.0,1.0}; }{ return sqrt(vector{0} * vector{0} + vector{1} * vector{1}); } // FPU settling time for a mixer band change, 2nd block // Block for second tuning block FPU_Settling_time_second_tuning_fm HIFI 3684 { string band_2 = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band int int_time2 = 600; //Integration time after first and second switch double lo_freq_2 = 500.0; //LO frequency in sub-band b string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); // // //Init and tune of LO: configuration from safe to tuned. LCU_config_nominal_proc_fm(band_2,lo_freq_2); LO_tuning_w_mixerchoice_proc(band_2,lo_freq_2,"H"); // //Configure spectroscopy integration Configure_Spectrometer_proc_fm(band_2,int_time2,["wb1","wb1"],backend); //4 sec. integration //Take series of spectra during int_time2 seconds HIFI_Spectr_total_power_proc_fm(band_2,backend,int_time2); // //Now switch off LO sub-band LCU_switch_off_proc_fm(); } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the DBS raster mode procedure FastDBSRaster_commanding { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 10 in [4,80]; // data dump interval int n_int = 20; // number chop cycles to integrate in ICU before transfer int n_seq = 1; // number of data transfer cycles per pointing int n_cycles = 1; // Number of half OFF-ON-ON-OFF cycles int n_pointsperscan = 1; // Number of points measured before moving to the second pointing phase int n_loadinterval = 10; // number of nods before a load measurement int n_load = 0; // additional load measurements in one pointing phase bool final_load = false; // Need for final load measurement int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,10,0,10,20,21,0,0,0]; // Timing of the observation from telescope int loadlength = 21; // Load duration bool iscross = false; // Whether we use a cross instead of a raster }{ // Auxiliary variables // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Fixed timings in the fast-chop mode int load_datatime = GetStdLoadReadout(band,lo_freq); // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time //////////////////////////////////////////////////////////////////////// // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // // Clustering is currently not implemented in MPS - switched off here int clustered = 0; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time / 2); double[] rates = dataparms{1}; int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,true); int readoutdead = FastChopReadoutDelay(band,lo_freq,backendreadoutparms); // Count phases by hand to allow simultaneous usage by Raster and Cross int iphase = 0; // There is no nod counter in the return values - count this by hand int inod = 0; // Do I have to make loads in short nods and subsequent holds? if(iscross) { bool holdforload = n_pointsperscan > 1; } else { holdforload = n_pointsperscan == 1 && n_loadinterval > n_cycles; } bool isOffAtPoint = false; //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; int[] choppars = [2 * n_int,0]; bool runintostate = false; while(state[0] >= 0) { if(runintostate) { state = next_state_no_check(); } else { state = next_state(); } if(state[0] == 1) { // Initialization if(clustered != 1) { HIFIInitObs(); TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal"); } delay(tinitslew - (time() - startobs) - hkduration - loadlength); // First load measurement HIFISetHK("normal",false); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); runintostate = false; iphase = iphase + 1; } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 3) { // First nodding position // Check whether we are in a cross mode using computed OFF isOffAtPoint = iscross && inod % 2 == 0; // Configure measurement choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_seq,band,lo_freq,backendreadoutparms); // Loop for load cycles // The use of n_load differs by 1 from the other observing modes here for(int i1 = 1 .. n_load - 1) { if(isOffAtPoint) { HIFIFastChopOffIntegration(data_time,n_seq,band,lo_freq,choppars,rates); } else { HIFIFastChopOnIntegration(data_time,n_seq,band,lo_freq,choppars,rates); } // Perform load calibration delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_seq,band,lo_freq,backendreadoutparms); } // Last cycle - no load if(isOffAtPoint) { HIFIFastChopOffIntegration(data_time,n_seq,band,lo_freq,choppars,rates); } else { HIFIFastChopOnIntegration(data_time,n_seq,band,lo_freq,choppars,rates); } // Load measurement if required - time included in pointing if(n_load > 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); } // Final point before nod // Special treatment for all cases where load has to be replaced by hold: // n_pointsperscan=1, n_loadinterval > n_cycles if(iphase % n_pointsperscan == 0 && iphase / n_pointsperscan % 2 == 1) { inod = inod + 1; if(holdforload && inod % n_loadinterval == 0 && n_load == 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); runintostate = true; } } else { // keep shift if we come from a holdforload nod, otherwise reset if(!holdforload) { runintostate = false; } } // Update phase counter iphase = iphase + 1; } // Second pointing phase if(state[0] == 7) { // second nod position choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_seq,band,lo_freq,backendreadoutparms); for(int i2 = 1 .. n_load - 1) { HIFIFastChopOffIntegration(data_time,n_seq,band,lo_freq,choppars,rates); // Perform load calibration delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_seq,band,lo_freq,backendreadoutparms); } // Last cycle HIFIFastChopOffIntegration(data_time,n_seq,band,lo_freq,choppars,rates); // Load measurement if required - time included in pointing if(n_load > 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); } // Final point before nod // Special treatment for all cases where load has to be replaced by hold: if(iphase % n_pointsperscan == 0 && iphase / n_pointsperscan % 2 == 1) { inod = inod + 1; if(holdforload && inod % n_loadinterval == 0 && n_load == 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); runintostate = true; } } else { // keep shift if we come from a holdforload nod, otherwise reset if(!holdforload) { runintostate = false; } } // Update phase counter iphase = iphase + 1; } // Load nod if(state[0] == 9) { // Load nod delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); runintostate = false; } // Hold if(state[0] == 6) { // finished shift of instrument operations relative to pointing command runintostate = false; } // Final load if(state[0] == 5) { delay(readoutdead); if(final_load) { // Perform final load measurement LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); } runintostate = false; HIFICloseObs(); } } } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the observing mode procedure EngSScanDBS_commanding { string band = "4a"; // HIFI band double reffreq = 978300.0; // Reference characteristic LO frequency {double,double} eff_resolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} double[] freqgrid = [978053.7,978301.8,978381.1]; // Table of frequency points bool retunediplexer = false; // need for diplexer retuning bool retunelo = false; // whether to retune LO Vd2 with freq int data_time = 4; // chunk size int n_chop = 1; // Normal number of chop cycles per frequency and pointing int n_cycles = 1; // Number of half OFF-ON-ON-OFF cycles at one frequency int allsteps = 4; // Total number of frequency pointing periods int shiftlength = 10; // Shift of the loop start relative to the pointing int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,20,1,21,0]; // Timing of the observation from telescope }{ // Auxiliary variables // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time int tnodslew = telescopetimes[2]; // slew dead time between points // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] rates = dataparms{1}; int hkduration = HkReadoutTime(band,reffreq,backendreadoutparms,false); int readoutdead = SlowChopReadoutDelay(band,reffreq,backendreadoutparms); // recompute tune duration for initial load measurement int bigtunestep = duration(HIFIChangeLO(band,freqgrid[0],reffreq,retunediplexer,retunelo)); int n_loadinterval = n_cycles; // All commands with a duration possibly depending on the frequency // are taken at the reference frequency to guarantee synchonization // Declare auxiliary variables to be used in the loops int i_freq = 0; int i_phase = 0; // variables storing the configuration setting bool islong = false; bool isinvalid = true; //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; bool runintostate = false; while(state[0] >= 0) { if(runintostate) { state = next_state_no_check(); } else { state = next_state(); } if(state[0] == 1) { // Instrument Initialization: // Start with setup at reference frequency, go to grid in the next step // HIFIInitObs(); TuneHIFI(band,reffreq,hrs1,hrs2,wbs1{0},wbs2{0},"sscan_normal"); // First load measurement HIFISetHK("normal",false); SScanLoadMeasurement(band,reffreq,reffreq,true,eff_resolution{0},data_time,backendreadoutparms); delay(tinitslew - (time() - startobs) - bigtunestep + shiftlength - hkduration); // // Now switch to the actual frequency grid to be measured double runningfreq = freqgrid[i_freq]; HIFIChangeLO(band,runningfreq,reffreq,retunediplexer,retunelo); runintostate = true; } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 3) { // First nodding position // state counters runintostate = false; i_phase = (state[2] + 1) % 2; // intermediate nod cycles without retuning // (Check for match with first or last cycle index) if(n_cycles > 1 && state[2] % n_cycles != state[2] % 2) { delay(shiftlength); } // Actual integration HIFIConfigureSlowChopIntegration(data_time,n_chop,band,reffreq,backendreadoutparms); HIFISlowChopOnIntegration(data_time,n_chop,band,reffreq,rates); // Now we switch to the next frequency group or repeat the cycle if(state[2] % n_cycles == 0 && i_phase == 1) { // Big tuning step, but not at end of observation if(state[2] < allsteps) { i_freq = i_freq + 1; runningfreq = freqgrid[i_freq]; HIFIChangeLO(band,runningfreq,reffreq,retunediplexer,retunelo); runintostate = true; } } // Active Backend HK if we have a nod slew without calibration if(i_phase == 0 && state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } if(state[0] == 7) { // Second nodding position // state counters runintostate = false; i_phase = state[2] % 2; // intermediate nod cycles without retuning if(n_cycles > 1 && state[2] % n_cycles != (state[2] + 1) % 2) { delay(shiftlength); } // Actual integration HIFIConfigureSlowChopIntegration(data_time,n_chop,band,reffreq,backendreadoutparms); HIFISlowChopOffIntegration(data_time,n_chop,band,reffreq,rates); // Now we switch to the next frequency group or repeat the cycle if(state[2] % n_cycles == 0 && i_phase == 1) { // Big tuning step, but not at end of observation if(state[2] < allsteps) { i_freq = i_freq + 1; runningfreq = freqgrid[i_freq]; HIFIChangeLO(band,runningfreq,reffreq,retunediplexer,retunelo); runintostate = true; } } // Active Backend HK if we have a nod slew without calibration if(i_phase == 0 && state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } if(state[0] == 9) { // Load nod delay(readoutdead); SScanLoadMeasurement(band,runningfreq,reffreq,false,eff_resolution{0},data_time,backendreadoutparms); runintostate = false; } if(state[0] == 5) { // The instrument stops shiftlength before the telescope // but I have to wait to close the observation HIFICloseObs(); } } } {string,double,double}[] procedure HifiSScanModeLoadChopNoRefSequencerInit { string modeName = "load-freq"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_cycles = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles per frequency and pointing int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,redundancy,wbs1Used,wbs2Used,data_time); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; // Get frequency grid characteristic parameters {double,int,double} gfref = GetFReference(band,lo_freq,lo_freq_up); double reffreq = gfref{0}; int stdredun = gfref{1}; double stdstep = gfref{2}; int increment = stdredun / redundancy; // allowed group size double nocaliblen = GetFNoCalibLength(band,reffreq); int n_freq_point_guess = ifloor(nocaliblen / (stdstep * double(increment)) + 1.0); int n_freq_point_range = 1 - n_freq_point_guess; if(n_freq_point_range == 0) { n_freq_point_range = 1; } // inherit from fs-noref mode // spectral scans always use the full bandwidth for reference bool narrowReference = false; {string,double,double}[] retvalues = HifiPointProcLoadChopNoRefSequencerInit(naifid,ra,dec,band,reffreq,effResolution,narrowReference,hr1,hr2,wb1,wb2,data_time,n_cycles,load_interval,docommands); retvalues[1] = {"n_freq_point",double(n_freq_point_guess),double(n_freq_point_range)}; return retvalues; } //TM check when rescue mode: very difficult to identify as such. //Is based on the reception/non-reception of certain event packets procedure Mode_status_check_rescue { string context = "normal" in ["normal","failure"]; //indicate if this is a normal or failure arrival to rescue }{ mois_comment("Checking instrument status in rescue mode"); if(context == "failure") { mois_tmcheck("Check that the previous execution of either of the telecommands: Hifi_HIFI_force_bootdefault or Hifi_HIFI_force_bootpartition, has resulted in either of the following: no (5,1) packet was received, or a (5,4) packet was received."); } if(context == "normal") { mois_tmcheck("The ICU should be powered ON"); } } //////////////////////////////////////////////////////////////////////// // Radiometric noise from an OTF observation // This is still to be scaled by a factor 1.0/(B_fluct*T_A) double procedure OtfRadioNoise { double x = 0.02; // integration time (everything relative to the Allan time) double xr = 0.06; // reference integration time double d1 = 0.3; // time difference between last OFF and point double d2 = 0.3; // time difference between point and next OFF }{ if(x > 0.0 && xr > 0.0) { // Auxiliary parameters double l = (d2 + 0.5 * (xr + x)) / (d1 + d2 + xr + x); double ladd = 1.0 - 2.0 * l + 2.0 * l * l; // // finally the radiometric noise double y = 1.0 / x + ladd / xr; } else { // forbid x values <=0 y = 1.0E11 * (1.0 - x); } return y; } // Spectrometer configuration for fast chop, low level procedure int[] procedure Configure_Spectrometer_fast_chop_proc_fm { string band = "1a"; // HIFI band int integ_time = 8; //Total integation time of the two phases in seconds double chop_phase = 1.0 in [0.2,2.0]; // Chop phase length for fast chop string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4,wb5 string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //First derive backend setting codes as expected by VO's routine //Build up backend parameter tupple: {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = BackendSettings(band,0.0,hrs_mode,backend); // Readout parameters for HRS1,HRS2, WBS1,WBS2 //Compute data_time and n_switch using the wrapper int[] res = ConfigFastChop(integ_time,chop_phase,band,0.0,backendreadoutparms); int data_time = res[0]; int n_data = res[1]; int n_chop = res[2]; // Now call the spectroscopy setup: it is common to ILT and AOT CUS. // The deadtimes output is not used at ILT level. {{double,double,double},{int,int}} pars = ConfigSpectroscopyFastChop_IST(chop_phase,n_chop,n_data,band,0.0,backendreadoutparms); // int[] final_res = [res[0],res[1],pars{1}{0},pars{1}{1}]; return final_res; } // BLOCK : Functional Test No 2 (HRS Square S Internal Test) block HRS_functional_test_No_2_Square_s_block_fm HIFI 3621 { string band = "1a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int integ_time = 4; //Total integration time in sec. string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); //Fill in block parameter names for each mode - consequence of SPR-0198 string[] hrs_blocks_square_s_ultra = ["square_s_ultra","square_s_ultra","square_s_ultra","square_s_ultra","square_s_ultra","square_s_ultra","square_s_ultra","square_s_ultra"]; string[] hrs_blocks_square_s_wide = ["square_s_wide","square_s_wide","square_s_wide","square_s_wide","square_s_wide","square_s_wide","square_s_wide","square_s_wide"]; string[] hrs_blocks_square_s_low = ["square_s_hilonom","low","square_s_low","low_nominal","square_s_low_nom","low","square_s_low","high_nominal_low"]; string[] hrs_blocks_square_s_nom = ["square_s_hilonom","high_nominal","high_nominal","low_nominal","square_s_low_nom","high_nominal","high_nominal","high_nominal_low"]; string[] hrs_blocks_square_s_high = ["square_s_hilonom","high_nominal","high_nominal","high","high","high_nominal","high_nominal","high_nominal_low"]; // Configure spectroscopy Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); // // Configure LO and attenuators //============================= HRS_config_att_lo_fm(band,hrs_mode); // // Loops on the different configurations of the HRS //====================================== //Calls the 5 modes to be checked //Square_S_ultra Hifi_HIFI_Config_HRS_H_blocks($BBID,hrs_blocks_square_s_ultra[0],hrs_blocks_square_s_ultra[1],hrs_blocks_square_s_ultra[2],hrs_blocks_square_s_ultra[3],hrs_blocks_square_s_ultra[4],hrs_blocks_square_s_ultra[5],hrs_blocks_square_s_ultra[6],hrs_blocks_square_s_ultra[7]); //delay(1); Hifi_HIFI_Config_HRS_V_blocks($BBID,hrs_blocks_square_s_ultra[0],hrs_blocks_square_s_ultra[1],hrs_blocks_square_s_ultra[2],hrs_blocks_square_s_ultra[3],hrs_blocks_square_s_ultra[4],hrs_blocks_square_s_ultra[5],hrs_blocks_square_s_ultra[6],hrs_blocks_square_s_ultra[7]); delay(1); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // //Square_S_wide Hifi_HIFI_Config_HRS_H_blocks($BBID,hrs_blocks_square_s_wide[0],hrs_blocks_square_s_wide[1],hrs_blocks_square_s_wide[2],hrs_blocks_square_s_wide[3],hrs_blocks_square_s_wide[4],hrs_blocks_square_s_wide[5],hrs_blocks_square_s_wide[6],hrs_blocks_square_s_wide[7]); //delay(1); Hifi_HIFI_Config_HRS_V_blocks($BBID,hrs_blocks_square_s_wide[0],hrs_blocks_square_s_wide[1],hrs_blocks_square_s_wide[2],hrs_blocks_square_s_wide[3],hrs_blocks_square_s_wide[4],hrs_blocks_square_s_wide[5],hrs_blocks_square_s_wide[6],hrs_blocks_square_s_wide[7]); delay(1); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // //Square_S_low Hifi_HIFI_Config_HRS_H_blocks($BBID,hrs_blocks_square_s_low[0],hrs_blocks_square_s_low[1],hrs_blocks_square_s_low[2],hrs_blocks_square_s_low[3],hrs_blocks_square_s_low[4],hrs_blocks_square_s_low[5],hrs_blocks_square_s_low[6],hrs_blocks_square_s_low[7]); //delay(1); Hifi_HIFI_Config_HRS_V_blocks($BBID,hrs_blocks_square_s_low[0],hrs_blocks_square_s_low[1],hrs_blocks_square_s_low[2],hrs_blocks_square_s_low[3],hrs_blocks_square_s_low[4],hrs_blocks_square_s_low[5],hrs_blocks_square_s_low[6],hrs_blocks_square_s_low[7]); delay(1); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // //Square_S_nominal Hifi_HIFI_Config_HRS_H_blocks($BBID,hrs_blocks_square_s_nom[0],hrs_blocks_square_s_nom[1],hrs_blocks_square_s_nom[2],hrs_blocks_square_s_nom[3],hrs_blocks_square_s_nom[4],hrs_blocks_square_s_nom[5],hrs_blocks_square_s_nom[6],hrs_blocks_square_s_nom[7]); //delay(1); Hifi_HIFI_Config_HRS_V_blocks($BBID,hrs_blocks_square_s_nom[0],hrs_blocks_square_s_nom[1],hrs_blocks_square_s_nom[2],hrs_blocks_square_s_nom[3],hrs_blocks_square_s_nom[4],hrs_blocks_square_s_nom[5],hrs_blocks_square_s_nom[6],hrs_blocks_square_s_nom[7]); delay(1); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // //Square_S_high Hifi_HIFI_Config_HRS_H_blocks($BBID,hrs_blocks_square_s_high[0],hrs_blocks_square_s_high[1],hrs_blocks_square_s_high[2],hrs_blocks_square_s_high[3],hrs_blocks_square_s_high[4],hrs_blocks_square_s_high[5],hrs_blocks_square_s_high[6],hrs_blocks_square_s_high[7]); //delay(1); Hifi_HIFI_Config_HRS_V_blocks($BBID,hrs_blocks_square_s_high[0],hrs_blocks_square_s_high[1],hrs_blocks_square_s_high[2],hrs_blocks_square_s_high[3],hrs_blocks_square_s_high[4],hrs_blocks_square_s_high[5],hrs_blocks_square_s_high[6],hrs_blocks_square_s_high[7]); delay(1); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // //} } ///////////////////////////////////////////////////////////////// // Treatment of calibration parameters for spectral scans // // Get frequency steps from long calibration table ///////////////////////////////////////////////////////////////// // First get index range {int,int} procedure GetFIndex { string band = "4a"; // HIFI band double lo_freq1 = 978200.0 in [480000.0,1950000.0]; // LO frequency double lo_freq2 = 979600.0 in [480000.0,1950000.0]; // LO frequency }{ // first step: read master file string calibfile = slookup("frequencystep_masterfile",band,"tablefile"); int iindex1 = ibracket(calibfile,"stepnumber",lo_freq1); //reduce the upper frequency by epsilon to guarantee bracketing double eps = 0.1; int iindex2 = ibracket(calibfile,"stepnumber",lo_freq2 - eps); // Exception handling int tsize = table_size(calibfile); if(iindex1 == 0 || iindex1 == tsize - 2) { IError("LO frequency " + lo_freq1 + " not covered by available range!"); } if(iindex2 == 0 || iindex2 == tsize - 2) { IError("LO frequency " + lo_freq2 + " not covered by available range!"); } else { iindex2 = iindex2 + 1; } return {iindex1,iindex2}; } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the observing mode procedure DBS_commanding { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // chunk size int n_seq = 1; // Number of continuous chop cycles int n_load = 0; // additional load measurements in one pointing phase int n_loadinterval = 10; // number of nods before a load measurement bool end_load = false; // Need for load after each pointing phase bool final_load = false; // Need for final load measurement int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,20,1,21,0]; // Timing of the observation from telescope int loadlength = 21; // Load duration int shiftlength = 10; // Shift of the loop start relative to the pointing }{ // Auxiliary variables // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time int tnodslew = telescopetimes[2]; // slew dead time between points //////////////////////////////////////////////////////////////////////// // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // // Clustering is currently not implemented in MPS - switched off here int clustered = 0; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] rates = dataparms{1}; int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; bool runintostate = false; while(state[0] >= 0) { if(runintostate) { state = next_state_no_check(); } else { state = next_state(); } if(state[0] == 1) { // Initialization if(clustered != 1) { HIFIInitObs(); TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal"); } delay(tinitslew - (time() - startobs) - loadlength + shiftlength - hkduration); // First load measurement HIFISetHK("normal",false); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); if(shiftlength > 0) { runintostate = true; } else { runintostate = false; } } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 3) { // First nodding position HIFIConfigureSlowChopIntegration(data_time,n_seq,band,lo_freq,backendreadoutparms); // Loop for load cycles for(int i1 = 1 .. n_load) { HIFISlowChopOnIntegration(data_time,n_seq,band,lo_freq,rates); // Perform load calibration delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); HIFIConfigureSlowChopIntegration(data_time,n_seq,band,lo_freq,backendreadoutparms); } // Last cycle - no load HIFISlowChopOnIntegration(data_time,n_seq,band,lo_freq,rates); // Second phase in first nod position // occurs for even cycle numbers runintostate = false; if(state[2] % 2 == 0) { if(end_load) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); runintostate = true; } } else { // A nod slew follows - active HK if not used by load measurement if(state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } } if(state[0] == 7) { // second nod position HIFIConfigureSlowChopIntegration(data_time,n_seq,band,lo_freq,backendreadoutparms); // Loop for load cycles for(int i2 = 1 .. n_load) { // Use asymmetric scheme now to minimize setup uncertainties HIFISlowChopOffIntegration(data_time,n_seq,band,lo_freq,rates); // Perform load calibration delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); HIFIConfigureSlowChopIntegration(data_time,n_seq,band,lo_freq,backendreadoutparms); } // Last cycle - no load HIFISlowChopOffIntegration(data_time,n_seq,band,lo_freq,rates); // First phase in second nod position // occurs for odd cycle numbers runintostate = false; if(state[2] % 2 == 1) { if(end_load) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); runintostate = true; } } else { // A nod slew follows - active HK if not used by load measurement if(state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } } if(state[0] == 9) { // Load nod delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); runintostate = false; } if(state[0] == 5) { delay(readoutdead); if(final_load) { // Perform final load measurement // ( Does not occur if end_load is set) LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } runintostate = false; HIFICloseObs(); } } } // LCU configuration into NOMINAL mode, procedure // Uses best guess D2 voltage from confgilcu table // It then uses the new TM page dump TC from the MIB procedure LCU_config_nominal_w_TMPageDump_proc_fm { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency }{ //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlcutune = "name_configlcutune_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1_v = result[0]{1}; string curlim2_v = result[1]{1}; // result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); //Fetch best guess, and clip to blue max double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lo_freq); drain2_v = min(result[0]{0},drain2_bluemax); //Send command: expect that we have already switched to NOMINAL //We set D2 to best guess and wait some time to stabilize chain temperature HIFI_Configure_LCU_w_TMPageDump_block_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum,config_lo_delay); // } // WBS overall attenuator FM functional test, block block FT_WBS_att_overall_COMB_fm HIFI 3714 { string band = "1a"; // HIFI band int integ_time = 4; //Total integration time in sec. string laser_H = "Laser1" in ["Laser1","Laser2"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2"]; //WBS-V laser to be set ON string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); // //Set zero and comb on Hifi_HIFI_Single_cmd($BBID,"HWH_ZERO_ON"); Hifi_HIFI_Single_cmd($BBID,"HWV_ZERO_ON"); Hifi_HIFI_Single_cmd($BBID,"HWH_COMB_ON"); Hifi_HIFI_Single_cmd($BBID,"HWV_COMB_ON"); delay(2); // //Initial configuration: overall attenuators set to max., individual attenuators to 3 //H-Polarization // {double,string}[] result = ConfigurationReader("name_configwbs",["hwh_heater","hwh_latchup_s"],band,0.0); string hwh_laser1_s = "OFF"; string hwh_laser2_s = "OFF"; if(laser_H == "Laser1") { hwh_laser1_s = "ON"; } if(laser_H == "Laser2") { hwh_laser2_s = "ON"; } int hwh_heater = iround(result[0]{0}); string hwh_latchup_s = result[1]{1}; int hwh_att_band4 = 3; int hwh_att_band3 = 3; int hwh_att_band2 = 3; int hwh_att_band1 = 3; int hwh_att_in = 16; // result = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result[0]{0}); // //V-Polarization // result = ConfigurationReader("name_configwbs",["hwv_heater","hwv_latchup_s"],band,0.0); string hwv_laser1_s = "OFF"; string hwv_laser2_s = "OFF"; if(laser_V == "Laser1") { hwv_laser1_s = "ON"; } if(laser_V == "Laser2") { hwv_laser2_s = "ON"; } int hwv_heater = iround(result[0]{0}); string hwv_latchup_s = result[1]{1}; int hwv_att_band4 = 3; int hwv_att_band3 = 3; int hwv_att_band2 = 3; int hwv_att_band1 = 3; int hwv_att_in = 16; // //Loop on overall attenuators for(int i = 0 .. 15) { // Change the value of the main attenuator //======================================== hwh_att_in = hwh_att_in - 1; hwv_att_in = hwv_att_in - 1; // Set WBS //======== Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); delay(wbs_config_delay); //Wait for configuration to be applied // Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); delay(wbs_config_delay); //Wait for configuration to be applied // HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // } //Set att. to max. WBS_config_proc_max_att_w_laser_fm(band,laser_H,laser_V); // } {int,double,double,double,double,double} obs HifiSScanModeLoadChop { string modeName = "load-freq"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles per frequency and pointing int n_switch_off = 1 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles on OFF int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int n_cycles = 1 in [1,600]; // Number of half OFF-ON-ON-OFF cycles at one frequency int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode OpenMessages("HIFI Spectral Scan - Load Chop Ref",{data_time,data_time_off,0,n_switch_on,n_switch_off,0,0,n_freq_point,n_cycles,load_interval}); // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,redundancy,wbs1Used,wbs2Used,data_time); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; ////////////////////////////////////////////////////////////////////// // Call first part of the timing computer {{int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int},{int,double,double[],int[][],bool,double[],int,bool}} pre_timing = SScanLoadChop_pre_timing(band,lo_freq,lo_freq_up,redundancy,effResolution,hr1,hr2,wb1,wb2,data_time,data_time_off,n_switch_on,n_switch_off,n_freq_point,n_cycles,load_interval,docommands); // frequency parameters int groupnumber = pre_timing{1}{0}; double reffreq = pre_timing{1}{1}; double[] freqgrid = pre_timing{1}{2}; int[][] grouporder = pre_timing{1}{3}; bool retuning = pre_timing{1}{4}; double[] targetlevels = pre_timing{1}{5}; int nfreq_if = pre_timing{1}{6}; bool dsb = pre_timing{1}{7}; int n_total = groupnumber * n_cycles; ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {double,double} refPosition = {raoff,decoff}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,int,int,int,int,int,int} tpar = PositionSwitch_telescope(naifid,onPosition,refPosition,band,reffreq,pre_timing{0},n_total); // Dummy call to spacecraft command int[] telescopetimes = nodding_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},true); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int},double,double,double} post_timing = SScanDoubleChop_post_timing(pre_timing{0},telescopetimes,n_freq_point,groupnumber,n_cycles); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = PositionSwitch_telescope(naifid,onPosition,refPosition,band,reffreq,post_timing{1},n_total); // Call telescope command telescopetimes = nodding_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},true); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following // normal pre_timing values int on_inttime = post_timing{1}{0}; int off_inttime = post_timing{1}{1}; int n_loadinterval = post_timing{1}{7}; int n_long_on = post_timing{1}{8}; int n_long_off = post_timing{1}{9}; int shiftlength = post_timing{1}{5}; int initlength = post_timing{1}{14}; bool final_load = post_timing{1}{12}; // efficiency parameters double avnumchop_on = post_timing{2}; double avnumchop_off = post_timing{3}; double tscan = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { SScanLoadChop_commanding(band,reffreq,effResolution,hr1,hr2,wb1,wb2,n_freq_point,grouporder,freqgrid,retuning,targetlevels,data_time,data_time_off,n_switch_on,n_switch_off,n_long_on,n_long_off,n_cycles,n_total,n_loadinterval,final_load,startobs,telescopetimes,shiftlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double,double,double} tact = SScanDoubleChop_deadtimes("lchop",band,reffreq,hr1,hr2,wb1,wb2,n_freq_point,data_time,data_time_off,n_switch_on,n_switch_off,n_long_on,n_long_off,n_cycles,avnumchop_on,avnumchop_off,tscan); // // Call noise computer {double,double,double,double,double} noisevalues = SScanLoadChop_noisecomputer(band,reffreq,nfreq_if,dsb,effResolution,on_inttime,off_inttime,n_cycles,tscan,tact); // Evaluate performance SScanDoubleChop_performance(band,reffreq,nfreq_if,dsb,effResolution,noisevalues,timeTaken,n_freq_point,n_cycles,groupnumber * n_freq_point,avnumchop_on,avnumchop_off,false,tscan,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } //HIFI-COP-2.1-FTUnp obs HifiEng_FT_unpumped_COP { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band }{ //General parameters in use int integ_time = 4; string backend = "both"; string[] hrs_mode = ["wb1","wb1"]; //For bands 6 and 7, use wb8 if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { hrs_mode = ["wb8","wb8"]; } // // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(FT_unpumped_w_att_setting(band,hrs_mode,integ_time,backend)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution FT_unpumped_w_att_setting(band,hrs_mode,integ_time,backend); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } //General script to read TM1, TM2,etc, procedure //Will also clear the error flags procedure LCU_Read_TM_pages_proc_aot { }{ // //It will use one single MIB TC, and clear the error flag at end Hifi_HIFI_LCU_all_tuning_hk(); // delay(1); } // Compute the distance of two vectors in angular coordinates // General accurate equation double procedure AngularDistance { {double,double} vector1 = {0.0,0.0}; // First vector {double,double} vector2 = {0.2,0.2}; // Second vector }{ double pideg = 3.14159265 / 180.0; double l1 = vector1{0} * pideg; double b1 = vector1{1} * pideg; double l2 = vector2{0} * pideg; double b2 = vector2{1} * pideg; double dist = acos(sin(b1) * sin(b2) + cos(b1) * cos(b2) * cos(l1 - l2)) / pideg; return dist; } ////Obsolete block: use procedure instead. // Move chopper block Chopper_block_fm HIFI 3206 { double chopper = 0.0; }{ // Start_block() ; // chopper = Check_Chopper_Prime_Redundant(chopper); // Hifi_HIFI_CPR_Chopper_Rot ($BBID,chopper); // Hifi_HIFI_non_periodic_hk_FCU (); //To get sent voltage // delay (1) ; error("Obsolete block. Use Chopper_Rotation_proc_fm instead"); } //General script to clear error flags and set to nominal, block block LCU_enable_some_bands_block_fm HIFI 3770 { int hl_maskband = 16383; // bit description of bands to be enabled }{ // //switch to standby {double,string}[] result = ConfigurationReader("name_delays",["stdby_delay"],"0",0.0); int stdby_delay = iround(result[0]{0}); Hifi_HIFI_HL_Standby($BBID); delay(stdby_delay); //Enable all bands Hifi_HIFI_Conf_LCU_internal($BBID,hl_maskband,"RESET","RESET",256); //LSU_delta_f: 256 = 88mV // } // Switch HIFI from intermediate to standby I, mode // Assumed to have switched on and booted ICU when starting this mode // Will end in standby I mode, i.e. chopper, upconverter, and HBB OFF. mode HifiManCmd_HIFI_global_switch_on_ops { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red string chopper_loop = "OPEN" in ["OPEN","CLOSE"]; //chopper loop status }{ Mode_status_check_intermediate(); mois_comment("HIFI global switch ON: successively switch ON subsystems"); mois_tmcheck("The HIFI ICU must have been switched on and successfully booted before to execute this procedure."); StartMode_block_ops(); //Switch on units HIFI_global_switch_on_proc_ops(prime_or_redundant); //from moc_1.2: use proc instead of block //FPU start-up mois_step("Set HIFI FPU to band 0 with chopper loop " + chopper_loop); string chop_startup_prime_red = "chop_startup_cold_prime"; if(prime_or_redundant == "Red") { chop_startup_prime_red = "chop_startup_cold_red"; } {double,string}[] result = ConfigurationReader("name_chopper",[chop_startup_prime_red],"0",0.0); if(chopper_loop == "OPEN") { result = ConfigurationReader("name_chopper",["chop_startup_warm"],"0",0.0); } Init_MSA_ops("0",chopper_loop,0.0,result[0]{0},"ON",prime_or_redundant); StopMode_block_ops(); Mode_status_check_standby_I(chopper_loop,"up",prime_or_redundant); } // Load calibration measurement // // Most generic version for spectral scans with potentially different // frequencies for tuning and timing and retuning switch // // We might consider removing zero and comb as well - needs discussion !!! procedure SScanLoadMeasurement { string band = "4a"; // HIFI band (needed to estimate stabilization) double tuning_freq = 978200.0; // LO tuning frequency double lo_freq = 978200.0; // LO calibration frequency bool retunelo = true; // Whether LO retuning is enabled double deltanu = 1.0; // minimum effective resolution of the calibrated data int data_time = 4; // time between subsequent data readouts {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // Readout parameters for HRS1,HRS2, WBS1,WBS2 }{ // Initial computations {int,int,bool} calinit = HIFICalInit(band,lo_freq,deltanu,data_time); int used_datatime = calinit{0}; int n_inttime = calinit{1}; bool retuning = calinit{2} && retunelo; // Perform zero and comb measurement ZeroCombMeasurement(band,lo_freq,used_datatime,backendreadoutparms); // No we perform the actual hot-cold measurement // slow_chop_spectroscopy int danglingreadout = HIFI_Calibrate_hot_cold(band,lo_freq,used_datatime,n_inttime,backendreadoutparms,false); // Retune and another load if we are in HEB bands if(retuning) { // we have to wait for readout delay(danglingreadout); // Another LO vector scan at the same frequency for a stable HEB operation HIFITuneFreq(band,tuning_freq,false,""); danglingreadout = HIFI_Calibrate_hot_cold(band,lo_freq,used_datatime,n_inttime,backendreadoutparms,false); } } //////////////////////////////////// // DBS raster observing mode - Engineering version with half throw // // Return time and noise levels {int,double,double,double,double,double} obs HifiEngHalfThrowDBSRaster { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source {double,double} lineDistance = {0.0050,0.0050}; // Distance between subsequent rows int nlines = 1 in [1,100]; // Number of rows in the map double stepsize = 0.0050 in [5.5556E-4,0.13333]; // Distance between subsequent points in the raster line int npoints = 10 in [2,100]; // Number of points per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_switch_on = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Engineering - DBS Raster Map halfThrow slowChop",{data_time,0,0,n_switch_on,0,0,n_pointsperscan,0,n_cycles,load_interval}); // Call first part of the timing computer {int,int,int,int,int,int,int,int,int,int,int,int,int} pre_timing = DBSRaster_pre_timing(nlines,npoints,band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_switch_on,n_pointsperscan,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; // Check for NoddingInRaster or NoddingOfRaster int scansize = pre_timing{10}; if(scansize > 1) { {int,int,int,string,int,double,double,bool,double,double,double,int,int,double,double,int,int,double,double,int,int,int,int,int} tmpar = DBSMultiRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"half",pre_timing,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = nodding_of_raster_pointing(false,tmpar{0},tmpar{1},tmpar{2},tmpar{3},tmpar{4},tmpar{5},tmpar{6},tmpar{7},tmpar{8},tmpar{9},tmpar{10},tmpar{11},tmpar{12},tmpar{13},tmpar{14},tmpar{15},tmpar{16},tmpar{17},tmpar{18},tmpar{19},tmpar{20},tmpar{21},tmpar{22},tmpar{23}); } else { {int,int,int,string,int,double,double,bool,double,double,double,int,int,double,double,int,int,int,double,double,int,int,int,double,double,int,int,int,int} tpar = DBSRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"half",pre_timing,n_cycles); telescopetimes = nodding_raster_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23},tpar{24},tpar{25},tpar{26},tpar{27},tpar{28}); } ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,int},bool,double,double} post_timing = DBSRaster_post_timing(pre_timing,telescopetimes,nlines,npoints,n_switch_on,n_cycles,load_interval,false); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command if(scansize > 1) { tmpar = DBSMultiRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"half",post_timing{1},n_cycles); // Call telescope command telescopetimes = nodding_of_raster_pointing(true,tmpar{0},tmpar{1},tmpar{2},tmpar{3},tmpar{4},tmpar{5},tmpar{6},tmpar{7},tmpar{8},tmpar{9},tmpar{10},tmpar{11},tmpar{12},tmpar{13},tmpar{14},tmpar{15},tmpar{16},tmpar{17},tmpar{18},tmpar{19},tmpar{20},tmpar{21},tmpar{22},tmpar{23}); } else { tpar = DBSRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"half",post_timing{1},n_cycles); telescopetimes = nodding_raster_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23},tpar{24},tpar{25},tpar{26},tpar{27},tpar{28}); } // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{3}; int n_load = post_timing{1}{6}; int n_loadinterval = post_timing{1}{7}; int n_seq = post_timing{1}{8}; int initlength = post_timing{1}{11}; int dangling = post_timing{1}{12}; bool final_load = post_timing{2}; double tscan = post_timing{3}; double tdead = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { HalfDBSRaster_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_seq,n_cycles,scansize,n_loadinterval,n_load,final_load,startobs,telescopetimes,loadlength,false); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double} tact = DBSRaster_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_seq,n_load,scansize,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = DBS_noisecomputer(band,lo_freq,effResolution,continuumDetection,oneGHzReference,n_cycles,tscan,tact); // Evaluate performance DBSRaster_performance(band,lo_freq,effResolution,noisevalues,timeTaken,nlines,npoints,n_cycles,n_seq * imax(n_load,1),tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } //Fast chopped hotcold, block block Hot_cold_fastchop_fm HIFI 3225 { string band = "1a"; int integ_time = 8; //Total integration time for delay computation string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4,etc string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast int n_wbs1 = 20; int n_hrs_trans = 1; }{ //Start_block(); //Rotate chopper: assume we come from M3: no rotation as this is done in the fastchop_spectro //Chopper_Rotation_proc_fm(band,"chop_M3_ang","chop_hot_ang"); //Fetch respective chopper angles {double,string}[] result = ConfigurationReader("name_confilfpu",["chop_hot","chop_cold"],band,0.0); double chop_hot = result[0]{0}; double chop_cold = result[1]{0}; // //Compute data-rate double[] rates = ILT_datarate_proc_fm(band,backend,"fastchop",integ_time); //Take spectrum // set data rates non_ess_hk_data_rate(rates[2] / 1024.0); data_rate(rates[0] / 1024.0); // HIFI_Spectr_fast_chop_proc_fm(chop_hot,chop_cold,n_wbs1,n_hrs_trans); Apply_Fast_Chop_delay(integ_time,1,band,backend); // reset data rates non_ess_hk_data_rate(rates[1] / 1024.0); data_rate(0.0); } // Preliminary LO scan with HRS 0-lag measured, procedure procedure Proc_LO_scan_w_HRS_lag { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double[] lo_freq_input = [500.0,500.15,0.02]; //Start, end and step lo_freq for the LO scan string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int integ_time = 4; //Total (co-added) integration time of a phase in sec. string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Tune at the first frequency LO_tuning_block_fm(band,lo_freq_input[0]); // Chopper_Rotation_block_fm(band,"chop_M3_ang","chop_cold_ang"); //Look at CBB // //WBS calibration and backend tuning if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band); WBS_tune_proc_fm(band); } if(backend == "hrs" || backend == "both" || backend == "hrsFast") { HRS_tune_block_fm(band); } // //Configure spectrometers integration int[] res = Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); // //Loop on LO frequencies. It is assumed that the LO is tuned at the initial frequency double lo_freq = lo_freq_input[0]; while(lo_freq <= lo_freq_input[1]) { //Set synthesizer to new LO freq. LCU_config_nominal_noretune_block_fm(band,lo_freq,lo_freq_input[0]); // //For bands with diplexer, update diplexer setting double band_nb = GetBandCode(band); if(band_nb <= 2.0 || band_nb == 5.0) { double diplex_H = 0.0; //For bands 1, 2 and 5 double diplex_V = 0.0; } else { double[] result_dip = Get_Diplexer_setting(band,lo_freq); diplex_H = result_dip[0]; diplex_V = result_dip[1]; Set_Diplexer_current_block_fm(diplex_H,diplex_V); } //Take total power spectroscopy Spectro_total_power_block_fm(band,res,backend); //Increase lo_freq lo_freq = lo_freq + lo_freq_input[2]; } } ///////////////////////////////////////////////////////////////// // Redundancy enhancement at the edges // Return increased redundancy and length of application {int,double,double} procedure GetEdgeEnhance { int redundancy = 4; // Standard redundancy of the scan string band = "4a"; // HIFI band }{ double[] edge = SpectralScanReader("fscanedge",["bandwidth","edgelength","edgeredun"],band,redundancy); int newredun = iround(edge[2]); return {newredun,edge[1],edge[0]}; } //////////////////////////////////// // OTF frequency switch observing mode without baseline calibration // // Return time and noise levels {int,double,double,double,double,double} obs HifiMappingProcFSwitchOTFNoRef { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source {double,double} lineDistance = {0.0050,0.0050}; // Distance between subsequent rows int nlines = 1 in [1,240]; // Number of rows in the map double stepsize = 0.0050 in [0.0,0.13333]; // Distance between subsequent points in the OTF line int npoints = 10 in [1,720]; // Number of data dumps per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // chunk size given by the data rates and optimum speed int n_switch_on = 1 in [1,1800]; // Supersamplingfactor int n_cycles = 1 in [1,1200]; // Number of map coverages int load_interval = 1800 in [10,7200]; // load period defines number of lines between two loads bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Mapping - OTF Map Frequency Switch noRef",{data_time,0,0,n_switch_on,0,0,0,0,n_cycles,load_interval}); // Auxiliary routine for API parameter correction {double,double,int} mapused = ValidMapSize(band,lo_freq,lineDistance,nlines,stepsize,npoints,2 * data_time * n_switch_on); double line_used = mapused{0}; double scanvelocity = mapused{1}; int npoints_used = mapused{2}; // Call first part of the timing computer {int,int,int,int,bool,int,int} pre_timing = OTFFSwitchNoRef_pre_timing(nlines,npoints_used,band,lo_freq,freq_throw,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_switch_on,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,double,double,int,int,int} tpar = OTFDoubleChopNoRef_telescope(naifid,onPosition,lineDistance,nlines,line_used,scanvelocity,band,lo_freq,n_cycles,pre_timing); // Dummy call to spacecraft command int[] telescopetimes = line_scan_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17}); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,bool,int,int},double,double} post_timing = OTFDoubleChopNoRef_post_timing(pre_timing,telescopetimes,nlines,data_time,n_cycles); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = OTFDoubleChopNoRef_telescope(naifid,onPosition,lineDistance,nlines,line_used,scanvelocity,band,lo_freq,n_cycles,post_timing{1}); // Call telescope command telescopetimes = line_scan_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17}); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{0}; bool end_load_on = post_timing{1}{4}; int n_loadinterval = post_timing{1}{2}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { OTFFSwitchNoRef_commanding(band,lo_freq,freq_throw,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,npoints_used * n_switch_on,n_loadinterval,nlines * n_cycles,end_load_on,startobs,telescopetimes,loadlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double} tact = SingleChop_deadtimes("fs",band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,npoints_used * n_switch_on); double tscan = 2.0 * (tact{1} + tact{2}); double tdead = 2.0 * tact{2}; // // Call noise computer {double,double,double,double,double} noisevalues = FSwitchNoRef_noisecomputer(band,lo_freq,effResolution,oneGHzReference,n_switch_on * n_cycles,tscan,tdead); // Evaluate performance OTFDoubleChopNoRef_performance(band,lo_freq,effResolution,noisevalues,timeTaken,nlines,npoints_used,n_switch_on * n_cycles,true,tscan,tdead); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } //////////////////////////////////// // OTF frequency switch observing mode // {string,double,double}[] procedure HifiMappingProcFSwitchOTFSequencerInit { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source double raoff = 0.0; // RA coordinate of the OFF position double decoff = 0.0; // DEC coordinate of the OFF position {double,double} lineDistance = {0.0050,0.0050}; // Distance between subsequent rows int nlines = 1 in [1,240]; // Number of rows in the map double stepsize = 0.0050 in [0.0,0.13333]; // Distance between subsequent points in the OTF line int npoints = 10 in [1,720]; // Number of data dumps per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // chunk size given by the data rates and optimum speed int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 1 in [1,1800]; // Supersamplingfactor int n_switch_off = 3 in [1,3600]; // Number of data dumps for the OFF integration time int n_linesperscan = 1 in [1,32]; // Number of lines between two OFFs int n_cycles = 1 in [1,1200]; // Number of map coverages int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode // limit on data rate {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // limits from noise section {double,double,double,double} phaselengths = FSwitchPhaseLengths(band,lo_freq,effResolution,oneGHzReference); // Compute derived quantities // Main loop int main_phase = iceil(phaselengths{0}); // How many lines could we do at most? int n_linesperscan_guess = main_phase / (2 * datalimit) + 1; n_linesperscan_guess = imax(n_linesperscan_guess * n_linesperscan_guess / npoints,1); // restrict the scan size if(nlines == 1 && n_linesperscan_guess > 1) { n_linesperscan_guess = 2; } else { n_linesperscan_guess = IMultiple(n_linesperscan_guess,nlines); n_linesperscan_guess = imin(n_linesperscan_guess,nlines); } int n_linesperscan_range = 1 - n_linesperscan_guess; if(n_linesperscan_range == 0) { n_linesperscan_range = 1; } double n_pointsperscan = double(n_linesperscan * npoints); // Compute back int int_time_guess = main_phase / iceil(sqrt(n_pointsperscan)); int data_time_guess = imin(imax(iceil(phaselengths{1}),datalimit),20); int n_switch_on_guess = imax(int_time_guess / (2 * data_time_guess),1); int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } data_time_guess = imax(imin(5,int_time_guess / (2 * n_switch_on_guess)),datalimit); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } // OFF phase int data_time_off_guess = imin(imax(iceil(phaselengths{2}),datalimit),20); int data_time_off_range = datalimit - data_time_off_guess; if(data_time_off_range == 0) { data_time_off_range = 1; } int n_switch_off_guess = imax(iceil(double(data_time_guess * n_switch_on_guess) * 0.67 * sqrt(n_pointsperscan) / (double(data_time_off_guess) * sqrt(phaselengths{3} / effResolution{1}))),1); int n_switch_off_range = 1 - n_switch_off_guess; if(n_switch_off_range == 0) { n_switch_off_range = 1; } // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"data_time_off",double(data_time_off_guess),double(data_time_off_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)},{"n_switch_off",double(n_switch_off_guess),double(n_switch_off_range)},{"n_linesperscan",double(n_linesperscan_guess),double(n_linesperscan_range)}]; return retvalues; } //PDU switch off of a S/S, procedure procedure PDU_switch_off_proc_ops { string subsystem = "ICU_Prime" in ["ICU_Prime","ICU_Red","LO_Prime","LO_Red","WBS_H","WBS_V","HRS_H","HRS_V"]; }{ ////HifiIltEgse_PDU_switch_off($BBID,subsystem); //The TEI command: WILL BE DONE BY SPACON mois_spacon("Please power OFF Sub-System " + subsystem); //delay(1); } ////////////////////////////////////////////////////////// // Stand-by configuration //////////////////////////// //Set LCU back to standby status without setting any particular LO band, block //LCU is only set to standby if the band has been switched off block LCU_standby_block_fm HIFI 3629 { }{ // //Start_block(); {double,string}[] result = ConfigurationReader("name_delays",["stdby_delay"],"0",0.0); int stdby_delay = iround(result[0]{0}); // //Set in standby mode Hifi_HIFI_HL_Standby($BBID); delay(stdby_delay); } // Laser stabilization time for WBS, procedure procedure FT_WBS_stabilization_time_proc_fm { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band int n = 100; //Number of load pairs to be measured string laser_H = "Laser1" in ["Laser1","Laser2"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2"]; //WBS-V laser to be set ON int integ_time = 4; //Total integration time in sec. to be set at end of test string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ // //Configure WBS WBS_config_w_laser_block_fm(band,laser_H,laser_V); //Attenuator Tune WBS_tune_proc_fm(band); //Integration Stability_backend_fm(band,n,integ_time,backend,["wb1","wb1"]); //Configure spectrometers integration back to default Configure_Spectrometer_proc_fm(band,integ_time,["wb1","wb1"],backend); //Do zero and COMB WBS_calib_fm(band); //Set att. to max. WBS_config_max_att_w_laser_block_fm(band,laser_H,laser_V); // } //Get true chopper angles for a chopped observation {bool,double,double} procedure GetChopVoltages { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz string chop1string = "chop_M3left"; // first chopper position string chop2string = "chop_M3right"; // second chopper position }{ // get chopper angles for the two positions in prime configuration {double,string}[] result = ConfigurationReader("name_confilfpu",[chop1string,chop2string],band,lo_freq); double chop1 = result[0]{0}; double chop2 = result[1]{0}; //Check prime or redundant status {double,string}[] result_d = ConfigurationReader("name_chopper",["prime_or_redundant","p_to_r_coeff_0","p_to_r_coeff_1","p_to_r_coeff_2","prime_endstop_min","prime_endstop_max","red_endstop_min","red_endstop_max"],band,lo_freq); bool isPrime = result_d[0]{1} == "prime"; if(isPrime) { // check the chopper angle is within the ranges double endstop_min = result_d[4]{0}; double endstop_max = result_d[5]{0}; if(chop1 > endstop_max || chop1 < endstop_min) { IError("The chopper voltage (requested is " + chop1 + " V) in prime" + " mode has to be between " + endstop_min + " and " + endstop_max + " V."); } if(chop2 > endstop_max || chop2 < endstop_min) { IError("The chopper voltage (requested is " + chop2 + " V) in prime" + " mode has to be between " + endstop_min + " and " + endstop_max + " V."); } } else { //Change chopper voltage if necessary chop1 = result_d[3]{0} * pow(chop1,2.0) + result_d[2]{0} * chop1 + result_d[1]{0}; chop2 = result_d[3]{0} * pow(chop2,2.0) + result_d[2]{0} * chop2 + result_d[1]{0}; //Now check the chopper angle is within the ranges endstop_min = result_d[6]{0}; endstop_max = result_d[7]{0}; if(chop1 > endstop_max || chop1 < endstop_min) { IError("The chopper voltage (requested is " + chop1 + " V) in redundant" + " mode has to be between " + endstop_min + " and " + endstop_max + " V."); } if(chop2 > endstop_max || chop2 < endstop_min) { IError("The chopper voltage (requested is " + chop2 + " V) in redundant" + " mode has to be between " + endstop_min + " and " + endstop_max + " V."); } } return {isPrime,chop1,chop2}; } //Configure backends procedure ConfigureBackend { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} }{ //HRS configuration: //Internal LO relative to IF centre double if_centre = 6.0; // //Resolution mode string hrs_mode_h = "hr"; double[] hrsH_LO = [if_centre + hrs1{2}[0] / 1000.0,if_centre + hrs1{2}[1] / 1000.0,if_centre + hrs1{2}[2] / 1000.0,if_centre + hrs1{2}[3] / 1000.0]; if(hrs1{0}) { // Resolution strings and LO assignment if(hrs1{1} == 1) { // medium resolution hrs_mode_h = "mr"; hrsH_LO = [if_centre + hrs1{2}[0] / 1000.0,if_centre + hrs1{2}[2] / 1000.0,if_centre + hrs1{2}[3] / 1000.0,if_centre + hrs1{2}[1] / 1000.0]; } if(hrs1{1} == 2) { // low resolution hrs_mode_h = "lr"; hrsH_LO = [if_centre + hrs1{2}[0] / 1000.0,if_centre + hrs1{2}[3] / 1000.0,if_centre + hrs1{2}[1] / 1000.0,if_centre + hrs1{2}[2] / 1000.0]; } if(hrs1{1} == 3) { // wide-band resolution hrs_mode_h = "wb"; } } string hrs_mode_v = "hr"; double[] hrsV_LO = [if_centre + hrs2{2}[0] / 1000.0,if_centre + hrs2{2}[1] / 1000.0,if_centre + hrs2{2}[2] / 1000.0,if_centre + hrs2{2}[3] / 1000.0]; if(hrs2{0}) { // Resolution strings and LO assignment if(hrs2{1} == 1) { // medium resolution hrs_mode_v = "mr"; hrsV_LO = [if_centre + hrs2{2}[0] / 1000.0,if_centre + hrs2{2}[2] / 1000.0,if_centre + hrs2{2}[3] / 1000.0,if_centre + hrs2{2}[1] / 1000.0]; } if(hrs2{1} == 2) { // low resolution hrs_mode_v = "lr"; hrsV_LO = [if_centre + hrs2{2}[0] / 1000.0,if_centre + hrs2{2}[3] / 1000.0,if_centre + hrs2{2}[1] / 1000.0,if_centre + hrs2{2}[2] / 1000.0]; } if(hrs2{1} == 3) { // wide-band resolution hrs_mode_v = "wb"; } } // // Apply string[] hrs_mode = [hrs_mode_h,hrs_mode_v]; HRS_config_resol_block_aot(band,hrs_mode); HRS_config_att_lo_block_aot(band,hrs_mode,hrsH_LO,hrsV_LO); // //WBS configuration: set all attenuators to max. Maybe superfluous WBS_config_block_aot(band); // } // Zero measurement with nominal selection // This should turn into a single command when SCR 743 is solved int block WBS_Full_Zero HIFI 6003 { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency int data_time = 4; // time between subsequent data readouts {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // Readout parameters for HRS1,HRS2, WBS1,WBS2 }{ // data rate and read-out time {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int readout = dataparms{0}; // work-around for SCR 607 // put the zero switch on Hifi_HIFI_Single_cmd($BBID,"HWH_ZERO_ON"); Hifi_HIFI_Single_cmd($BBID,"HWV_ZERO_ON"); // Unfortunately we loose 1s here due to the additional commands delay(1); // send the configure spectroscopy command to configure the measurement // returned dead times not needed here ConfigureSpectroscopy(data_time,1,"tp",band,lo_freq,backendreadoutparms); // set data rates non_ess_hk_data_rate(dataparms{1}[2] / 1024.0); data_rate(dataparms{1}[0] / 1024.0); // execute a total power measurement with the zero switch on Hifi_HIFI_Spectr_total_power($BBID); delay(data_time); // reset data rates non_ess_hk_data_rate(dataparms{1}[1] / 1024.0); data_rate(0.0); // put zero off Hifi_HIFI_Single_cmd($BBID,"HWH_ZERO_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWV_ZERO_OFF"); // We loose again 1s here due to the additional commands delay(1); // This is reduced due to the SCR 607 overhead in the buidling block readout = readout - 1; return readout; } ///////////////////////////////////////////////////////////////// // Procedure to translate levels into strings string[] procedure TargetNames { string band = "4a"; // HIFI band double lo_freq = 978200.0; // reference LO frequency in MHz bool retuning = false; // need for WBS retuning double[] targetlevels = [1.0,1.0,1.0]; // WBS target levels }{ // Get target limits double[] limits = CalibrationReader("attenuator_levels",["sscan_max","sscan_min","sscan_high","sscan_normal","sscan_low"],band,lo_freq); // Criteria for the table setup double halfwidth = limits[2] - limits[4]; // Output field string[] target = []; int nfreq = length(targetlevels); // Check for retuning needs if(retuning) { // Construct table of actual target levels from differences double oldtarget = targetlevels[0]; double step = 0.0; int oldindex = 0; target[0] = ""; for(int jjj = 1 .. nfreq - 1) { target[jjj] = ""; step = targetlevels[jjj] - oldtarget; if(abs(step) > halfwidth) { if(step > 0.0) { target[oldindex] = "sscan_low"; } else { target[oldindex] = "sscan_high"; } oldtarget = targetlevels[jjj]; oldindex = jjj; } // Final tuning if(step > 0.0) { target[oldindex] = "sscan_low"; } else { target[oldindex] = "sscan_high"; } } } else { // No retuning needed // search again for minimum - use for target level double absmin = arraymin(targetlevels); if(limits[0] - absmin < halfwidth) { target[0] = "sscan_normal"; } else { if(targetlevels[0] > limits[3]) { if(targetlevels[0] > limits[2]) { target[0] = "sscan_max"; } else { target[0] = "sscan_high"; } } else { if(targetlevels[0] < limits[4]) { target[0] = "sscan_min"; } else { target[0] = "sscan_low"; } } } // Fill the table with empty values for(int jjjj = 1 .. nfreq - 1) { target[jjjj] = ""; } } // table with either a single entry or entries at tuning points return target; } //HIFI-COP-3-Dipscan obs HifiEng_Dipscan_calibration_COP { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Diplexer_survey_proc_COP(band)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Diplexer_survey_proc_COP(band); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } // Single IV curve procedure: always called from a block ! procedure IVcurve { string band = "1a"; double bias_min = -6.0; double bias_max = 6.0; int step_count = 131; double magnet_current_h = 15.0; // magnet current, set first (mA) double magnet_current_v = 15.0; // magnet current, set first (mA) double bias_h = 2.2; // bias voltage, set before exit (mV) double bias_v = 2.2; // bias voltage, set before exit (mV) }{ //In case of band 6 or 7, set first to 4mV if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { {double,string}[] result = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,0.0); //First go to 4mV Mixerbias(result[0]{0},result[1]{0}); } // int duration_ivcurve = 0; double step_duration = 0.1; int max_per_command = 40; int steps = 0; int steps_done = 0; double step = Stepsize(bias_min,bias_max,step_count,"hifi_HIF_mxbias_step_V"); double margin = Stepmargin(bias_min,bias_max,"hifi_HIF_mxbias_step_V"); int steps_wanted = 1 + iceil((bias_max - bias_min) / step); // force the last portion to less than max_per_command: if(max_per_command * (steps_wanted / max_per_command) == steps_wanted) { steps_wanted = steps_wanted - 1; } double bias_start = bias_min; while(steps_done < steps_wanted) { steps = steps_wanted - steps_done; if(steps > max_per_command) { steps = max_per_command; } bias_start = bias_min + double(steps_done) * step; Hifi_HIFI_FCU_parameter_scan($BBID,steps,1,step_duration,bias_start,bias_start,step + margin,magnet_current_h,magnet_current_v,0.0); duration_ivcurve = iceil(double(steps) * step_duration); delay(duration_ivcurve + 2); steps_done = steps_done + steps; } //Set back to value on exit //In case of band 6 or 7, set first to 4mV if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { result = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,0.0); //First go to 4mV Mixerbias(result[0]{0},result[1]{0}); } // Mixerbias(bias_h,bias_v); } //Check D2 is within the BLUE ranges bool procedure Check_D2_vs_BLUE_proc_fm { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency double drain2_v = 1.6; //D2_V to compare to blue table }{ bool go_ahead = true; //Fetch index string name_confindex = "name_confindex_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_confindex = "name_confindex_b"; } {double,string}[] result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Fetch D2 blue min and max result = ConfigurationReader("name_configlcublue",["blmn1a","blmx1a","blmn1b","blmx1b","blmn2a","blmx2a","blmn2b","blmx2b","blmn3a","blmx3a","blmn3b","blmx3b","blmn4a","blmx4a","blmn4b","blmx4b","blmn5a","blmx5a","blmn5b","blmx5b","blmn6a","blmx6a","blmn6b","blmx6b","blmn7a","blmx7a","blmn7b","blmx7b"],band,double(freq_nx)); // if(band == "1a" && (drain2_v < result[0]{0} || drain2_v > result[1]{0})) { go_ahead = false; } if(band == "1b" && (drain2_v < result[2]{0} || drain2_v > result[3]{0})) { go_ahead = false; } if(band == "2a" && (drain2_v < result[4]{0} || drain2_v > result[5]{0})) { go_ahead = false; } if(band == "2b" && (drain2_v < result[6]{0} || drain2_v > result[7]{0})) { go_ahead = false; } if(band == "3a" && (drain2_v < result[8]{0} || drain2_v > result[9]{0})) { go_ahead = false; } if(band == "3b" && (drain2_v < result[10]{0} || drain2_v > result[11]{0})) { go_ahead = false; } if(band == "4a" && (drain2_v < result[12]{0} || drain2_v > result[13]{0})) { go_ahead = false; } if(band == "4b" && (drain2_v < result[14]{0} || drain2_v > result[15]{0})) { go_ahead = false; } if(band == "5a" && (drain2_v < result[16]{0} || drain2_v > result[17]{0})) { go_ahead = false; } if(band == "5b" && (drain2_v < result[18]{0} || drain2_v > result[19]{0})) { go_ahead = false; } if(band == "6a" && (drain2_v < result[20]{0} || drain2_v > result[21]{0})) { go_ahead = false; } if(band == "6b" && (drain2_v < result[22]{0} || drain2_v > result[23]{0})) { go_ahead = false; } if(band == "7a" && (drain2_v < result[24]{0} || drain2_v > result[25]{0})) { go_ahead = false; } if(band == "7b" && (drain2_v < result[26]{0} || drain2_v > result[27]{0})) { go_ahead = false; } if(go_ahead == false) { //debug_print("go_ahead is: " + go_ahead); error("D2 voltage not within allowed range for band " + band); } return go_ahead; } //Reduced version: IVC //HIFI-COP-7.2-LO_FT procedure LO_FT_IVC_COP_proc_ops { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ //General parameters in use string multiplier = "ALL"; int operation_delay = 0; // double[] cresult_d = CalibrationReader("name_keyfreq",["keyfreq"],band,0.0); double lo_freq = cresult_d[0]; //applies to cold LO // Measure_LCU_IV_proc_fm(band,multiplier,operation_delay); // } //Set HIFI to standby II in dissipation mode //It will keep LO band xx switched on with safe settings - see SCR- obs HifiEngSetIntoStandby_II_Dissipate { }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(HifiIntoStandby_II_Dissipate()); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // ON integration HifiIntoStandby_II_Dissipate(); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } //////////////////////////////////// // Load chop mode without baseline calibration // // The implementation now assumes that the corresponding Herschel // pseudo-pointing mode will be available // {int,double,double,double,double,double} obs HifiPointProcLoadChopNoRef { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rates int n_cycles = 2 in [1,3600]; // number of half load-sky-sky-load cycles on ON int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Single Point - Load Chop noRef",{data_time,0,0,0,0,0,0,0,n_cycles,load_interval}); // Call first part of the timing computer {int,int,int,int,int,int,bool,int,int} pre_timing_f = LoadChopNoRef_pre_timing(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_cycles,load_interval,docommands); // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,double,double,int} tpar_f = Fine_telescope(naifid,onPosition,band,lo_freq,pre_timing_f); // Dummy call to spacecraft command int[] telescopetimes = basic_fine_pointing(false,tpar_f{0},tpar_f{1},tpar_f{2},tpar_f{3},tpar_f{4},tpar_f{5},tpar_f{6},tpar_f{7},tpar_f{8},tpar_f{9}); // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,bool,int,int},double,double} post_timing_f = SingleChopNoRef_post_timing(pre_timing_f,telescopetimes); // Now the actual observation starts // Prepare telescope command tpar_f = Fine_telescope(naifid,onPosition,band,lo_freq,post_timing_f{1}); // Call telescope command telescopetimes = basic_fine_pointing(true,tpar_f{0},tpar_f{1},tpar_f{2},tpar_f{3},tpar_f{4},tpar_f{5},tpar_f{6},tpar_f{7},tpar_f{8},tpar_f{9}); // Consistency check int totaltime = post_timing_f{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following ////////////////////////////////////////////////////////////////////// // standard parameters for fine pointing int loadlength = post_timing_f{1}{2}; int n_per_on = post_timing_f{1}{4}; int n_load_on = post_timing_f{1}{5}; bool end_load_on = post_timing_f{1}{6}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands ////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { LoadChopNoRef_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_per_on,n_load_on,end_load_on,startobs,telescopetimes,loadlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // There are no telescope dead times involved in this mode {double,double,double} tact = SingleChop_deadtimes("lchop",band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_per_on); double tscan = 2.0 * (tact{1} + tact{2}); double tdead = 2.0 * tact{2}; // // Call noise computer {double,double,double,double,double} noisevalues = PositionSwitch_noisecomputer(band,lo_freq,effResolution,oneGHzReference,n_per_on * (n_load_on + 1),tscan,tdead); // Evaluate performance SingleChopNoRef_performance(band,lo_freq,effResolution,noisevalues,timeTaken,n_per_on * (n_load_on + 1),false,tscan,tdead); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } {int,double,double,double,double,double} obs HifiMappingModeOTF { string modeName = "fly"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,5]; // chunk size given by the data rates and optimum speed int n_int_on = 1 in [1,1800]; // Supersamplingfactor int n_linesperscan = 1 in [1,32]; // Number of lines between two OFFs int n_switch_off = 3 in [1,3600]; // Number of data dumps for the OFF integration time int n_cycles = 1 in [1,1200]; // Number of map coverages int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode OpenMessages("HIFI Mapping - OTF Map Position Switch",{data_time,0,n_int_on,0,n_switch_off,n_linesperscan,0,0,n_cycles,load_interval}); // Auxiliary routine for API parameter correction {double,double,int} mapused = ValidMapSize(band,lo_freq,lineDistance,nlines,stepsize,npoints,data_time * n_int_on); double line_used = mapused{0}; double scanvelocity = mapused{1}; int npoints_used = mapused{2}; // Call first part of the timing computer {int,int,int,int,int,int,int,int} pre_timing = OTFmap_pre_timing(nlines,npoints_used,band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_linesperscan,n_switch_off,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {double,double} refPosition = {raoff,decoff}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,double,double,int,int,double,double,int,int,int,int,int} tpar = OTFmap_telescope(naifid,onPosition,lineDistance,nlines,line_used,refPosition,scanvelocity,band,lo_freq,n_linesperscan,n_cycles,pre_timing); // Dummy call to spacecraft command int[] telescopetimes = line_scan_with_off_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23}); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int},double,double} post_timing = OTFmap_post_timing(pre_timing,telescopetimes,data_time,n_linesperscan,n_cycles,load_interval); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = OTFmap_telescope(naifid,onPosition,lineDistance,nlines,line_used,refPosition,scanvelocity,band,lo_freq,n_linesperscan,n_cycles,post_timing{1}); // Call telescope command telescopetimes = line_scan_with_off_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23}); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int n_pp = post_timing{1}{0}; int n_scans = post_timing{1}{1}; int loadlength = post_timing{1}{4}; int n_loadinterval = post_timing{1}{5}; double tscan = post_timing{2}; double tdead = post_timing{3}; // telescope time int slewtime = telescopetimes[6]; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { OTFmap_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,nlines * n_cycles,n_linesperscan,n_switch_off,n_pp,n_loadinterval,startobs,telescopetimes,loadlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check]) int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double} tact = OTFmap_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_linesperscan,n_switch_off,n_pp,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = OTFmap_noisecomputer(band,lo_freq,effResolution,oneGHzReference,nlines,npoints_used,n_int_on,n_linesperscan,n_cycles,slewtime,tscan,tact); // Evaluate performance OTF_performance(band,lo_freq,effResolution,noisevalues,timeTaken,nlines,npoints_used,n_scans,n_cycles,tscan,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // HRS attenuator tuning, block // Both polarizations are treated // !!! The routine is 1s too short to get rid of all the data. // It must be externally guaranteed that there is always a dangling // second without data frames produced !!! block HRS_tune_block_aot HIFI 6601 { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band }{ Tune_HRS_aot(band); } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the observing mode procedure LoadChopNoRef_FCal_commanding { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // data dump interval limited by the data rates int n_per_on = 2; // number of half load-sky-sky-load cycles on ON int n_load_on = 0; // additional load measurements in ON pointing phase bool end_load_on = false; // Need for load after ON pointing phase int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,0]; // Timing of observation from telescope int loadlength = 21; // Load duration }{ ////////////////////////////////////////////////////////////////////// // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time //////////////////////////////////////////////////////////////////////// // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // // Clustering is currently not implemented in MPS - switched off here int clustered = 0; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] rates = dataparms{1}; int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 1) { // Initialization if(clustered != 1) { HIFIInitObs(); TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal"); } delay(tinitslew - (time() - startobs) - loadlength - hkduration); // First load measurement HIFISetHK("normal",false); LoadMeasurement_FCal(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 3) { // ON integration HIFIConfigureLoadChopIntegration(data_time,n_per_on,band,lo_freq,backendreadoutparms); // Loop for load cycles for(int i1 = 1 .. n_load_on) { HIFILoadChopOnIntegration(data_time,n_per_on,band,lo_freq,rates); // Perform load calibration delay(readoutdead); LoadMeasurement_FCal(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); HIFIConfigureLoadChopIntegration(data_time,n_per_on,band,lo_freq,backendreadoutparms); } // Last cycle - no load HIFILoadChopOnIntegration(data_time,n_per_on,band,lo_freq,rates); } if(state[0] == 5) { delay(readoutdead); if(end_load_on) { // Perform final load measurement LoadMeasurement_FCal(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } HIFICloseObs(); } } } ///////////////////////////////////////////////////////////////// // Spectral scan in load-chop with OFF calibration // // Implemented as procedure returning time and noise levels for HSPOT {int,double,double,double,double,double} obs HifiSScanProcLoadChop { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source double raoff = 0.0; // RA coordinate of the OFF position double decoff = 0.0; // DEC coordinate of the OFF position bool refSelected = true; // Dummy parameter required by HSPOT string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz int redundancy = 4 in [1,12]; // Frequency scan redundancy {double,double} effResolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz bool wbs1Used = true; // whether WBS1 is used bool wbs2Used = true; // whether WBS2 is used /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles per frequency and pointing int n_switch_off = 1 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles on OFF int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int n_cycles = 1 in [1,600]; // Number of half OFF-ON-ON-OFF cycles at one frequency int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Spectral Scan - Load Chop Ref",{data_time,data_time_off,0,n_switch_on,n_switch_off,0,0,n_freq_point,n_cycles,load_interval}); // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,redundancy,wbs1Used,wbs2Used,data_time); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; ////////////////////////////////////////////////////////////////////// // Call first part of the timing computer {{int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int},{int,double,double[],int[][],bool,double[],int,bool}} pre_timing = SScanLoadChop_pre_timing(band,lo_freq,lo_freq_up,redundancy,effResolution,hr1,hr2,wb1,wb2,data_time,data_time_off,n_switch_on,n_switch_off,n_freq_point,n_cycles,load_interval,docommands); // frequency parameters int groupnumber = pre_timing{1}{0}; double reffreq = pre_timing{1}{1}; double[] freqgrid = pre_timing{1}{2}; int[][] grouporder = pre_timing{1}{3}; bool retuning = pre_timing{1}{4}; double[] targetlevels = pre_timing{1}{5}; int nfreq_if = pre_timing{1}{6}; bool dsb = pre_timing{1}{7}; int n_total = groupnumber * n_cycles; ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {double,double} refPosition = {raoff,decoff}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,int,int,int,int,int,int} tpar = PositionSwitch_telescope(naifid,onPosition,refPosition,band,reffreq,pre_timing{0},n_total); // Dummy call to spacecraft command int[] telescopetimes = nodding_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},true); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int},double,double,double} post_timing = SScanDoubleChop_post_timing(pre_timing{0},telescopetimes,n_freq_point,groupnumber,n_cycles); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = PositionSwitch_telescope(naifid,onPosition,refPosition,band,reffreq,post_timing{1},n_total); // Call telescope command telescopetimes = nodding_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},true); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following // normal pre_timing values int on_inttime = post_timing{1}{0}; int off_inttime = post_timing{1}{1}; int n_loadinterval = post_timing{1}{7}; int n_long_on = post_timing{1}{8}; int n_long_off = post_timing{1}{9}; int shiftlength = post_timing{1}{5}; int initlength = post_timing{1}{14}; bool final_load = post_timing{1}{12}; // efficiency parameters double avnumchop_on = post_timing{2}; double avnumchop_off = post_timing{3}; double tscan = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { SScanLoadChop_commanding(band,reffreq,effResolution,hr1,hr2,wb1,wb2,n_freq_point,grouporder,freqgrid,retuning,targetlevels,data_time,data_time_off,n_switch_on,n_switch_off,n_long_on,n_long_off,n_cycles,n_total,n_loadinterval,final_load,startobs,telescopetimes,shiftlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double,double,double} tact = SScanDoubleChop_deadtimes("lchop",band,reffreq,hr1,hr2,wb1,wb2,n_freq_point,data_time,data_time_off,n_switch_on,n_switch_off,n_long_on,n_long_off,n_cycles,avnumchop_on,avnumchop_off,tscan); // // Call noise computer {double,double,double,double,double} noisevalues = SScanLoadChop_noisecomputer(band,reffreq,nfreq_if,dsb,effResolution,on_inttime,off_inttime,n_cycles,tscan,tact); // Evaluate performance SScanDoubleChop_performance(band,reffreq,nfreq_if,dsb,effResolution,noisevalues,timeTaken,n_freq_point,n_cycles,groupnumber * n_freq_point,avnumchop_on,avnumchop_off,false,tscan,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } //////////////////////////////////////////////////////////////////////// // Radiometric noise from an asymmetric two-phase observation // This is still to be scaled by a factor 1.0/(B_fluct_A*T_Allan) double procedure AsymmetricRadioNoise { double xa = 0.1; // integration time in phase A relative to Allan time double xb = 0.1; // integration time in phase B relative to Allan time double resrat = 1.0; // Ratio in the effective resolution B/A }{ if(xa > 0.0) { double y = 1.0 / xa + 1.0 / (xb * resrat); } else { // forbid x values <=0 y = 1.0E11 * (1.0 - xa); } return y; } ////////////////////////////////////////////////////////////////////// // Generic procedure to determine backend parameters for a // Configure_spectroscopy command {int,int,int,int,int[],int[],string} procedure ConfigSpectroscopyBackends { /* Integration time */ int data_time = 4; // Integration time between two data readouts /* Backend settings */ {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // HRS1/2 {used,resolution,subbands}, WBS1/2 {used, channel windows} }{ // The following parameters are hard-wired here as they should never change int wbs16bitlimit = 5; int wbs16bitrshift1 = 1; int wbs16bitrshift2 = 2; int wbs24bitrshift0 = 20; int wbs24bitrshift1 = 40; int wbs24bitrshift2 = 80; int hrsrshift0 = 16; int hrsrshift1 = 32; int hrsrshift2 = 64; // Compute transfer mode // 16 bit format for short integrations if(data_time <= wbs16bitlimit) { string packing = "16_bits_format"; // Right shift depends in data_time if(data_time <= wbs16bitrshift1) { int wbs_rshift = 1; } else { if(data_time <= wbs16bitrshift2) { wbs_rshift = 2; } else { wbs_rshift = 3; } } // 24 bit mode for long integrations } else { packing = "24_bits_format"; // Right shift to produce valid IF power HK data if(data_time <= wbs24bitrshift0) { wbs_rshift = 0; } else { if(data_time <= wbs24bitrshift1) { wbs_rshift = 1; } else { if(data_time <= wbs24bitrshift2) { wbs_rshift = 2; } else { wbs_rshift = 3; } } } } // bit shift for HRS if(data_time <= hrsrshift0) { int hrs_rshift = 0; } else { if(data_time <= hrsrshift1) { hrs_rshift = 1; } else { if(data_time <= hrsrshift2) { hrs_rshift = 2; } else { hrs_rshift = 3; } } } // Backend selection // HRS {int,int,int,int} hrssets = HrsSubbandSelection(backendreadoutparms); int hrsh_sel = hrssets{0}; int hrsv_sel = hrssets{1}; // WBS windows // WBS-H // Initialize to zero int[] wbsh_pars = [0,0,2048,0,4096,0,6144,0]; if(backendreadoutparms{2}{0}) { // Set defined boundaries wbsh_pars[0] = backendreadoutparms{2}{1}[0][0] + wbsh_pars[0]; wbsh_pars[1] = backendreadoutparms{2}{1}[0][1] - backendreadoutparms{2}{1}[0][0]; wbsh_pars[2] = backendreadoutparms{2}{1}[1][0] + wbsh_pars[2]; wbsh_pars[3] = backendreadoutparms{2}{1}[1][1] - backendreadoutparms{2}{1}[1][0]; wbsh_pars[4] = backendreadoutparms{2}{1}[2][0] + wbsh_pars[4]; wbsh_pars[5] = backendreadoutparms{2}{1}[2][1] - backendreadoutparms{2}{1}[2][0]; wbsh_pars[6] = backendreadoutparms{2}{1}[3][0] + wbsh_pars[6]; wbsh_pars[7] = backendreadoutparms{2}{1}[3][1] - backendreadoutparms{2}{1}[3][0]; } // WBS-V // Initialize to zero int[] wbsv_pars = [0,0,2048,0,4096,0,6144,0]; if(backendreadoutparms{3}{0}) { // Set defined boundaries wbsv_pars[0] = backendreadoutparms{3}{1}[0][0] + wbsv_pars[0]; wbsv_pars[1] = backendreadoutparms{3}{1}[0][1] - backendreadoutparms{3}{1}[0][0]; wbsv_pars[2] = backendreadoutparms{3}{1}[1][0] + wbsv_pars[2]; wbsv_pars[3] = backendreadoutparms{3}{1}[1][1] - backendreadoutparms{3}{1}[1][0]; wbsv_pars[4] = backendreadoutparms{3}{1}[2][0] + wbsv_pars[4]; wbsv_pars[5] = backendreadoutparms{3}{1}[2][1] - backendreadoutparms{3}{1}[2][0]; wbsv_pars[6] = backendreadoutparms{3}{1}[3][0] + wbsv_pars[6]; wbsv_pars[7] = backendreadoutparms{3}{1}[3][1] - backendreadoutparms{3}{1}[3][0]; } // return {wbs_rshift,hrs_rshift,hrsh_sel,hrsv_sel,wbsh_pars,wbsv_pars,packing}; } //Set LCU6La back to standby status, procedure procedure LCU6La_standby_proc_fm { string band = "6a"; // HIFI band double lo_freq = 1500.0 in [1410.0,1575.0]; //LO frequency }{ error("This module is obsolete: use LCU_standby_proc_fm instead"); } // WBS zero, block block WBS0_fm HIFI 3604 { string band = "1a"; // HIFI band }{ //Start_block(); //Two options are possible: CUS sequence or automatic OBS command //Option1: CUS sequence (has its own delay) //WBS0_fm_proc(band); //Option2: OBS command Hifi_HIFI_WBS_Zero($BBID); //Get delay {double,string}[] result_d = ConfigurationReader("name_delays",["wbs_zero_delay"],band,0.0); int wbs_zero_delay = iround(result_d[0]{0}); delay(wbs_zero_delay); } //Get best guess D2 from look-up table double procedure Get_BEST_GUESS_D2_proc_fm { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO Frequency }{ //Fetch best guess for D2 string name_configlcutune = "name_configlcu_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlcutune = "name_configlcu_b"; } // {double,string}[] result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lo_freq); // return result[0]{0}; } // Switch HIFI off, procedure // Prime and Redundancy are both called, regardless of which is effectively used // procedure HIFI_global_switch_off_fm { }{ //Sequentially notify PDU off then switch off S/S //This maybe non-instictive order is due to an ICU bug that //screws things up when the ICU tries to get HK from a switched off S/S // //LOU Hifi_HIFI_notify_PDU_status("ON","OFF","ON","ON","ON","ON"); //HifiIltEgse_PDU_switch_off($BBID,"LO_Prime"); //HifiIltEgse_PDU_switch_off($BBID,"LO_Red"); //WBS-H Hifi_HIFI_notify_PDU_status("ON","OFF","ON","OFF","ON","ON"); //HifiIltEgse_PDU_switch_off($BBID,"WBS_H"); //WBS-V Hifi_HIFI_notify_PDU_status("ON","OFF","OFF","OFF","ON","ON"); //HifiIltEgse_PDU_switch_off($BBID,"WBS_V"); //HRS-H Hifi_HIFI_notify_PDU_status("ON","OFF","OFF","OFF","ON","OFF"); //HifiIltEgse_PDU_switch_off($BBID,"HRS_H"); //HRS-V Hifi_HIFI_notify_PDU_status("ON","OFF","ON","OFF","OFF","OFF"); //HifiIltEgse_PDU_switch_off($BBID,"HRS_V"); //ICU Hifi_HIFI_notify_PDU_status("OFF","OFF","OFF","OFF","OFF","OFF"); //HifiIltEgse_PDU_switch_off($BBID,"ICU_Prime"); //HifiIltEgse_PDU_switch_off($BBID,"ICU_Red"); //At that stage, the instrument is idle... } // Magnet current scan, fast, procedure. // Mixer current as a function of magnet current. procedure Magnet_scan_fast_proc { string band = "1a"; // HIFI band //Setting file double magnet_current_min_h = -10.0; //minimum magnet current H double magnet_current_max_h = 15.0; //maximum magnet current H double magnet_current_min_v = -10.0; //minimum magnet current V double magnet_current_max_v = 15.0; //maximum magnet current V int n_steps = 100; //number of steps double lo_freq = 522.0; //LO frequency }{ // Magnet_scan_fast_fm(band,magnet_current_min_h,magnet_current_max_h,magnet_current_min_v,magnet_current_max_v,n_steps,lo_freq); //Back to nominal values if(band != "0") { {double,string}[] result = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,0.0); } if(band == "0") { result = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v","magnet_standby_h","magnet_standby_v","bias_standby_h","bias_standby_v"],band,0.0); } //First set magnet to maximum to avoid hysteresis double magnetcurrent_max_h = result[0]{0}; double magnetcurrent_max_v = result[1]{0}; Set_Magnet_current_block_fm(magnetcurrent_max_h,magnetcurrent_max_v); //Nominal values result = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v","norm_bias_h","norm_bias_v"],band,lo_freq); Set_Magnet_current_block_fm(result[0]{0},result[1]{0}); //Also set bias voltages back to nominal values Mixerbias_block_fm(result[2]{0},result[3]{0}); } // Standing wave analysis, mode // For COP, we observe mostly sky-CBB, and sometimes sky-HBB and sky-sky pairs //HIFI-COP-3-StWv1 obs HifiEng_standing_wave_noretune_COP { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band int freq_index = 1; //The frequency index to consider: 1 to 4 string los_code = "sc" in ["sc","sh","ss"]; //The line-of-sight code: sc (sky-CBB), sh (sky-HBB), ss (sky-sky) }{ //General parameters in use string backend = "both"; string[] hrs_mode = ["mr","mr"]; // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Standing_wave_noretune_COP_proc_ops(band,backend,hrs_mode,freq_index,los_code)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Standing_wave_noretune_COP_proc_ops(band,backend,hrs_mode,freq_index,los_code); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } // Perform frequency-switch integration at OFF position ON-OFF-OFF-ON... block HIFIFSwitchOffIntegration HIFI 6039 { int data_time = 4; // Integration time between two data readouts int n_cycle = 1; // chop cycle number string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double[] rates = [120.0,1.0,2.0]; // Data rates between and during integrations }{ HIFI_Spectr_fswitch_proc_aot(data_time,n_cycle,band,lo_freq,rates); } // WBS overall attenuator FM functional test, block // Done for laser1 block FT_WBS_att_individual_fm HIFI 3707 { string band = "1a"; // HIFI band int integ_time = 4; //Total integration time in sec. string laser_H = "Laser1" in ["Laser1","Laser2"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2"]; //WBS-V laser to be set ON string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); // //Set zero and comb off Hifi_HIFI_Single_cmd($BBID,"HWH_ZERO_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWV_ZERO_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWH_COMB_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWV_COMB_OFF"); delay(2); // //Initial configuration: overall attenuators set to 0, individual attenuators to max. //H-Polarization // {double,string}[] result = ConfigurationReader("name_configwbs",["hwh_heater","hwh_latchup_s"],band,0.0); string hwh_laser1_s = "OFF"; string hwh_laser2_s = "OFF"; if(laser_H == "Laser1") { hwh_laser1_s = "ON"; } if(laser_H == "Laser2") { hwh_laser2_s = "ON"; } int hwh_heater = iround(result[0]{0}); string hwh_latchup_s = result[1]{1}; int hwh_att_band4 = 8; int hwh_att_band3 = 8; int hwh_att_band2 = 8; int hwh_att_band1 = 8; int hwh_att_in = 0; // result = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result[0]{0}); // //V-Polarization // result = ConfigurationReader("name_configwbs",["hwv_heater","hwv_latchup_s"],band,0.0); string hwv_laser1_s = "OFF"; string hwv_laser2_s = "OFF"; if(laser_V == "Laser1") { hwv_laser1_s = "ON"; } if(laser_V == "Laser2") { hwv_laser2_s = "ON"; } int hwv_heater = iround(result[0]{0}); string hwv_latchup_s = result[1]{1}; int hwv_att_band4 = 8; int hwv_att_band3 = 8; int hwv_att_band2 = 8; int hwv_att_band1 = 8; int hwv_att_in = 0; // //Loop on overall attenuators for(int i = 0 .. 7) { // Change the value of the individual attenuators //=============================================== hwh_att_band4 = hwh_att_band4 - 1; hwh_att_band3 = hwh_att_band3 - 1; hwh_att_band2 = hwh_att_band2 - 1; hwh_att_band1 = hwh_att_band1 - 1; hwv_att_band4 = hwv_att_band4 - 1; hwv_att_band3 = hwv_att_band3 - 1; hwv_att_band2 = hwv_att_band2 - 1; hwv_att_band1 = hwv_att_band1 - 1; // Set WBS //======== Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); delay(wbs_config_delay); //Wait for configuration to be applied // Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); delay(wbs_config_delay); //Wait for configuration to be applied // HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // } //Set att. to max. WBS_config_proc_max_att_w_laser_fm(band,laser_H,laser_V); // } //HIFI LO tuning with choice of mixer to be used, block //Target current is read from look-up table block LO_tuning_w_mixerchoice_block_fm HIFI 3675 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency string mixer_polarization = "H" in ["H","V","B"]; //The polarization to be used for the tuning }{ //Clear potential failure mode Set_LO_Nominal_proc_fm(); // //Start_block(); // //Get target mixer current {double,string}[] result = ConfigurationReader("name_confilmix",["target_mx_c_h","target_mx_c_v"],band,lo_freq); double target_current = result[0]{0}; if(mixer_polarization == "V") { target_current = result[1]{0}; } if(mixer_polarization == "B") { target_current = 0.5 * (result[1]{0} + result[0]{0}); } // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; name_configlcutune = "name_configlcutune_b"; } // result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // result = ConfigurationReader(name_configlotune,["step_drain2_v","nsteps","step_time"],band,lo_freq); double step_drain2_v = result[0]{0}; int nsteps = iround(result[1]{0}); double step_time = result[2]{0}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // //Adjust scan cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); double drain2_safe = cresult[0]; // double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); // //For all bands, scan will be done with decreasing drain2 voltages //The best guess is taken from look-up table double tune_range = 0.1; result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lo_freq); double middle_d2 = result[0]{0}; double drain2_v_start = min(middle_d2 * (1.0 + tune_range / 2.0),drain2_bluemax); double drain2_v_end = (1.0 - tune_range / 2.0) / (1.0 + tune_range / 2.0) * drain2_v_start; step_drain2_v = (drain2_v_end - drain2_v_start) / double(nsteps - 1); // result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); // //Send command HIFI_Configure_LCU_proc_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,macro_checksum,config_lo_delay); // //delay(5); //to settle at this value // //Load vector scan //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Load_vector_safe_1a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "1b") { //Band 1b Hifi_HIFI_Load_vector_safe_1b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2a") { //Band 2a Hifi_HIFI_Load_vector_safe_2a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2b") { //Band 2b Hifi_HIFI_Load_vector_safe_2b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3a") { //Band 3a Hifi_HIFI_Load_vector_safe_3a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3b") { //Band 3b Hifi_HIFI_Load_vector_nom_3b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "4a") { //Band 4a Hifi_HIFI_Load_vector_safe_4a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "4b") { //Band 4b Hifi_HIFI_Load_vector_safe_4b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "5a") { //Band 5a Hifi_HIFI_Load_vector_nom_5a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "5b") { //Band 5b Hifi_HIFI_Load_vector_nom_5b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6a") { //Band 6a Hifi_HIFI_Load_vector_nom_6a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6b") { //Band 6b Hifi_HIFI_Load_vector_nom_6b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7a") { //Band 7a Hifi_HIFI_Load_vector_nom_7a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7b") { //Band 7b Hifi_HIFI_Load_vector_nom_7b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } // delay(1); // //Execute tuning: check which mixer is to be used if(mixer_polarization == "V") { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCV($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCV($BBID,target_current); } } else { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCH($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCH($BBID,target_current); } } // double time_needed = double(nsteps) * step_time; delay(iround(time_needed + 2.0 + 0.5)); //0.5s added for completion of load_vector // //Store settings into available register HIFI_HL_store_tm_only_proc_fm(); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } // // Magnet current scan, fast, block. // Mixer current as a function of magnet current. block Magnet_scan_fast_fm HIFI 3270 { string band = "1a"; // HIFI band double magnet_current_min_h = -15.0; //minimum magnet current H double magnet_current_max_h = 10.0; //maximum magnet current H double magnet_current_min_v = -15.0; //minimum magnet current V double magnet_current_max_v = 10.0; //maximum magnet current V int n_steps = 100; //number of steps double lo_freq = 522.0; //LO frequency }{ Start_block(); {double,string}[] result = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,0.0); double magnetcurrent_max_h = result[0]{0}; double magnetcurrent_max_v = result[1]{0}; //We use special biasing to evidence the minima in the magnet scan result = ConfigurationReader("name_confilmix",["bias4magn_h","bias4magn_v"],band,lo_freq); double bias_h = result[0]{0}; double bias_v = result[1]{0}; Mixerbias(bias_h,bias_v); // int steps = 0; int steps_done = 0; double step_duration = 0.1; int steps_wanted = n_steps; if(steps_wanted < 1) { steps_wanted = 1; } double magnet_current_h = 0.0; double stepsize_h = 0.0; double magnet_current_v = 0.0; double stepsize_v = 0.0; if(steps_wanted > 1) { stepsize_h = (magnet_current_max_h - magnet_current_min_h) / (double(steps_wanted) - 1.0); stepsize_v = (magnet_current_max_v - magnet_current_min_v) / (double(steps_wanted) - 1.0); } // //Set magnet to maximum to avoid hysteresis Hifi_HIFI_CH1_MX_MG_C($BBID,magnetcurrent_max_h); Hifi_HIFI_CV1_MX_MG_C($BBID,magnetcurrent_max_v); delay(1); // //Start scan: from max. to min. magnet downward. while(steps_done < steps_wanted) { steps = steps_wanted - steps_done; if(steps > n_steps) { steps = n_steps; } magnet_current_h = magnet_current_max_h - double(steps_done) * stepsize_h; magnet_current_v = magnet_current_max_v - double(steps_done) * stepsize_v; Hifi_HIFI_FCU_parameter_scan($BBID,1,1,step_duration,bias_h,bias_v,0.0,magnet_current_h,magnet_current_v,0.0); //Sets magnet current delay(2); steps_done = steps_done + 1; } } // LCU1a configuration and tuning, procedure procedure LCU1a_config_tune_proc_fm { string band = "1a"; // HIFI band double lo_freq = 500.0 in [488.0,552.0]; //LO frequency double drain_2_factor = 100.0; //Percentage factor of the targetted drain voltage }{ error("This module is obsolete: use LO_tuning_block_fm instead"); } // Configuration for slow-chop integration block HIFIConfigureSlowChopIntegration HIFI 6030 { int data_time = 4; // Integration time between two data readouts int n_cycle = 1; // chop cycle number string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // HRS1/2 {used,resolution,subbands used}, WBS1/2 {used, channel windows} }{ // Call procedure doing the work ConfigureSpectroscopy(data_time,2 * n_cycle,"chop",band,lo_freq,backendreadoutparms); } //Readback of LCU safety table, block block LcuSafetyTableReadback_ops HIFI 7901 { }{ StartBlock_ops(); // for(int band = 1 .. 7) { for(int fIndex = 0 .. 31) { Hifi_HIFI_non_periodic_hk_LCU(fIndex,"channel_" + band + "a"); delay(2); Hifi_HIFI_non_periodic_hk_LCU(fIndex,"channel_" + band + "b"); delay(2); } } } // Special configuration and data taking for FSW response time block FSW_Response_time_block_fm HIFI 3688 { string hrs_polar = "H" in ["H","V","B"]; //HRS polarizations in use int[] del_wbs_param = [10,200,10,100]; //starting, ending and step value for del_wbs }{ // //Additional "constant" parameters {double,string}[] result = ConfigurationReader("name_delays",["add_hrs","add_wbs","add_jitter","wbs_init","wbs_chunksize","tacc_add","hrs_phase"],"0",0.0); int add_hrs = iround(result[0]{0}); int add_wbs = iround(result[1]{0}); int wbs_init = iround(result[3]{0}); int wbs_chunksize = iround(result[4]{0}); int tacc_add = iround(result[5]{0}); int hrs_phase = iround(result[6]{0}); // HRS standard phase length // // Get fixed parameters from configuration and calibration files // Command jitter time is the default delay result = ConfigurationReader("name_delays",["add_jitter"],"0",0.0); int add_jitter = iround(result[0]{0}); //Fetch default parameters result = ConfigurationReader("name_confilspec",["del_hrs","del_wbs","t_acc_wbs","t_acc_hrs","n_wbs_integr","n_hrs_integr","r_hrs","wbsh_offset1","wbsh_width1","wbsh_offset2","wbsh_width2","wbsh_offset3","wbsh_width3","wbsh_offset4","wbsh_width4","wbsv_offset1","wbsv_width1","wbsv_offset2","wbsv_width2","wbsv_offset3","wbsv_width3","wbsv_offset4","wbsv_width4","hrs_rshift","wbs_rshift","hrsh_sel","hrsv_sel","wbs_packing"],"0",0.0); // // WBS delta time int del_wbs = del_wbs_param[0]; // HRS delta time - should be zero int del_hrs = add_jitter; //Fixed integration time for this test int n_data = 4; int data_time = 1; //Integration time for one phase if only one HRS polar if(hrs_polar == "B") { data_time = 2; } // Split total integration time int tint = data_time * n_data * 1000; // Accumulation time // Ignores that total power can be slightly more efficient int t_acc_wbs = (tint - wbs_init) / n_data - add_wbs - add_jitter - del_wbs; // discretize in 10ms chunks int nchunk = (t_acc_wbs - tacc_add) / wbs_chunksize; t_acc_wbs = nchunk * wbs_chunksize + tacc_add; // No WBS addition in ICU int n_wbs_integr = 1; int n_wbs_start = n_data; // HRS int hrs_fullphase = hrs_phase + del_hrs + add_hrs; int r_hrs = (t_acc_wbs + hrs_fullphase - add_jitter) / hrs_fullphase; int t_acc_hrs = iceil(min(double(del_wbs_param[0]),double((t_acc_wbs - add_jitter) / r_hrs - del_hrs - add_hrs))); // for n_wbs_integr=1 identical to r_hrs int n_hrs_integr = r_hrs; //No WBS int wbsh_offset1 = 0; int wbsh_width1 = 0; int wbsh_offset2 = 0; int wbsh_width2 = 0; int wbsh_offset3 = 0; int wbsh_width3 = 0; int wbsh_offset4 = 0; int wbsh_width4 = 0; int wbsv_offset1 = 0; int wbsv_width1 = 0; int wbsv_offset2 = 0; int wbsv_width2 = 0; int wbsv_offset3 = 0; int wbsv_width3 = 0; int wbsv_offset4 = 0; int wbsv_width4 = 0; int hrs_rshift = 0; int wbs_rshift = iround(result[24]{0}); int hrsh_sel = 0; int hrsv_sel = 0; if(hrs_polar == "H" || hrs_polar == "B") { hrsh_sel = 255; } if(hrs_polar == "V" || hrs_polar == "B") { hrsv_sel = 255; } string wbs_packing = result[27]{1}; // //Now loop on del_wbs and trigger FSW spectro int step = del_wbs_param[2]; while(del_wbs <= del_wbs_param[1]) { // //Configure integration to be done Hifi_HIFI_config_spectroscopy($BBID,n_wbs_start,r_hrs,n_wbs_integr,n_hrs_integr,del_hrs,del_wbs,t_acc_wbs,t_acc_hrs,wbsh_offset1,wbsh_width1,wbsh_offset2,wbsh_width2,wbsh_offset3,wbsh_width3,wbsh_offset4,wbsh_width4,wbsv_offset1,wbsv_width1,wbsv_offset2,wbsv_width2,wbsv_offset3,wbsv_width3,wbsv_offset4,wbsv_width4,hrs_rshift,wbs_rshift,hrsh_sel,hrsv_sel,wbs_packing); // //Take spectrum Hifi_HIFI_Spectr_freq_switch($BBID); //Compute delay result = ConfigurationReader("name_delays",["wbs_transfer_delay"],"0",0.0); // int wbs_packet_transfer_time = iround(result[0]{0}); int delay_fsw = n_wbs_start * data_time + wbs_packet_transfer_time / 1000; //debug_print("Total power delay: " + delay_total_power + " sec"); // //Apply delay delay(delay_fsw); // //Increase step del_wbs = del_wbs + step; //Re-adjust spectrometer integration times //WBS t_acc_wbs = (tint - wbs_init) / n_data - add_wbs - add_jitter - del_wbs; // discretize in 10ms chunks nchunk = (t_acc_wbs - tacc_add) / wbs_chunksize; t_acc_wbs = nchunk * wbs_chunksize + tacc_add; //HRS r_hrs = (t_acc_wbs + hrs_fullphase - add_jitter) / hrs_fullphase; t_acc_hrs = iceil(min(double(del_wbs_param[0]),double((t_acc_wbs - add_jitter) / r_hrs - del_hrs - add_hrs))); } } //HIFI-COP-2.1-DipCal2 obs HifiEng_Diplexer_calibration_hotcold_COP { string band = "3" in ["3","4","6","7"]; // HIFI mixer band }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Diplexer_calibration_hotcold_COP_proc_ops(band)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Diplexer_calibration_hotcold_COP_proc_ops(band); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } //HIFI LO tuning only for M1 investigation in 7b, block //Target current is read from look-up table block LO_tuning_w_M1_block_fm HIFI 3716 { string band = "7b"; // HIFI band double lo_freq = 1890.0; //LO frequency double m1 = -5.0; //M1 multiplier voltage }{ //Clear potential failure mode Set_LO_Nominal_proc_fm(); // //Start_block(); {double,string}[] result = ConfigurationReader("name_confpolar4lotune",[band],band,lo_freq); string mixer_polarization = result[0]{1}; // //Get target mixer current result = ConfigurationReader("name_confilmix",["target_mx_c_h","target_mx_c_v"],band,lo_freq); double target_current = result[0]{0}; if(mixer_polarization == "V") { target_current = result[1]{0}; } if(mixer_polarization == "B") { target_current = 0.5 * (result[1]{0} + result[0]{0}); } // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; name_configlcutune = "name_configlcutune_b"; } // result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = m1; //result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // result = ConfigurationReader(name_configlotune,["step_drain2_v","nsteps","step_time"],band,lo_freq); double step_drain2_v = result[0]{0}; int nsteps = iround(result[1]{0}); double step_time = result[2]{0}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // //Adjust scan cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); double drain2_safe = cresult[0]; // double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); // //For all bands, scan will be done with decreasing drain2 voltages //The best guess is taken from look-up table double tune_range = 0.1; result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lo_freq); //The automatic tuning shall use the min of the nominal best-guess and Vd2max - 100mV double middle_d2 = min(result[0]{0},drain2_bluemax - 0.1); double drain2_v_start = min(middle_d2 * (1.0 + tune_range / 2.0),drain2_bluemax); double drain2_v_end = (1.0 - tune_range / 2.0) / (1.0 + tune_range / 2.0) * middle_d2; //drain2_v_start; step_drain2_v = (drain2_v_end - drain2_v_start) / double(nsteps - 1); // result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); // //Send command if(band == "3b") { Hifi_HIFI_Conf_nom_LCU_ch3b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,macro_checksum); //Send command: specific to M3 in 3b delay(config_lo_delay); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } else { // //General command HIFI_Configure_LCU_proc_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,macro_checksum,config_lo_delay); } // //delay(5); //to settle at this value // //Load vector scan //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Load_vector_safe_1a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "1b") { //Band 1b Hifi_HIFI_Load_vector_safe_1b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2a") { //Band 2a Hifi_HIFI_Load_vector_safe_2a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2b") { //Band 2b Hifi_HIFI_Load_vector_safe_2b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3a") { //Band 3a Hifi_HIFI_Load_vector_safe_3a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3b") { //Band 3b Hifi_HIFI_Load_vector_nom_3b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "4a") { //Band 4a Hifi_HIFI_Load_vector_safe_4a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "4b") { //Band 4b Hifi_HIFI_Load_vector_safe_4b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "5a") { //Band 5a Hifi_HIFI_Load_vector_nom_5a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "5b") { //Band 5b Hifi_HIFI_Load_vector_nom_5b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6a") { //Band 6a Hifi_HIFI_Load_vector_nom_6a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6b") { //Band 6b Hifi_HIFI_Load_vector_nom_6b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7a") { //Band 7a Hifi_HIFI_Load_vector_nom_7a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7b") { //Band 7b Hifi_HIFI_Load_vector_nom_7b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } // delay(1); // //Execute tuning: check which mixer is to be used if(mixer_polarization == "V") { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCV($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCV($BBID,target_current); } } else { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCH($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCH($BBID,target_current); } } // double time_needed = double(nsteps) * step_time; delay(iround(time_needed + 2.0 + 0.5)); //0.5s added for completion of load_vector // //Store settings into available register HIFI_HL_store_tm_only_proc_fm(); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } ////////////////////////////////////////////////////////////////////// // Procedure to perform the noise level evaluation for the observing mode {double,double,double,double,double} procedure FSwitch_noisecomputer { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF int on_inttime = 16; // Integration time per ON phase int off_inttime = 16; // Integration time per OFF phase int n_cycles = 1; // Number of half OFF-ON-ON-OFF calibration cycles double tscan = 60.0; // Total average duration of one scan {double,double,double,double,double} tact = {10.0,4.9,4.9,0.05,0.05}; // Field of actual dead and integration times }{ double tdead = tact{0}; // Average total dead time in one scan double inttimeperonphase = tact{1}; // Actual integration time in ON phase double inttimeperoffphase = tact{2}; // Actual integration time in OFF phase double deadtimeperonphase = tact{3}; // Dead time per switch phase on ON // Get parameters which are needed double tsys = InterpolateTsys(band,lo_freq); double eta_mb = InterpolateCoupling(band,lo_freq); double[] gssb = InterpolateGssb(band,lo_freq); // Get the drift parameters to compute the drift noise // System Allan variance double[] allanparms = InterpolateSpecAllan(band,lo_freq,oneGHzReference); // rescale to frequency resolution double alpha = allanparms[1]; double binningexp = 1.0 / allanparms[2]; double allan_time_lores = allanparms[0] * pow(1.0 / eff_resolution{1},binningexp); double allan_time_hires = allanparms[0] * pow(1.0 / eff_resolution{0},binningexp); // Differential Allan variance allanparms = InterpolateSpecFSwitchAllan(band,lo_freq,oneGHzReference); // rescale to frequency resolution double dalpha = allanparms[1]; binningexp = 1.0 / allanparms[2]; double dallan_time_lores = allanparms[0] * pow(1.0 / eff_resolution{1},binningexp); double dallan_time_hires = allanparms[0] * pow(1.0 / eff_resolution{0},binningexp); // resolution of OFF phase double sw_resolution = GetFSwitchSWResolution(band,lo_freq); double sw_resolution_lores = max(eff_resolution{1},sw_resolution); double sw_resolution_hires = max(eff_resolution{0},sw_resolution); // Compute the relative noise for the detailed timing double on_int = double(on_inttime); double off_int = double(off_inttime); // The dead time per switch might deviate between ON and OFF - ignored double deadtimeperswitch = deadtimeperonphase; // Get actual noise // This is returned twice: for both limiting resolutions double systemnoise_lores = DoubleDifferenceNoise(inttimeperonphase / allan_time_lores,[inttimeperoffphase / inttimeperonphase,sw_resolution_lores / eff_resolution{1},on_int / allan_time_lores,off_int / allan_time_lores,deadtimeperswitch / allan_time_lores,tdead / allan_time_lores,alpha,dallan_time_lores / allan_time_lores,dalpha]); double systemnoise_hires = DoubleDifferenceNoise(inttimeperonphase / allan_time_hires,[inttimeperoffphase / inttimeperonphase,sw_resolution_hires / eff_resolution{0},on_int / allan_time_hires,off_int / allan_time_hires,deadtimeperswitch / allan_time_hires,tdead / allan_time_hires,alpha,dallan_time_hires / allan_time_hires,dalpha]); double noiseratio = DoubleDifferenceNoiseRatio(inttimeperonphase / allan_time_lores,[inttimeperoffphase / inttimeperonphase,sw_resolution_lores / eff_resolution{1},on_int / allan_time_lores,off_int / allan_time_lores,deadtimeperswitch / allan_time_lores,tdead / allan_time_lores,alpha,dallan_time_lores / allan_time_lores,dalpha]); // Compute total double sideband noise // Correct for signal in both pases double dsbnoise_lores = tsys * sqrt(systemnoise_lores / (eff_resolution{1} * 2000000.0 * double(n_cycles) * tscan)); double dsbnoise_hires = tsys * sqrt(systemnoise_hires / (eff_resolution{0} * 2000000.0 * double(n_cycles) * tscan)); // Translate to the main beam scale, correct for eta_mb // (This is typically not done at ground based telescopes, // but leads often to problems there - to be discussed.) dsbnoise_lores = dsbnoise_lores / eta_mb; dsbnoise_hires = dsbnoise_hires / eta_mb; // Get single sideband noise equivalent double usbnoise_lores = dsbnoise_lores / gssb[0]; double usbnoise_hires = dsbnoise_hires / gssb[0]; double lsbnoise_lores = dsbnoise_lores / gssb[1]; double lsbnoise_hires = dsbnoise_hires / gssb[1]; // Return noise values and the maximum ratio of drift to radiometric noise return {usbnoise_lores,usbnoise_hires,lsbnoise_lores,lsbnoise_hires,noiseratio}; } //TM check when in standby II procedure Mode_status_check_standby_II { string laser_H = "Laser1" in ["Laser1","Laser2"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2"]; //WBS-V laser to be set ON string chopper_loop = "OPEN" in ["OPEN","CLOSE"]; //chopper loop status string sequence_order = "up" in ["down","up"]; //order in which sequence is done string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ mois_comment("Checking instrument status in standby II mode"); //General checks: not applicable here: S/S should all be on here //FCU checks {double,string}[] result_d = ConfigurationReader("name_confilfpu",["calibrator_current_on"],"0",0.0); double calibcurrent = result_d[0]{0}; //Getting in band0 is only new when coming from primary if(sequence_order == "down") { mois_tmcheck("Check that parameter HF_DH1_MXBAND and HF_DV1_MXBAND are both 0"); } //Checking if HBB is on important at any standby or primary stage mois_tmcheck("Check that parameter HF_APR_CS_C is set to " + calibcurrent + " mA. If not, you can proceed but need to inform HIFI ICC."); //Chopper voltage string chop_startup_prime_red = "chop_startup_cold_prime"; if(prime_or_redundant == "Red") { chop_startup_prime_red = "chop_startup_cold_red"; } result_d = ConfigurationReader("name_chopper",[chop_startup_prime_red],"0",0.0); if(chopper_loop == "OPEN") { result_d = ConfigurationReader("name_chopper",["chop_startup_warm"],"0",0.0); } if(sequence_order == "down") { mois_tmcheck("Check that parameter HF_DPR_CH_ROT is set to " + result_d[0]{0}); //Chopper loop status should always be monitored mois_tmcheck("Check that parameter HF_DPR_CHLOOP_S is set to " + chopper_loop); } // //WBS checks: although only lasers are changed, the whole configuration command is called result_d = ConfigurationReader("name_configwbs",["hwh_latchup_s","hwv_latchup_s"],"0",0.0); string hwh_latchup_s = "Low"; if(result_d[0]{1} == "Level2") { hwh_latchup_s = "High"; } string hwv_latchup_s = "Low"; if(result_d[1]{1} == "Level2") { hwv_latchup_s = "High"; } string hwh_laser1_s = "OFF"; string hwh_laser2_s = "OFF"; if(laser_H == "Laser1") { hwh_laser1_s = "ON"; } if(laser_H == "Laser2") { hwh_laser2_s = "ON"; } string hwv_laser1_s = "OFF"; string hwv_laser2_s = "OFF"; if(laser_H == "Laser1") { hwv_laser1_s = "ON"; } if(laser_H == "Laser2") { hwv_laser2_s = "ON"; } // mois_tmcheck("Check that parameters HWH_Laser1_S, HWH_Laser2_S, HWV_Laser1_S and HWV_Laser2_S are respectively " + hwh_laser1_s + ", " + hwh_laser2_s + ", " + hwv_laser1_s + " and " + hwv_laser2_s); mois_tmcheck("Check that both parameters HWH_Zero_S and HWV_Zero_S are ON"); mois_tmcheck("Check that both parameters HWH_Comb_S and HWV_Comb_S are OFF"); mois_tmcheck("Check that parameters HWH_LUP_level_S and HWV_LUP_level_S are " + hwh_latchup_s + " and " + hwv_latchup_s + " respectively"); mois_tmcheck("Check that parameter HWH_IN_ATT is set to 15, and parameters HWH_Band_1_ATT, HWH_Band_2_ATT, HWH_Band_3_ATT, HWH_Band_4_ATT are set to 7"); mois_tmcheck("Check that parameter HWV_IN_ATT is set to 15, and parameters HWV_Band_1_ATT, HWV_Band_2_ATT, HWV_Band_3_ATT, HWV_Band_4_ATT are set to 7"); //HRS Checks: HRS only modified if from primary to standbyII if(sequence_order == "down") { // Fetch HRS configuration parameters //=================================== //H-polar string hrs_filename_h = "name_confighrs_wb"; {double,string}[] result = ConfigurationReader(hrs_filename_h,["hrh_switch","hrh_1u_att","hrh_1l_att","hrh_2u_att","hrh_2l_att","hrh_3u_att","hrh_3l_att","hrh_4u_att","hrh_4l_att","hrh_up_ol1","hrh_up_ol2","hrh_up_ol3","hrh_up_ol4","hrh_down_ol5","hrh_down_ol6","hrh_down_ol7"],"0",0.0); string hrs_polarization_h = result[0]{1}; double[] hrsH_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; //V-polar string hrs_filename_v = "name_confighrs_wb"; result = ConfigurationReader(hrs_filename_v,["hrv_switch","hrv_1u_att","hrv_1l_att","hrv_2u_att","hrv_2l_att","hrv_3u_att","hrv_3l_att","hrv_4u_att","hrv_4l_att","hrv_up_ol1","hrv_up_ol2","hrv_up_ol3","hrv_up_ol4","hrv_down_ol5","hrv_down_ol6","hrv_down_ol7"],"0",0.0); string hrs_polarization_v = result[0]{1}; double[] hrsV_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; // mois_tmcheck("Check that parameters HRH_1U_ATT, HRH_1L_ATT, HRH_2U_ATT, HRH_2L_ATT, HRH_3U_ATT, HRH_3L_ATT, HRH_4U_ATT and HRH_4L_ATT are set to 15.5"); mois_tmcheck("Check that parameters HRV_1U_ATT, HRV_1L_ATT, HRV_2U_ATT, HRV_2L_ATT, HRV_3U_ATT, HRV_3L_ATT, HRV_4U_ATT and HRV_4L_ATT are set to 15.5"); mois_tmcheck("Check that parameters HRH_LOCK_LO1_S, HRH_LOCK_LO2_S, HRH_LOCK_LO3_S, HRH_LOCK_LO4_S, HRH_LOCK_LO5_S, HRH_LOCK_LO6_S, and HRH_LOCK_LO7_S are all Locked"); mois_tmcheck("Check that parameters HRV_LOCK_LO1_S, HRV_LOCK_LO2_S, HRV_LOCK_LO3_S, HRV_LOCK_LO4_S, HRV_LOCK_LO5_S, HRV_LOCK_LO6_S, and HRV_LOCK_LO7_S are all Locked"); Check_HRS_LO_proc_ops(["wb","wb"],hrsH_LO[0],hrsH_LO[1],hrsH_LO[2],hrsH_LO[3],hrsH_LO[4],hrsH_LO[5],hrsH_LO[6],hrsV_LO[0],hrsV_LO[1],hrsV_LO[2],hrsV_LO[3],hrsV_LO[4],hrsV_LO[5],hrsV_LO[6]); } //LOU Checks: if(sequence_order == "down") { mois_tmcheck("Check that parameter HL_MODE_S is standby"); mois_tmcheck("Check that parameter HL_Channel_S is Off"); } } // Switch on LO band - version using the slew towards a fixed point for // stabilization // assumes HIFI is prime and LO is in nominal mode obs HifiEngSwitchonLO_inslew { int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band bool robust = true; // whether the subsequent AOR is chopped+spectroscopic }{ // First part - determine timing and telescope parameters // Fixed parameters int data_time = 4; // Data readout period {double,double} eff_resolution = {1.1,1.1}; // Native WBS resolution as goal resolution // Get reference frequency string keyfreqname = "keyfreq"; //this is for warm LO operations // "keyfreq" for cold LO operations // "keyfreq_dummy" for dummy LO operations // "midfreq" old approach double[] result_d = CalibrationReader("name_keyfreq",[keyfreqname],band,0.0); double lo_freq = result_d[0] * 1000.0; // Backend settings // standard routine from spectral scans {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,2,true,true,data_time); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; // Call specific pre_timing computer {int,int,int,int,int,int} pre_timing = SwitchOnLoadChop_pre_timing(band,lo_freq,eff_resolution,hr1,hr2,wb1,wb2,data_time,robust); // get parameters for fine pointing int totaltime = pre_timing{0}; // total duration for check int on_pointing = pre_timing{1}; // Pointing time int initlength = pre_timing{2}; // Initial setup time int dangling = pre_timing{3}; // Final load measurement int n_cycles1 = pre_timing{4}; // Number of chop cycles before retuning int n_cycles = pre_timing{5}; // Number of chop cycles after retuning // In the slew mode we rearrange the times initlength = initlength + on_pointing; on_pointing = dangling; dangling = 0; // Prepare telescope command {double,double} onPosition = {ra,dec}; // standard timing parameter list to reuse Fine_telescope procedure {int,int,int,int,int,int,bool,int,int} std_timing = {on_pointing,on_pointing,on_pointing,0,0,0,false,initlength,dangling}; {int,int,int,string,int,double,double,double,double,int} tpar_f = Fine_telescope(naifid,onPosition,band,lo_freq,std_timing); // Call telescope command int[] telescopetimes = basic_fine_pointing(true,tpar_f{0},tpar_f{1},tpar_f{2},tpar_f{3},tpar_f{4},tpar_f{5},tpar_f{6},tpar_f{7},tpar_f{8},tpar_f{9}); }{ // Second part - instrument commanding // Get final deceleration time from the telescope section int telinit = telescopetimes[1]; // Initial slew time int tend = telescopetimes[2]; // Final deceleration time totaltime = totaltime + tend + telinit - initlength; // Backend settings // Create a composite readout structure {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hr1{0},hr1{1},hr1{3}},{hr2{0},hr2{1},hr2{3}},wb1,wb2}; // additional fixed parameters like in standard observing modes // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] rates = dataparms{1}; int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); ////////////////// // Instrument commanding sync(); int startobs = time(); // use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 1) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); // Actual switch-on // The switch will always be done at the same frequency LCU_switchon_proc_aot(band,lo_freq / 1000.0); // Initial setup and LO tuning Init_Mixing_proc_aot(band,lo_freq / 1000.0); //Deflux will do be done for bands 1 to 4 Deflux_SingleBand_proc_aot(band,lo_freq / 1000.0); // Standard backend tuning string target_name = "normal"; // Name of target level if(wb1{0} || wb2{0}) { WBS_attenuators_block(band,lo_freq / 1000.0,target_name,false); } if(hr1{0} || hr2{0}) { HRS_tune_block_aot(band); } // First load measurement HIFISetHK("normal",false); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); // ON integration - long hot-cold measurement if(n_cycles1 > 0) { HIFI_Calibrate_hot_cold(band,lo_freq,data_time,2 * n_cycles1,backendreadoutparms,false); HIFITuneFreq(band,lo_freq,false,""); } HIFI_Calibrate_hot_cold(band,lo_freq,data_time,2 * n_cycles,backendreadoutparms,false); } if(state[0] == 3) { delay(readoutdead); // Perform final load measurement LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); HIFICloseObs(); } } // Finalize observations // consistency check int timeTaken = time() - startobs; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } // Noise estimates could be easily added, but are not done here // in the current implementation } // Chopper calibration for a given mixer band, procedure procedure Chopper_calibration_proc_fm { int band = 1 in [1,7]; // HIFI mixer band int integ_time = 4; //Integration time PER PHASE for the slowchop measurement bool shutter_used = false; bool sky = true; //whether or not we scan over M3 area string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3 }{ string chopmode = "slowchop"; //close shutter if necessary if(shutter_used) { //Shutter_rotate_proc_fm("closed"); } //Tune backends on the hot load Chopper_Rotation_block_fm("" + band + "a","chop_M3_ang","chop_hot_ang"); //Configure and tune backends WBS_calib_fm("" + band + "a"); WBS_tune_proc_fm("" + band + "a"); HRS_tune_block_fm("" + band + "a"); //The chopper scan is done in slowchop mode to avoid short term instabilities int[] res = Configure_Spectrometer_hc_slow_chop_proc_fm("" + band + "a",integ_time * 2,["wb1","wb1"],"both"); int total_time = res[0] * res[1]; int n_wbs1 = 0; //we use the slowchop mode int n_hrs_trans = 0; //we use the slowchop mode double chop_phase = 1.0; //we use the slowchop mode // //If HEB bands, chop faster with fastchop: 1Hz if(band > 5) { chop_phase = 0.5; res = Configure_Spectrometer_fast_chop_proc_fm("" + band + "a",integ_time * 2,chop_phase,["wb1","wb1"],"both"); total_time = iceil(chop_phase * double(res[1] * res[2])); n_wbs1 = res[2]; n_hrs_trans = res[3]; chopmode = "fastchop"; } // //Get voltages for start and end positions, and number of steps {double,string}[] result_d = ConfigurationReader("name_confilchopcalib",["chop_start","chop_end","chop_nstep","chop_start_sky","chop_end_sky","chop_nstep_sky"],"" + band + "a",double(band)); double chopper_pos_min = result_d[0]{0}; double chopper_pos_max = result_d[1]{0}; int n_steps = iround(result_d[2]{0}); if(sky) { chopper_pos_min = result_d[3]{0}; chopper_pos_max = result_d[4]{0}; n_steps = iround(result_d[5]{0}); } // Chopper_scan_fm("" + band + "a",chopper_pos_min,chopper_pos_max,n_steps,total_time,"both",chopmode,n_wbs1,n_hrs_trans,false,shutter_used,hrs_mode,chop_phase); } {int,double,double,double,double,double} obs HifiSScanModeFastDBS { string modeName = "freq"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 10 in [4,80]; // data dump interval int n_int_on = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_switch_on = 1 in [1,1800]; // number of data transfer cycles per pointing int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int n_cycles = 1 in [1,600]; // Number of half OFF-ON-ON-OFF cycles at one frequency int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode OpenMessages("HIFI Spectral Scan - DBS fastChop",{data_time,0,n_switch_on,n_int_on,0,0,0,n_freq_point,n_cycles,load_interval}); // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,redundancy,wbs1Used,wbs2Used,data_time / 2); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; ////////////////////////////////////////////////////////////////////// // Call first part of the timing computer {{int,int,int,int,int,int,int,int,int,bool,int,int,int},{int,double,double[],int[][],bool,double[],int,bool}} pre_timing = FastSScanDBS_pre_timing(band,lo_freq,lo_freq_up,redundancy,effResolution,hr1,hr2,wb1,wb2,data_time,n_int_on,n_switch_on,n_freq_point,n_cycles,load_interval,docommands); // frequency parameters int groupnumber = pre_timing{1}{0}; double reffreq = pre_timing{1}{1}; double[] freqgrid = pre_timing{1}{2}; int[][] grouporder = pre_timing{1}{3}; bool retuning = pre_timing{1}{4}; double[] targetlevels = pre_timing{1}{5}; int nfreq_if = pre_timing{1}{6}; bool dsb = pre_timing{1}{7}; int n_total = groupnumber * n_cycles; ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,int,int,int,int,int,int} tpar = DBS_telescope(naifid,onPosition,band,reffreq,"",pre_timing{0},n_total); // Dummy call to spacecraft command int[] telescopetimes = nodding_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},false); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,bool,int,int,int},double,double,double} post_timing = SScanDBS_post_timing(pre_timing{0},telescopetimes,n_freq_point,groupnumber,n_cycles,true); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = DBS_telescope(naifid,onPosition,band,reffreq,"",post_timing{1},n_total); // Call telescope command telescopetimes = nodding_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},false); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following // normal pre_timing values int n_loadinterval = post_timing{1}{7}; int n_bchop = post_timing{1}{8}; int shiftlength = post_timing{1}{10}; int initlength = post_timing{1}{11}; double avnumchop = post_timing{2}; // efficiency parameters double tscan = post_timing{3}; double tdead = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { FastSScanDBS_commanding(band,reffreq,effResolution,hr1,hr2,wb1,wb2,n_freq_point,grouporder,freqgrid,retuning,targetlevels,data_time,n_int_on,n_cycles,n_total,n_bchop,n_switch_on,n_loadinterval,startobs,telescopetimes,shiftlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double} tact = FastSScanDBS_deadtimes(band,reffreq,hr1,hr2,wb1,wb2,n_freq_point,data_time,n_int_on,n_bchop,n_switch_on,n_cycles,avnumchop,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = SScanDBS_noisecomputer(band,reffreq,nfreq_if,dsb,effResolution,continuumDetection,n_cycles,tscan,tact); // Evaluate performance SScanDBS_performance(band,reffreq,nfreq_if,dsb,effResolution,noisevalues,timeTaken,n_total,groupnumber * n_freq_point,avnumchop * double(n_int_on),tscan,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } //////////////////////////////////// // Auxiliary function to compute the noise of an ideal instrument with // 100% observing efficiency for comparison {int,double,double,double,double,double} procedure IdealHifi { /* Setup parameters */ string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz int redundancy = 4; // Frequency scan redundancy int nlines = 1 in [1,240]; // Number of rows in the map int npoints = 10 in [1,720]; // Number of data dumps per row {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz int goalTime = 8; // Total integration time /* Sequence parameters */ bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode // Get parameters which are needed double center_lo_freq = 0.5 * (lo_freq + lo_freq_up); double tsys = InterpolateTsys(band,center_lo_freq); double eta_mb = InterpolateCoupling(band,center_lo_freq); double[] gssb = InterpolateGssb(band,center_lo_freq); double phasetime = double(goalTime); double noiseratio = 0.0; // Compute total double sideband noise double dsbnoise_lores = tsys * sqrt(1.0 / (effResolution{1} * 1000000.0 * phasetime)); double dsbnoise_hires = tsys * sqrt(1.0 / (effResolution{0} * 1000000.0 * phasetime)); // Translate to the main beam scale, correct for eta_mb // (This is typically not done at ground based telescopes, // but leads often to problems there - to be discussed.) dsbnoise_lores = dsbnoise_lores / eta_mb; dsbnoise_hires = dsbnoise_hires / eta_mb; // Get single sideband noise equivalent double usbnoise_lores = dsbnoise_lores / gssb[0]; double usbnoise_hires = dsbnoise_hires / gssb[0]; double lsbnoise_lores = dsbnoise_lores / gssb[1]; double lsbnoise_hires = dsbnoise_hires / gssb[1]; // return total time with initial slew int returntime = goalTime; // Originally I had added 180s from telescope // Now make corrections for maps or spectral scans if(npoints * nlines > 1) { double factor = sqrt(double(nlines * npoints)); usbnoise_lores = usbnoise_lores * factor; usbnoise_hires = usbnoise_hires * factor; lsbnoise_lores = lsbnoise_lores * factor; lsbnoise_hires = lsbnoise_hires * factor; } if(lo_freq_up > lo_freq) { {int,double,double[],int[][],int,bool} fqparms = MakeFreqGrid(band,lo_freq,lo_freq_up,redundancy,0.0,1); factor = sqrt(double(fqparms{0} / fqparms{4})); usbnoise_lores = usbnoise_lores * factor; usbnoise_hires = usbnoise_hires * factor; lsbnoise_lores = lsbnoise_lores * factor; lsbnoise_hires = lsbnoise_hires * factor; } // Return noise values and the maximum ratio of drift to radiometric noise return {returntime,usbnoise_lores,usbnoise_hires,lsbnoise_lores,lsbnoise_hires,noiseratio}; } // Switch HIFI off, block // Prime and Redundancy are both called, regardless of which is effectively used // block HIFI_global_switch_off_block_fm HIFI 3921 { }{ Start_block(); //Sequentially notify PDU off then switch off S/S //This maybe non-instictive order is due to an ICU bug that //screws things up when the ICU tries to get HK from a switched off S/S // //LOU Hifi_HIFI_notify_PDU_status("ON","OFF","ON","ON","ON","ON"); //HifiIltEgse_PDU_switch_off($BBID,"LO_Prime"); //HifiIltEgse_PDU_switch_off($BBID,"LO_Red"); //WBS-H Hifi_HIFI_notify_PDU_status("ON","OFF","ON","OFF","ON","ON"); //HifiIltEgse_PDU_switch_off($BBID,"WBS_H"); //WBS-V Hifi_HIFI_notify_PDU_status("ON","OFF","OFF","OFF","ON","ON"); //HifiIltEgse_PDU_switch_off($BBID,"WBS_V"); //HRS-H Hifi_HIFI_notify_PDU_status("ON","OFF","OFF","OFF","ON","OFF"); //HifiIltEgse_PDU_switch_off($BBID,"HRS_H"); //HRS-V Hifi_HIFI_notify_PDU_status("ON","OFF","ON","OFF","OFF","OFF"); //HifiIltEgse_PDU_switch_off($BBID,"HRS_V"); //ICU Hifi_HIFI_notify_PDU_status("OFF","OFF","OFF","OFF","OFF","OFF"); //HifiIltEgse_PDU_switch_off($BBID,"ICU_Prime"); //HifiIltEgse_PDU_switch_off($BBID,"ICU_Red"); //At that stage, the instrument is idle... } //Procedure to get from standby to primary mode //Concerns LO and WBS settings procedure HifiIntoPrimary { }{ //Switch LO to nominal Set_LO_Nominal_block_aot(); //Set applicable LO FDIR limits (SCR-2226) Set_LO_FDIR_temperatures_block_aot(); } //Reduced version: IVC //HIFI-COP-7.2-FPU_FT procedure FPU_FT_IVC_COP_proc_ops { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b","8"]; // HIFI band string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ //General parameters in use string hbb_heater = "ON"; //hot source on/off string chopper_loop = "CLOSE"; // string chop_startup_prime_red = "chop_startup_cold_prime"; if(prime_or_redundant == "Red") { chop_startup_prime_red = "chop_startup_cold_red"; } {double,string}[] result = ConfigurationReader("name_chopper",[chop_startup_prime_red],"0",0.0); if(chopper_loop == "OPEN") { result = ConfigurationReader("name_chopper",["chop_startup_warm"],"0",0.0); } double[] cresult_d = CalibrationReader("name_keyfreq",["keyfreq"],band,0.0); double lo_freq = cresult_d[0]; //applies to cold LO Init_MSA_ops(band,chopper_loop,lo_freq,result[0]{0},hbb_heater,prime_or_redundant); // //IVC IVcurve_raw_fm(band); // } //Readback of LCU Memory Patch, block procedure LCU_readback_TPF_maker { string section = "P" in ["P","R"]; }{ // //{int, int[]} [] runs = LcuGetMemoryRuns_ops( section); {int,int[]}[] runs = LcuGetMemoryRuns(section,1); int runcount = length(runs); if(runcount != 0) { for(int i = 0 .. runcount - 1) { int count = length(runs[i]{1}); Hifi_HIFI_WBS_Zero(runs[i]{0}); Hifi_HIFI_WBS_Zero(count); } //Complement the number of TCs sent to reach the fixed TC pattern needed for TPF int nb_TC_needed = 50; int remaining_TC = nb_TC_needed - runcount; mois_comment("The following " + remaining_TC + " TCs are dummy repetition of the first memory dump command"); // for(int ii = 1 .. remaining_TC) { Hifi_HIFI_WBS_Zero(runs[0]{0}); Hifi_HIFI_WBS_Zero(length(runs[0]{1})); } } } //Load and boot new OBSW from rescue, block block Load_boot_block_ops HIFI 7929 { }{ // mois_step("Construct the OBSW copy"); mois_spacon("Use the OBSM or OBS-loader to prepare the load_mem TC list to build the new version of the OBSW that is to be loaded and started"); // mois_step("Upload the OBSW copy to DM"); mois_spacon("Use the OBSM or OBS-loader to run the TC list previously prepared to load the new version of the OBSW"); // mois_step("Run the load boot TC"); Hifi_HIFI_load_boot(); delay(1); //The new OBSW should be booted mois_tmcheck("Check that the new OBSW release numbers have been updated (HI_SW_Version, HI_SW_Revision and HI_SW_Patch)"); // mois_comment("Assign obsid number to procedure execution"); mois_spacon("In the following command, the second parameter (OBS_ID) shall be replaced by a Formal Parameter value according to the list provided by the instrument ICC."); Hifi_HIFI_Set_OBS_ID($BBID,$OBSID); // //Do we want to copy the new image onto the EEPROM ? //TC for this: Hifi_HIFI_eeprom_write -> decided to rather prepare a dedicated procedure for this. } // upload of memory patch table, block //Prime/Redundant is handled with the CUS table block LcuMemoryPatchUpload_fm HIFI 3902 { }{ Start_block(); string section = GetLcuSection(); {int,int[]}[] runs = LcuGetMemoryRuns(section,100); int runcount = length(runs); for(int i = 0 .. runcount - 1) { {int}[] par = []; int[] values = runs[i]{1}; int count = length(values); for(int j = 0 .. count - 1) { par[j] = {values[j]}; } int crc = checksum("short",values); Hifi_HIFI_load_LCU(runs[i]{0},count,par,crc); delay(2); } } // Very Short Performance Test, procedure // Assumes LO is stabilized, in nominal mode, and instrument is ready to be configured // Also assumes backends are ready // This is to be used in cold context procedure HIFI_VSPT_proc { string band = "1a"; // HIFI band double lo_freq = 500.0; //LO frequency string mixer_polarization = "H" in ["H","V","B"]; //Polarization: H, V or Both string backend_code = "WBS" in ["WBS","HRS"]; //The backend to be used for magnet tuning string chop_loop = "CLOSE"; //The chopper loop status string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int integ_time = 4; //Total integration time in sec. string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string mixer_for_tuning = "H" in ["H","V","B"]; //Polarization: H, V or both }{ // //Configure FPU //The chopper will look at rest position per default // if(mixer_polarization == "H") { if(mixer_for_tuning == "V") { error("V mixer cannot be used for tuning since only mixer H was selected."); } if(band == "0") { Band0_hbb_on_fm(band,chop_loop); } else { Init_MSA_H_fm(band,chop_loop,lo_freq); } } if(mixer_polarization == "V") { if(mixer_for_tuning == "H" || mixer_for_tuning == "B") { error("H mixer cannot be used for tuning since only mixer V was selected."); } if(band == "0") { Band0_hbb_on_fm(band,chop_loop); } else { Init_MSA_V_fm(band,chop_loop,lo_freq); } } if(mixer_polarization == "B") { if(band == "0") { Band0_hbb_on_fm(band,chop_loop); } else { Init_MSA_fm(band,chop_loop,lo_freq,"ON"); } } // //Set-up LO at new frequency and performs tuning at that frequency. //Assumes the band was already switched on prior to the VSPT. //Also assumes we are in nominal mode. LO_tuning_w_mixerchoice_block_fm(band,lo_freq,mixer_for_tuning); // //Magnet tuning: only up to band 5 since band6-7 have no magnets if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { {double,string}[] result_d = ConfigurationReader("name_configwbs",["tune_target_magnet"],band,lo_freq); int tune_target_magnet = iround(result_d[0]{0}); Magnet_tuning_block_fm(band,lo_freq,backend_code,tune_target_magnet); } // //Spectrometer attenuator tuning: should be done on Hot source Chopper_Rotation_block_fm(band,"chop_M3_ang","chop_hot_ang"); // //WBS calibration and backend tuning if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band); WBS_tune_proc_fm(band); } if(backend == "hrs" || backend == "both") { HRS_tune_block_fm(band); } // //Configure spectrometers after tuning int[] res = Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); // //HotCold measurement Hot_cold(band,hrs_mode,backend,res[0] * res[1],"tp",0,0); // } //Procedure to translate old band name into new convention string procedure Translate_band_name { string band = "1a"; //"OLD" band naming }{ //Translate band name string band_new = "1a"; if(band == "1a") { //Band 1a band_new = "1a"; } if(band == "1b") { //Band 1b band_new = "1b"; } if(band == "2a") { //Band 2a band_new = "2a"; } if(band == "2b") { //Band 2b band_new = "2b"; } if(band == "3a") { //Band 3a band_new = "3a"; } if(band == "3b") { //Band 3b band_new = "3b"; } if(band == "4a") { //Band 4a band_new = "4a"; } if(band == "4b") { //Band 4b band_new = "4b"; } if(band == "5a") { //Band 5a band_new = "5a"; } if(band == "5b") { //Band 5b band_new = "5b"; } if(band == "6a") { //Band 6a band_new = "6a"; } if(band == "6b") { //Band 6b band_new = "6b"; } if(band == "7a") { //Band 7a band_new = "7a"; } if(band == "7b") { //Band 7b band_new = "7b"; } return band_new; } // Generic A_M function for LSU setting // DT - 18 Aug 2006 int[] procedure ComputeLSU_A_M_R { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978.2; //LO frequency }{ //Read parameters double[] result = CalibrationReader("name_lsu_convertion",["multiplier","f_offset","n10","n20"],band,lo_freq); double multiplier = result[0]; double f_offset = result[1]; int n10 = iround(result[2]); int n20 = iround(result[3]); // //Compute LSU frequency IN MHZ double f_lsu = lo_freq * 1000.0 / multiplier; //Compute total frequency double f_total = f_lsu + f_offset; //Compute parameter n int n = ifloor(15.0 * (f_total / 1.875 - double(ifloor(f_total / 1.875)))); //Compute main and offset loop parameters int n1 = n10 + n; // offset loop int d1 = 15; //offset loop int n2 = iround(abs(double(n20 - ifloor(f_total / 1.875) + n))); //main loop int d2 = 16; // //Compute A,M and R parameters for main and offset loop int m1 = ifloor(double(n1) / 10.0) - 1; // offset loop int a1 = n1 - 10 * ifloor(double(n1) / 10.0); // offset loop int r1 = d1 - 1; // offset loop int m2 = ifloor(double(n2) / 10.0) - 1; // main loop int a2 = n2 - 10 * ifloor(double(n2) / 10.0); // main loop int r2 = d2 - 1; // main loop // int[] lsu_a_m_r_parameter = [0,0,0,0,0,0]; lsu_a_m_r_parameter[0] = m1; lsu_a_m_r_parameter[1] = a1; lsu_a_m_r_parameter[2] = r1; lsu_a_m_r_parameter[3] = m2; lsu_a_m_r_parameter[4] = a2; lsu_a_m_r_parameter[5] = r2; // //Conversion into main and offset LSU word int main_word = iround(pow(2.0,18.0) * double(ifloor(double(r2) % pow(2.0,6.0) / pow(2.0,4.0))) + pow(2.0,15.0) * double(ifloor(double(m2) % pow(2.0,9.0) / pow(2.0,7.0))) + pow(2.0,8.0) * (double(m2) % pow(2.0,9.0)) + pow(2.0,4.0) * (double(r2) % pow(2.0,6.0) % pow(2.0,4.0)) + double(a2) % pow(2.0,4.0)); int offset_word = iround(pow(2.0,18.0) * double(ifloor(double(r1) % pow(2.0,6.0) / pow(2.0,4.0))) + pow(2.0,15.0) * double(ifloor(double(m1) % pow(2.0,9.0) / pow(2.0,7.0))) + pow(2.0,8.0) * (double(m1) % pow(2.0,9.0)) + pow(2.0,4.0) * (double(r1) % pow(2.0,6.0) % pow(2.0,4.0)) + double(a1) % pow(2.0,4.0)); // //debug_print("LSU conversion result " + lsu_a_m_r_parameter); //debug_print("main: " + main_word + ", offset: " + offset_word); // //Compute real LO frequency set by A,M,R combination double nn1 = double(10 * (m1 + 1) + a1); double dd1 = double(r1 + 1); double nn2 = double(10 * (m2 + 1) + a2); double dd2 = double(r2 + 1); double flsu_back = 24000.0 + 30.0 * (nn1 / dd1 + nn2 / dd2); if(band == "2a" || band == "3b") { flsu_back = 24000.0 + 30.0 * (nn1 / dd1 - nn2 / dd2); } double flo_back = flsu_back * multiplier; //debug_print("Real tuned frequency: " + flo_back); // int[] resu = [0,0]; resu[0] = main_word; resu[1] = offset_word; //Modification following SPR-1302 resu = [resu[0] + 0xf2200000,resu[1] + 0xf2300000]; // return resu; } // Noise ratio from an OTF line for the special case of a // multiple scan of the same line // double procedure OtfRepeatedNoiseRatio { double num_scans = 2.0; // number of scans of the same line double n = 10.0; // number of points in one scan double[] parameters = [0.02,0.4,0.05,0.667,2.5]; // Parameters: integration time, delay and turn-around relative to Allan time, ratio of t_off time to sqrt(n)*t_on, line length, drift exponent }{ // Assign parameters double x = parameters[0]; double d = parameters[1]; double doff = parameters[2]; double qval = parameters[3]; double alpha = parameters[4]; // Make corrections for different calibration double qcorr = qval * sqrt(num_scans); {double,double} noisevalues = OtfNoiseValues(num_scans * n,[x,d,doff,qcorr,alpha]); double yn = noisevalues{0}; yn = yn / num_scans; double yd = noisevalues{1}; // Compute ratio double y = yd / yn; return y; } // thermal tests, fast: this is the quick health check // Follows description of FPSS-01204 block Thermal_fast_fm HIFI 3281 { string band = "1a"; // HIFI band double lo_freq = 522.0; //LO frequency }{ //Start_block(); {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band"],band,lo_freq); int band_nb = iround(result_d[0]{0}); // //Get Targetted values for magnet, mixer bias, heater time and diplexer double[] cresult_d = CalibrationReader("name_configthermal",["dipl_h","magn_h","mbias_h","heat_h","dipl_v","magn_v","mbias_v","heat_v"],band,0.0); double target_dipl_h = cresult_d[0]; double target_magn_h = cresult_d[1]; double target_mbias_h = cresult_d[2]; double target_heat_h = cresult_d[3]; double target_dipl_v = cresult_d[4]; double target_magn_v = cresult_d[5]; double target_mbias_v = cresult_d[6]; double target_heat_v = cresult_d[7]; // //Read SIF cresult_d = CalibrationReader("name_configthermal",["sif1hv","sif1hc","sif2hv","sif2hc","sif3hv","sif3hc"],band,0.0); double volt_H_SIF_1 = cresult_d[0]; double curr_H_SIF_1 = cresult_d[1]; double volt_H_SIF_2 = cresult_d[2]; double curr_H_SIF_2 = cresult_d[3]; double volt_H_SIF_3 = cresult_d[4]; double curr_H_SIF_3 = cresult_d[5]; // cresult_d = CalibrationReader("name_configthermal",["sif1vv","sif1vc","sif2vv","sif2vc","sif3vv","sif3vc"],band,0.0); double volt_V_SIF_1 = cresult_d[0]; double curr_V_SIF_1 = cresult_d[1]; double volt_V_SIF_2 = cresult_d[2]; double curr_V_SIF_2 = cresult_d[3]; double volt_V_SIF_3 = cresult_d[4]; double curr_V_SIF_3 = cresult_d[5]; // //Read FIF: these are the nominal values cresult_d = CalibrationReader("name_configthermal",["fif1v","fif1c","fif2v","fif2c"],band,0.0); double volt_H_FIF_1 = cresult_d[0]; double curr_H_FIF_1 = cresult_d[1]; double volt_H_FIF_2 = cresult_d[2]; double curr_H_FIF_2 = cresult_d[3]; // double volt_V_FIF_1 = cresult_d[0]; double curr_V_FIF_1 = cresult_d[1]; double volt_V_FIF_2 = cresult_d[2]; double curr_V_FIF_2 = cresult_d[3]; // //Get chopper settings string chop_sine_s = "ON"; string chop_loop = "CLOSE"; result_d = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2"],band,lo_freq); int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // result_d = ConfigurationReader("name_confilfpu",["calibrator_current_on"],band,lo_freq); double calibcurrent = result_d[0]{0}; double bias_H = target_mbias_h; double magnetcurrent_H = target_magn_h; double diplex_H = target_dipl_h; double bias_V = target_mbias_v; double magnetcurrent_V = target_magn_v; double diplex_V = target_dipl_v; result_d = ConfigurationReader("name_confilfpu",["chop_cold"],band,lo_freq); double chopper = result_d[0]{0}; chopper = Check_Chopper_Prime_Redundant(chopper); // //Get diplexer codes if(band_nb <= 2 || band_nb == 5) { int diplex_h_ctrl_mode = 0; int diplex_v_ctrl_mode = 0; } else { //Get diplexer currents result_d = ConfigurationReader("name_confilfpu",["diplex_h_ctrl_mode","diplex_v_ctrl_mode"],band,lo_freq); diplex_h_ctrl_mode = iround(result_d[0]{0}); diplex_v_ctrl_mode = iround(result_d[1]{0}); } // //1. Switch on diplexer, SIF, FIF, magnets and mixer bias // //Send command to FPU and wait 25 min. HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(1500); // //2. Check heater current effect on temperature: Let current ON // during the standard deflux time. //We will bias the junction at low bias to check when //the heater effect is effective result_d = ConfigurationReader("name_confilfpu",["bias_very_low_h","bias_very_low_v"],band,lo_freq); bias_H = result_d[0]{0}; bias_V = result_d[1]{0}; Mixerbias(bias_H,bias_V); // //Magnets need to be switched to 0 prior to the deflux Hifi_HIFI_CH1_MX_MG_C($BBID,0.0); Hifi_HIFI_CV1_MX_MG_C($BBID,0.0); delay(1); // //Get time during which one wants to send the pulse double max_heater_time_h = target_heat_h * 1000.0; //in msec double max_heater_time_v = target_heat_v * 1000.0; //in msec //Start to send the pulse //H-polar first Hifi_HIFI_HF_CH1_DHTR_C($BBID,max_heater_time_h); delay(iceil(max_heater_time_h / 1000.0) + 1); //V-polar then Hifi_HIFI_HF_CV1_DHTR_C($BBID,max_heater_time_v); delay(iceil(max_heater_time_v / 1000.0) + 1); // //3. Heater back to 0: achieved automatically after the above is elapsed. //Extra delay to cool down in band 0 before switch to next band Band0_chopper_on_proc_fm("0","CLOSE"); //Wait another 25 minutes delay(1500); // } //Readback of LCU Memory Patch, block block LcuMemoryPatchReadback_fm HIFI 3903 { }{ Start_block(); string section = GetLcuSection(); {int,int[]}[] runs = LcuGetMemoryRuns(section,498); int runcount = length(runs); for(int i = 0 .. runcount - 1) { int count = length(runs[i]{1}); Hifi_HIFI_dump_memory("LCU",runs[i]{0},count); // delay( iceil( double( count ) *.003 ) ); // 3 msec per word readout // Workaround delay(2 + iceil(double(count) * 0.0030)); // 3 msec per word readout } } // Initialisation of FPU, block with only V-MSA in use // It is only for cold context ! block Init_MSA_V_fm HIFI 3208 { string band = "1a"; string chop_loop = "CLOSE"; double lo_freq = 522.0; //LO frequency }{ Start_block(); {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band"],band,lo_freq); int band_nb = iround(result_d[0]{0}); double diplex_H = 0.0; double diplex_V = 0.0; int diplex_h_ctrl_mode = 0; int diplex_v_ctrl_mode = 0; // result_d = ConfigurationReaderWarm("name_confilfpu",["fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],"0",0.0); // double volt_H_FIF_1 = result_d[0]{0}; double curr_H_FIF_1 = result_d[1]{0}; double volt_H_FIF_2 = result_d[2]{0}; double curr_H_FIF_2 = result_d[3]{0}; // double volt_H_SIF_1 = result_d[4]{0}; double curr_H_SIF_1 = result_d[5]{0}; double volt_H_SIF_2 = result_d[6]{0}; double curr_H_SIF_2 = result_d[7]{0}; double volt_H_SIF_3 = result_d[8]{0}; double curr_H_SIF_3 = result_d[9]{0}; // result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,lo_freq); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // string chop_sine_s = "ON"; // string chop_loop = "CLOSE" ; result_d = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current_on"],band,lo_freq); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // double calibcurrent = result_d[7]{0}; // //Get biases result_d = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); double bias_H = result_d[0]{0}; double bias_V = result_d[1]{0}; //For bands 6 and 7, first set to 4mV if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { result_d = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,lo_freq); bias_H = result_d[0]{0}; bias_V = result_d[1]{0}; } // //Get magnets: not applicable to bands 6 and 7 double magnetcurrent_H = 0.0; double magnetcurrent_V = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,lo_freq); magnetcurrent_H = result_d[0]{0}; magnetcurrent_V = result_d[1]{0}; } //Diplexer is interpolated from a table for Bands 3, 4, 6L and 6H if(band_nb <= 2 || band_nb == 5) { diplex_H = 0.0; //For bands 1, 2 and 5 diplex_V = 0.0; diplex_h_ctrl_mode = 0; diplex_v_ctrl_mode = 0; } else { //Get diplexer currents result_d = ConfigurationReader("name_confilfpu",["diplex_h_ctrl_mode","diplex_v_ctrl_mode"],band,lo_freq); diplex_h_ctrl_mode = iround(result_d[0]{0}); diplex_v_ctrl_mode = iround(result_d[1]{0}); double[] result_dip = Get_Diplexer_setting(band,lo_freq); diplex_H = result_dip[0]; diplex_V = result_dip[1]; } // result_d = ConfigurationReader("name_chopper",["chop_startup_cold"],band,0.0); if(chop_loop == "OPEN") { result_d = ConfigurationReader("name_chopper",["chop_startup_warm"],band,0.0); } double chopper = result_d[0]{0}; //For this configuration we won't convert prime chopper voltage into redundant voltage //Just checking we are in range. //chopper = Check_Chopper_Prime_Redundant(chopper); chopper = Check_Chopper_Range(chopper); // //Switch on upconverter, assuming chopper and mixers are also ON Hifi_HIFI_Configure_FCU_Power($BBID,"ON","ON","ON","ON","ON"); // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result_d = ConfigurationReader("name_delays",["config_fpu_delay"],band,lo_freq); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // //In case of band 6 or 7, bias have been set to 4mV. Now set to nominal if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { {double,string}[] result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); Mixerbias(result[0]{0},result[1]{0}); } // //Magnet are so far at maximum value. Now set to nominal if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); Hifi_HIFI_CH1_MX_MG_C($BBID,result_d[0]{0}); Hifi_HIFI_CV1_MX_MG_C($BBID,result_d[1]{0}); delay(1); } // Hifi_HIFI_non_periodic_hk_FCU(); } //Shutter rotation during peakup in ILT context, procedure //Shutter is used to partially blind external BB load procedure Peakup_shutter_rotation_proc_fm { string band = "1" in ["1","2","3","4","5","6","7"]; // HIFI band int position = 1 in [1,9]; //peakup pattern sequence number: from 1 to 9 string peakup_matrix = "centred" in ["centred","offseted","flat"]; //Which brightness distribution to simulate with shutter }{ //Get number of shutter rotation steps depending on position number string band_nb = band + "a"; string name_shutter_pos = "name_shutter_pos_centred"; if(peakup_matrix == "offseted") { name_shutter_pos = "name_shutter_pos_offseted"; } {double,string}[] result = ConfigurationReader(name_shutter_pos,["shutter_step"],band_nb,double(position)); //If flat distribution is chosen, the shutter should not be moved int shutter_step = iround(result[0]{0}); if(peakup_matrix == "flat") { shutter_step = 1; } // //Rotate shutter: number of steps is accounted from open position //HifiIltEgse_FPU_set_shutter_betw($BBID,shutter_step); //Fixed delay result = ConfigurationReader(name_shutter_pos,["shutter_delay"],band_nb,double(position)); delay(iround(result[0]{0})); // } /////////////////////////////////////////////////////////////////////////////// // Subroutine for HRS settings shared between ConfigSpectroscopy and DataTaking {int,int,int,int} procedure HrsSubbandSelection { /* Backend settings */ {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // HRS1/2 {used,resolution,subbands}, WBS1/2 {used, channel windows} }{ // Seection of HRS subbands in correct order int[] widebits = [129,66,36,24]; // [10000001,01000010,00100100,00011000] int[] lowbits = [192,48,12,3]; // [11000000,00110000,00001100,00000011] int[] normalbits = [240,15]; // [11110000,00001111] int[] highbits = [255]; // [11111111] // HRS-H int hrsh_sel = 0; int n_hchannels = 0; if(backendreadoutparms{0}{0} == true) { // normal resolution int maxbands = 2; int[] bits = normalbits; int n_perband = 2064; if(backendreadoutparms{0}{1} > 2) { // wide resolution maxbands = 4; bits = widebits; n_perband = 1032; } else { if(backendreadoutparms{0}{1} > 1) { // low resolution maxbands = 4; bits = lowbits; n_perband = 1032; } else { if(backendreadoutparms{0}{1} < 1) { // high resolution maxbands = 1; bits = highbits; n_perband = 4128; } } } for(int i0 = 0 .. maxbands - 1) { if(backendreadoutparms{0}{2}[i0]) { hrsh_sel = hrsh_sel + bits[i0]; n_hchannels = n_hchannels + n_perband; } } } // HRS-V int hrsv_sel = 0; int n_vchannels = 0; if(backendreadoutparms{1}{0} == true) { // normal resolution maxbands = 2; bits = normalbits; n_perband = 2064; if(backendreadoutparms{1}{1} > 2) { // wide resolution maxbands = 4; bits = widebits; n_perband = 1032; } else { if(backendreadoutparms{1}{1} > 1) { // low resolution maxbands = 4; bits = lowbits; n_perband = 1032; } else { if(backendreadoutparms{1}{1} < 1) { // high resolution maxbands = 1; bits = highbits; n_perband = 4128; } } } for(int i1 = 0 .. maxbands - 1) { if(backendreadoutparms{1}{2}[i1]) { hrsv_sel = hrsv_sel + bits[i1]; n_vchannels = n_vchannels + n_perband; } } } return {hrsh_sel,hrsv_sel,n_hchannels,n_vchannels}; } {int,double,double,double,double,double} obs HifiPointModeDBS { string modeName = "dbs"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_switch_on = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per pointing int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode OpenMessages("HIFI Single Point - DBS slowChop",{data_time,0,0,n_switch_on,0,0,0,0,n_cycles,load_interval}); // Call first part of the timing computer {int,int,int,int,int,int,int,int,int,bool,int,int,int} pre_timing = DBS_pre_timing(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_switch_on,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,int,int,int,int,int,int} tpar = DBS_telescope(naifid,onPosition,band,lo_freq,"",pre_timing,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = nodding_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},false); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,bool,int,int,int},bool,double,double} post_timing = DBS_post_timing(pre_timing,telescopetimes,n_cycles); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = DBS_telescope(naifid,onPosition,band,lo_freq,"",post_timing{1},n_cycles); // Call telescope command telescopetimes = nodding_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},false); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{3}; int n_load = post_timing{1}{6}; int n_seq = post_timing{1}{8}; int n_loadinterval = post_timing{1}{7}; bool end_load = post_timing{1}{9}; int shiftlength = post_timing{1}{10}; bool final_load = post_timing{2}; double tscan = post_timing{3}; double tdead = post_timing{4}; // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { DBS_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_seq,n_load,n_loadinterval,end_load,final_load,startobs,telescopetimes,loadlength,shiftlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double} tact = DBS_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_seq,n_load,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = DBS_noisecomputer(band,lo_freq,effResolution,continuumDetection,oneGHzReference,n_cycles,tscan,tact); // Evaluate performance DBS_performance(band,lo_freq,effResolution,noisevalues,timeTaken,n_cycles,n_seq * (n_load + 1),tscan,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // Stability test, procedure, case 4 // Measurement of internal cold against external cold procedure Proc_stability_intcold_extcold { string band = "1a"; // HIFI band int n = 100; //Number of load pairs to be measured string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int integ_time = 4; //Total (co-added) integration time of a phase in sec. string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string chopmode = "slowchop" in ["slowchop","fastchop"]; //Whether to use slowchop or fastchop double chop_phase = 1.0 in [0.2,2.0]; // Chop phase length }{ // Chopper_Rotation_block_fm(band,"chop_M3_ang","chop_hot_ang"); //Look at HBB // //WBS calibration if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band); WBS_tune_proc_fm(band); } if(backend == "hrs" || backend == "both" || backend == "hrsFast") { //Configure and tune backends HRS_config_block_fm(band,hrs_mode); HRS_tune_block_fm(band); } // //Configure spectrometers integration after tuning: done later //Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); // Stability_intcold_extcold_fm(band,n,integ_time,hrs_mode,backend,chopmode,chop_phase); //Configure spectrometers integration back to default in tp mode Configure_Spectrometer_proc_fm(band,4,hrs_mode,backend); //2 sec. integration } ////////////////////////////////////////////////////////////////////////// // Auxiliary procedure to compute sum of dead times across the map {int,int,int} procedure GetAllCrossSlewTimes { int[] telescopetimes = [300,180,20,0,21,0,2,10]; int scansize = 1; // Number of points measured in one scan int n_cycles = 1; // Number of half OFF-ON-ON-OFF pointing cycles }{ // Use telescope return parameters int numpoints = telescopetimes[6]; if(scansize > 1) { // Scan return field int n_scans = numpoints / (2 * scansize * n_cycles); int sumslews = 0; int sumnods = 0; int sumreturns = 0; for(int i1 = 0 .. numpoints - 2) { int theslew = telescopetimes[i1 + 7]; if(i1 % scansize == 0) { if(i1 % (2 * scansize) == 0) { // within A-A or B-B sumreturns = sumreturns + theslew; } else { // Nod instead of slew sumnods = sumnods + theslew; } } else { sumslews = sumslews + theslew; } } // Parameters irrelevant for scansize>1 int shortmove = 0; // Main returns int tinscandead = sumnods + sumslews; int toutscandead = sumreturns; } else { // trivial computation for scansize=1; // Single point per nod int nodtime = telescopetimes[2]; // Slew time to second nod int returntime = telescopetimes[3]; // Idle time between two phases // Scan return field numpoints = telescopetimes[6]; n_scans = numpoints / scansize; sumreturns = n_scans * (n_cycles - 1) * returntime; // Initial values sumslews = 0; shortmove = returntime; // All return values for(int i2 = 0 .. numpoints - 2) { theslew = telescopetimes[i2 + 7]; sumslews = sumslews + theslew; shortmove = imin(shortmove,theslew); } tinscandead = n_scans * n_cycles * nodtime; toutscandead = sumslews + sumreturns; } return {tinscandead,toutscandead,shortmove}; } // LCU1b configuration and tuning, procedure procedure LCU1b_config_tune_proc_fm { string band = "1b"; // HIFI band double lo_freq = 600.0 in [566.0,633.0]; //LO frequency double drain_2_factor = 100.0; //Percentage factor of the targetted drain voltage }{ error("This module is obsolete: use LO_tuning_block_fm instead"); } //HIFI-COP-7.2-FT: Regular FT during PV and routine for health monitoring obs HifiEng_HealthMon_FT { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(HealthMon_FT_COP_proc_ops(prime_or_redundant)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution HealthMon_FT_COP_proc_ops(prime_or_redundant); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } // WBS configuration with laser choice, block // Both polarizations are treated block WBS_config_w_laser_and_att_block_fm HIFI 3636 { string band = "1a"; // HIFI band string laser_H = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-V laser to be set ON int[] att_h = [7,7,7,7,15]; //User input att. for optimum level H-polar int[] att_v = [7,7,7,7,15]; //User input att. for optimum level V-polar }{ //Start_block(); //H-Polarization // {double,string}[] result_d = ConfigurationReader("name_configwbs",["hwh_laser1_s","hwh_laser2_s","hwh_heater","hwh_latchup_s","hwh_att_band4","hwh_att_band3","hwh_att_band2","hwh_att_band1","hwh_att_in"],band,0.0); string hwh_laser1_s = "OFF"; string hwh_laser2_s = "OFF"; if(laser_H == "Laser1") { hwh_laser1_s = "ON"; } if(laser_H == "Laser2") { hwh_laser2_s = "ON"; } int hwh_heater = iround(result_d[2]{0}); string hwh_latchup_s = result_d[3]{1}; int hwh_att_band4 = att_h[3]; int hwh_att_band3 = att_h[2]; int hwh_att_band2 = att_h[1]; int hwh_att_band1 = att_h[0]; int hwh_att_in = att_h[4]; // result_d = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result_d[0]{0}); // //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); // //delay(wbs_config_delay); //Wait for configuration to be applied // //V-Polarization // result_d = ConfigurationReader("name_configwbs",["hwv_laser1_s","hwv_laser2_s","hwv_heater","hwv_latchup_s","hwv_att_band4","hwv_att_band3","hwv_att_band2","hwv_att_band1","hwv_att_in"],band,0.0); string hwv_laser1_s = "OFF"; string hwv_laser2_s = "OFF"; if(laser_V == "Laser1") { hwv_laser1_s = "ON"; } if(laser_V == "Laser2") { hwv_laser2_s = "ON"; } int hwv_heater = iround(result_d[2]{0}); string hwv_latchup_s = result_d[3]{1}; int hwv_att_band4 = att_v[3]; int hwv_att_band3 = att_v[2]; int hwv_att_band2 = att_v[1]; int hwv_att_band1 = att_v[0]; int hwv_att_in = att_v[4]; // //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // delay(wbs_config_delay); //Wait for configuration to be applied // } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // These scripts allow to perform the FPU Functional // tests at SS level. They correspond to the procedures // prepared by PD. // // DT - 28 Sep 2004: First draft for QM // 20 Jul 2005: Update for FM //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //Modes: see fm_testmodes.cus //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Associated blocks //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // First part of FPSS FM functional test without spectra, block // Check that IF amplification is effective (only HK) procedure FT_FPU_check_IF_nospectra_fm { string band = "1a"; string context = "warm" in ["warm","cold"]; //Test context: warm or cold }{ //At that stage, all IFs are ON // //Switch OFF FIF //Get parameters {double,string}[] result_h = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,0.0); if(context == "warm") { result_h = ConfigurationReaderWarm("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,0.0); } // int band_nb = iround(result_h[0]{0}); int diplex_h_ctrl_mode = 0; int diplex_v_ctrl_mode = 0; // double volt_H_FIF_1 = 0.075; double curr_H_FIF_1 = 0.5; double volt_H_FIF_2 = 0.075; double curr_H_FIF_2 = 0.5; // double volt_H_SIF_1 = result_h[5]{0}; double curr_H_SIF_1 = result_h[6]{0}; double volt_H_SIF_2 = result_h[7]{0}; double curr_H_SIF_2 = result_h[8]{0}; double volt_H_SIF_3 = result_h[9]{0}; double curr_H_SIF_3 = result_h[10]{0}; // {double,string}[] result_v = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,0.0); if(context == "warm") { result_v = ConfigurationReaderWarm("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,0.0); } // // double volt_V_FIF_1 = 0.075; double curr_V_FIF_1 = 0.5; double volt_V_FIF_2 = 0.075; double curr_V_FIF_2 = 0.5; // double volt_V_SIF_1 = result_v[4]{0}; double curr_V_SIF_1 = result_v[5]{0}; double volt_V_SIF_2 = result_v[6]{0}; double curr_V_SIF_2 = result_v[7]{0}; double volt_V_SIF_3 = result_v[8]{0}; double curr_V_SIF_3 = result_v[9]{0}; // string chop_sine_s = "ON"; string chop_loop = "CLOSE"; {double,string}[] result = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,0.0); if(context == "warm") { result = ConfigurationReaderWarm("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,0.0); } // int chop_G1 = iround(result[0]{0}); int chop_G2 = iround(result[1]{0}); int chop_Z1 = iround(result[2]{0}); int chop_Z2 = iround(result[3]{0}); int chop_P2 = iround(result[4]{0}); // // // double calibcurrent = result[7]{0}; // double bias_H = 0.0; double magnetcurrent_H = 0.0; double diplex_H = 0.0; double bias_V = 0.0; double magnetcurrent_V = 0.0; double diplex_V = 0.0; double chopper = 0.0; // // chopper = Check_Chopper_Prime_Redundant(chopper); HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result = ConfigurationReader("name_delays",["config_fpu_delay"],band,0.0); int config_fpu_delay = iround(result[0]{0}); delay(config_fpu_delay); // //Switch OFF SIF // volt_H_SIF_1 = 0.075; curr_H_SIF_1 = 0.5; volt_H_SIF_2 = 0.075; curr_H_SIF_2 = 0.5; volt_H_SIF_3 = 0.075; curr_H_SIF_3 = 0.5; // volt_V_SIF_1 = 0.075; curr_V_SIF_1 = 0.5; volt_V_SIF_2 = 0.075; curr_V_SIF_2 = 0.5; volt_V_SIF_3 = 0.075; curr_V_SIF_3 = 0.5; // chopper = Check_Chopper_Prime_Redundant(chopper); HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // delay(config_fpu_delay); // } // Needs the chopper in open-loop mode !! block Chopper_openloop_scan_block_ops HIFI 7694 { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ //Hard-coded RAW values for end stops and rest position int low = 1298; //This is slightly further the low end-stop int high = 2548; //This is slightly further the high end-stop int zero = 2048; //This is the zero position int step = 50; // //Go-nogo criteria - taken from FPSS-01046 issue 3 double c0 = -7.71; double c0_E = 0.2; double c1 = 8.73; double c1_E = 0.2; if(prime_or_redundant == "Red") { c0 = -8.76; c0_E = 0.2; c1 = 7.61; c1_E = 0.2; } // int chopper_pos = zero; //Scan from zero to end-stop high mois_comment("Scanning from 2048 RAW to 2548 RAW"); while(chopper_pos <= high) { //Prime/Red has no effect on RAW to send, only to the TC name if(prime_or_redundant == "Prime") { Hifi_HIFI_P_Chopper_Rot_RAW($BBID,chopper_pos); //Rotate chopper } else { Hifi_HIFI_R_Chopper_Rot_RAW($BBID,chopper_pos); //Rotate chopper } Hifi_HIFI_non_periodic_hk_FCU(); //To get sent value mois_tmcheck("Check that parameter HF_DPR_CH_ROT is set to " + chopper_pos + " in RAW units"); chopper_pos = chopper_pos + step; delay(2); } //Go-nogo criterion after first scan mois_tmcheck("Check that parameter HF_APR_CH_ROT is within " + c0 + " +/- " + c0_E + " V. If not procedure needs to be aborted and the HIFI ICC contacted."); //Scan from end-stop high to end-stop low mois_comment("Scanning from 2548 RAW to 1298 RAW"); chopper_pos = 2498; while(chopper_pos >= low) { //Prime/Red has no effect on RAW to send, only to the TC name if(prime_or_redundant == "Prime") { Hifi_HIFI_P_Chopper_Rot_RAW($BBID,chopper_pos); //Rotate chopper } else { Hifi_HIFI_R_Chopper_Rot_RAW($BBID,chopper_pos); //Rotate chopper } Hifi_HIFI_non_periodic_hk_FCU(); //To get sent value mois_tmcheck("Check that parameter HF_DPR_CH_ROT is set to " + chopper_pos + " in RAW units"); chopper_pos = chopper_pos - step; delay(2); } //Go-nogo criterion after second scan mois_tmcheck("Check that parameter HF_APR_CH_ROT is within " + c1 + " +/- " + c1_E + " V. If not procedure needs to be aborted and the HIFI ICC contacted."); //Scan from end-stop low to zero mois_comment("Scanning from 1298 RAW to 2048 RAW"); chopper_pos = 1348; while(chopper_pos <= zero) { //Prime/Red has no effect on RAW to send, only to the TC name if(prime_or_redundant == "Prime") { Hifi_HIFI_P_Chopper_Rot_RAW($BBID,chopper_pos); //Rotate chopper } else { Hifi_HIFI_R_Chopper_Rot_RAW($BBID,chopper_pos); //Rotate chopper } Hifi_HIFI_non_periodic_hk_FCU(); //To get sent value mois_tmcheck("Check that parameter HF_DPR_CH_ROT is set to " + chopper_pos + " in RAW units"); chopper_pos = chopper_pos + step; delay(2); } } ///////////////////////////////////////////////////////////// // FPU configuration, procedure: is not used at the present time.. procedure Configure_FPU_proc_fm { string band = "1a"; // HIFI band double lo_freq = 522.0; //LO frequency string mixer_polarization = "B" in ["H","V","B"]; //Polarization: H, V, or both (B) string chop_loop = "CLOSE"; //Chopper loop status double chop = 0.0; //Chopper position }{ //Fetch parameters //H-polar {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,lo_freq); int band_nb = iround(result_d[0]{0}); double diplex_H = 0.0; double diplex_V = 0.0; int diplex_h_ctrl_mode = 0; int diplex_v_ctrl_mode = 0; // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; //V-polar result_d = ConfigurationReader("name_confilfpu",["band","fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,lo_freq); // double volt_V_FIF_1 = result_d[1]{0}; double curr_V_FIF_1 = result_d[2]{0}; double volt_V_FIF_2 = result_d[3]{0}; double curr_V_FIF_2 = result_d[4]{0}; // double volt_V_SIF_1 = result_d[5]{0}; double curr_V_SIF_1 = result_d[6]{0}; double volt_V_SIF_2 = result_d[7]{0}; double curr_V_SIF_2 = result_d[8]{0}; double volt_V_SIF_3 = result_d[9]{0}; double curr_V_SIF_3 = result_d[10]{0}; //Set IF according to polarization in use if(mixer_polarization == "H") { //Set V-polar to 0 volt_V_FIF_1 = 0.0; curr_V_FIF_1 = 0.0; volt_V_FIF_2 = 0.0; curr_V_FIF_2 = 0.0; // volt_V_SIF_1 = 0.0; curr_V_SIF_1 = 0.0; volt_V_SIF_2 = 0.0; curr_V_SIF_2 = 0.0; volt_V_SIF_3 = 0.0; curr_V_SIF_3 = 0.0; // } if(mixer_polarization == "V") { //Set H-polar to 0 volt_H_FIF_1 = 0.0; curr_H_FIF_1 = 0.0; volt_H_FIF_2 = 0.0; curr_H_FIF_2 = 0.0; // volt_H_SIF_1 = 0.0; curr_H_SIF_1 = 0.0; volt_H_SIF_2 = 0.0; curr_H_SIF_2 = 0.0; volt_H_SIF_3 = 0.0; curr_H_SIF_3 = 0.0; // } // //Chopper settings string chop_sine_s = "ON"; // string chop_loop = "CLOSE" ; result_d = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,lo_freq); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // double calibcurrent = result_d[7]{0}; //Freq. dependent bias and magnet settings result_d = ConfigurationReader("name_confilmix",["norm_bias_h","norm_magn_h","norm_bias_v","norm_magn_v"],band,lo_freq); double bias_H = result_d[0]{0}; double norm_magnetcurrent_H = result_d[1]{0}; double bias_V = result_d[2]{0}; double norm_magnetcurrent_V = result_d[3]{0}; //Max. magnets for hysteresis result_d = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,lo_freq); double magnetcurrent_H = result_d[0]{0}; double magnetcurrent_V = result_d[1]{0}; // //Diplexer is interpolated from a table for Bands 3, 4, 6L and 6H if(band_nb <= 2 || band_nb == 5) { diplex_H = 0.0; //For bands 1, 2 and 5 diplex_V = 0.0; diplex_h_ctrl_mode = 0; diplex_v_ctrl_mode = 0; } else { //Get diplexer currents result_d = ConfigurationReader("name_confilfpu",["diplex_h_ctrl_mode","diplex_v_ctrl_mode"],band,lo_freq); diplex_h_ctrl_mode = iround(result_d[0]{0}); diplex_v_ctrl_mode = iround(result_d[1]{0}); double[] result_dip = Get_Diplexer_setting(band,lo_freq); diplex_H = result_dip[0]; diplex_V = result_dip[1]; } // chop = Check_Chopper_Prime_Redundant(chop); HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chop,diplex_H,diplex_V); // result_d = ConfigurationReader("name_delays",["config_fpu_delay"],band,lo_freq); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // //In case of band 6 or 7, bias have been set to 4mV. Now set to nominal if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { {double,string}[] result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); Mixerbias(result[0]{0},result[1]{0}); } // //Magnet are so far at maximum value. Now set to nominal if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); Hifi_HIFI_CH1_MX_MG_C($BBID,result_d[0]{0}); Hifi_HIFI_CV1_MX_MG_C($BBID,result_d[1]{0}); delay(1); } // Hifi_HIFI_non_periodic_hk_FCU(); delay(1); } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // CUS scripts dedicated to instrument configuration // and setup in AOT framework // // Main difference with ILT CUS is that input parameters // are here in the form provided by HSPOT. // // DT - 05-June-06 // VO - 10-07-2006 // DT - 18-09-2006 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ///////////////////////////// // Global procedures //Tune HIFI at frequency of interest procedure HIFITune { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; //LO frequency bool hrs1used = true; // HRS1 parameter =used bool hrs2used = true; // HRS2 parameter bool wbs1used = true; // WBS1 parameter =used bool wbs2used = true; // WBS2 parameter string target_name = "normal"; // Name of target level }{ //LO power tuning: could use either H or V polar {double,string}[] result = ConfigurationReader("name_confpolar4lotune",[band],band,lo_freq); double x = result[0]{0}; string tuningbackend = "H"; if(iround(x) == 2) { tuningbackend = "V"; } else { tuningbackend = "H"; } LO_tuning_block_aot(band,lo_freq / 1000.0,lo_freq / 1000.0,tuningbackend,true,true,false); //Magnet tuning: could use either HRS or WBS. Not done for bands1,2,6,7 (SCR-2380) if(band == "3a" || band == "3b" || band == "4a" || band == "4b" || band == "5a" || band == "5b") { // Currently only the HRS is used tuningbackend = "HRS"; Magnet_tuning_block_aot(band,lo_freq / 1000.0,tuningbackend); } // //Spectrometer attenuator tuning on HBB if(wbs1used || wbs2used) { WBS_attenuators_block(band,lo_freq / 1000.0,target_name,false); } if(hrs1used || hrs2used) { HRS_tune_block_aot(band); } } {int,double,double,double,double,double} obs HifiMappingModeLoadChopOTFNoRef { string modeName = "load-raster"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // chunk size given by the data rates and optimum speed int n_switch_on = 1 in [1,1800]; // Supersamplingfactor int n_cycles = 1 in [1,1200]; // Number of map coverages int load_interval = 1800 in [10,7200]; // load period defines number of lines between two loads }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode OpenMessages("HIFI Mapping - OTF Map Load Chop noRef",{data_time,0,0,n_switch_on,0,0,0,0,n_cycles,load_interval}); // Auxiliary routine for API parameter correction {double,double,int} mapused = ValidMapSize(band,lo_freq,lineDistance,nlines,stepsize,npoints,2 * data_time * n_switch_on); double line_used = mapused{0}; double scanvelocity = mapused{1}; int npoints_used = mapused{2}; // Call first part of the timing computer {int,int,int,int,bool,int,int} pre_timing = OTFLoadChopNoRef_pre_timing(nlines,npoints_used,band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_switch_on,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,double,double,int,int,int} tpar = OTFDoubleChopNoRef_telescope(naifid,onPosition,lineDistance,nlines,line_used,scanvelocity,band,lo_freq,n_cycles,pre_timing); // Dummy call to spacecraft command int[] telescopetimes = line_scan_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17}); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,bool,int,int},double,double} post_timing = OTFDoubleChopNoRef_post_timing(pre_timing,telescopetimes,nlines,data_time,n_cycles); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = OTFDoubleChopNoRef_telescope(naifid,onPosition,lineDistance,nlines,line_used,scanvelocity,band,lo_freq,n_cycles,post_timing{1}); // Call telescope command telescopetimes = line_scan_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17}); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{0}; bool end_load_on = post_timing{1}{4}; int n_loadinterval = post_timing{1}{2}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { OTFLoadChopNoRef_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,npoints_used * n_switch_on,n_loadinterval,nlines * n_cycles,end_load_on,startobs,telescopetimes,loadlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double} tact = SingleChop_deadtimes("fs",band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,npoints_used * n_switch_on); double tscan = 2.0 * (tact{1} + tact{2}); double tdead = 2.0 * tact{2}; // // Call noise computer {double,double,double,double,double} noisevalues = PositionSwitch_noisecomputer(band,lo_freq,effResolution,oneGHzReference,n_switch_on * n_cycles,tscan,tdead); // Evaluate performance OTFDoubleChopNoRef_performance(band,lo_freq,effResolution,noisevalues,timeTaken,nlines,npoints_used,n_switch_on * n_cycles,false,tscan,tdead); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // Switch HIFI on, procedure // procedure HIFI_global_switch_on_proc_ops { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ //Sequentially switches on, then notify PDU // //WBS-H mois_step("Switch ON WBS-H S/S"); PDU_switch_on_block_ops("WBS_H"); mois_comment("Notify PDU status for WBS-H"); HIFI_notify_PDU_status_on_block_ops("ON","OFF","OFF","ON","OFF","OFF","WBSH"); //WBS-V mois_step("Switch ON WBS-V S/S"); PDU_switch_on_block_ops("WBS_V"); mois_comment("Notify PDU status for WBS-H"); HIFI_notify_PDU_status_on_block_ops("ON","OFF","ON","ON","OFF","OFF","WBSV"); //HRS-H and HRS-V are first powered ON, FT#0 is done, then notify PDU mois_step("Switch ON HRS-H S/S"); PDU_switch_on_block_ops("HRS_H"); mois_step("Switch ON HRS-V S/S"); PDU_switch_on_block_ops("HRS_V"); //HRS FT#0 and special HK handling for this mois_step("HRS start-up"); mois_comment("House-keeping for HRS-H and HRS-V is de-selected"); Switch_HK_block_ops("ON","ON","ON","ON","OFF","OFF"); mois_comment("Notify PDU status for HRS-H and HRS-V"); HIFI_notify_PDU_status_on_block_ops("ON","OFF","ON","ON","OFF","ON","HRSH"); HIFI_notify_PDU_status_on_block_ops("ON","OFF","ON","ON","ON","ON","HRSV"); HRS_functional_test_No_0_block_ops(); mois_comment("House-keeping for HRS-H and HRS-V is selected again"); Switch_HK_block_ops("ON","ON","ON","ON","ON","ON"); mois_comment("Initial configuration of HRS blocks and LO"); HRS_standby_block_ops("0",["wb","wb"]); //LOU mois_step("Switch ON LO S/S"); string lo_subsys = "LO_Prime"; if(prime_or_redundant == "Red") { lo_subsys = "LO_Red"; } PDU_switch_on_block_ops(lo_subsys); mois_comment("Notify PDU status for LCU"); HIFI_notify_PDU_status_on_block_ops("ON","ON","ON","ON","ON","ON","LCU"); } {int,double,double,double,double,double} obs HifiSScanModeFSwitch { string modeName = "fs-freq"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles per frequency and pointing int n_switch_off = 1 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles on OFF int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int n_cycles = 1 in [1,600]; // Number of half OFF-ON-ON-OFF cycles at one frequency int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode OpenMessages("HIFI Spectral Scan - Frequency Switch Ref",{data_time,data_time_off,0,n_switch_on,n_switch_off,0,0,n_freq_point,n_cycles,load_interval}); // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,redundancy,wbs1Used,wbs2Used,data_time); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; ////////////////////////////////////////////////////////////////////// // Call first part of the timing computer {{int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int},{int,double,double[],int[][],bool,double[],int,bool}} pre_timing = SScanFSwitch_pre_timing(band,lo_freq,lo_freq_up,redundancy,freq_throw,effResolution,hr1,hr2,wb1,wb2,data_time,data_time_off,n_switch_on,n_switch_off,n_freq_point,n_cycles,load_interval,docommands); // frequency parameters int groupnumber = pre_timing{1}{0}; double reffreq = pre_timing{1}{1}; double[] freqgrid = pre_timing{1}{2}; int[][] grouporder = pre_timing{1}{3}; bool retuning = pre_timing{1}{4}; double[] targetlevels = pre_timing{1}{5}; int nfreq_if = pre_timing{1}{6}; bool dsb = pre_timing{1}{7}; int n_total = groupnumber * n_cycles; ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {double,double} refPosition = {raoff,decoff}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,int,int,int,int,int,int} tpar = PositionSwitch_telescope(naifid,onPosition,refPosition,band,reffreq,pre_timing{0},n_total); // Dummy call to spacecraft command int[] telescopetimes = nodding_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},true); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int},double,double,double} post_timing = SScanDoubleChop_post_timing(pre_timing{0},telescopetimes,n_freq_point,groupnumber,n_cycles); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = PositionSwitch_telescope(naifid,onPosition,refPosition,band,reffreq,post_timing{1},n_total); // Call telescope command telescopetimes = nodding_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},true); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following // normal pre_timing values int on_inttime = post_timing{1}{0}; int off_inttime = post_timing{1}{1}; int n_loadinterval = post_timing{1}{7}; int n_long_on = post_timing{1}{8}; int n_long_off = post_timing{1}{9}; int shiftlength = post_timing{1}{5}; int initlength = post_timing{1}{14}; bool final_load = post_timing{1}{12}; // efficiency parameters double avnumchop_on = post_timing{2}; double avnumchop_off = post_timing{3}; double tscan = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { SScanFSwitch_commanding(band,reffreq,freq_throw,effResolution,hr1,hr2,wb1,wb2,n_freq_point,grouporder,freqgrid,retuning,targetlevels,data_time,data_time_off,n_switch_on,n_switch_off,n_long_on,n_long_off,n_cycles,n_total,n_loadinterval,final_load,startobs,telescopetimes,shiftlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double,double,double} tact = SScanDoubleChop_deadtimes("fs",band,reffreq,hr1,hr2,wb1,wb2,n_freq_point,data_time,data_time_off,n_switch_on,n_switch_off,n_long_on,n_long_off,n_cycles,avnumchop_on,avnumchop_off,tscan); // // Call noise computer {double,double,double,double,double} noisevalues = SScanFSwitch_noisecomputer(band,reffreq,nfreq_if,dsb,effResolution,on_inttime,off_inttime,n_cycles,tscan,tact); // Evaluate performance SScanDoubleChop_performance(band,reffreq,nfreq_if,dsb,effResolution,noisevalues,timeTaken,n_freq_point,n_cycles,groupnumber * n_freq_point,avnumchop_on,avnumchop_off,true,tscan,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // Reset observation ID - closes observation block HIFICloseObs HIFI 6999 { }{ // Previous command my have used second bus slot - use NOOP to fill Hifi_HIFI_noop(); // Switch to slow housekeeping {string,int,double,double,double,double} hkparms = PeriodicHKParms("slow"); string[] pattern = QueryHKPattern(true); Hifi_HIFI_Housekeeping_on(hkparms{0},pattern[0],pattern[1],pattern[2],pattern[3],pattern[4],pattern[5]); //Fetch last obsid applicable {double,string}[] result = ConfigurationReader("name_lastobsid",["last_obsid_current"],"0",0.0); int closing_obsid = iround(result[0]{0}); //Close OBSID Hifi_HIFI_Set_OBS_ID(0,closing_obsid); // clean bus delay(1); } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the observing mode procedure SScanFSwitch_commanding { string band = "4a"; // HIFI band double reffreq = 978300.0; // Reference characteristic LO frequency double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} eff_resolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int grouplen = 1; // Number of frequency steps per nodding phase int[][] grouporder = [[0],[0]]; // Sequence to trace frequency points in both phases double[] freqgrid = [978053.7,978301.8,978381.1]; // Table of frequency points bool retuning = false; // need for WBS retuning double[] targetlevels = [1.0,1.0,1.0]; // WBS tuning levels int data_time = 4; // chunk size int data_time_off = 4; // data dump interval on OFF int n_per_on = 1; // number of half nu1-nu2-nu2-nu1 cycles on ON int n_per_off = 1; // number of half nu1-nu2-nu2-nu1 cycles on OFF int n_long_on = 1; // number of cycles on ON without retuning int n_long_off = 1; // number of cycles on OFF without retuning int n_cycles = 1; // Number of half OFF-ON-ON-OFF cycles at one frequency int allsteps = 4; // Total number of frequency pointing periods int n_loadinterval = 1; // number of nods before a load measurement bool final_load = false; // Need for final load measurement int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,20,1,21,0]; // Timing of the observation from telescope int shiftlength = 0; // Shift of the loop start relative to the pointing }{ // Auxiliary variables // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time int tnodslew = telescopetimes[2]; // slew dead time between points // First frequency double runningfreq = freqgrid[grouporder[1][0]]; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] onrates = dataparms{1}; dataparms = DataTaking(backendreadoutparms,data_time_off); double[] offrates = dataparms{1}; int hkduration = HkReadoutTime(band,reffreq,backendreadoutparms,false); int readoutdead = SlowChopReadoutDelay(band,reffreq,backendreadoutparms); // recompute load duration for initial load measurement int loadlength = duration(SScanDoubleLoadMeasurement(band,runningfreq,reffreq,freq_throw,true,eff_resolution{0},data_time,backendreadoutparms)); loadlength = loadlength + readoutdead; // Tuning levels string[] targetnames = TargetNames(band,reffreq,retuning,targetlevels); string target = targetnames[0]; // All commands with a duration possibly depending on the frequency // are taken at the reference frequency to guarantee synchonization // Declare auxiliary variables to be used in the loops int i_freqcycles = 0; int i_group = 0; int i_phase = 0; // variables storing the configuration setting bool islong = false; bool isinvalid = true; //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; bool runintostate = false; while(state[0] >= 0) { if(runintostate) { state = next_state_no_check(); } else { state = next_state(); } if(state[0] == 1) { // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // HIFIInitObs(); TuneHIFIFsw(band,runningfreq,freq_throw,hrs1,hrs2,wbs1{0},wbs2{0},target); delay(tinitslew - (time() - startobs) - loadlength + shiftlength - hkduration); // First load measurement HIFISetHK("normal",false); SScanDoubleLoadMeasurement(band,runningfreq,reffreq,freq_throw,true,eff_resolution{0},data_time,backendreadoutparms); if(shiftlength > 0) { runintostate = true; } else { runintostate = false; } } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 7) { // The NOD-state represents our OFF position // Reset group counter i_group = 0; runintostate = false; // long integrations not possible in last and first PS cycle if(n_cycles > 1 && state[2] % n_cycles != state[2] % 2) { if(isinvalid || !islong) { HIFIConfigureFSwitchIntegration(data_time_off,n_long_off,band,reffreq,backendreadoutparms); islong = true; isinvalid = false; } HIFIFSwitchOffIntegration(data_time_off,n_long_off,band,reffreq,offrates); } else { if(isinvalid || islong) { HIFIConfigureFSwitchIntegration(data_time_off,n_per_off,band,reffreq,backendreadoutparms); islong = false; isinvalid = false; } // No group scanning on OFF HIFIFSwitchOffIntegration(data_time_off,n_per_off,band,reffreq,offrates); // Now we switch to the next frequency group or repeat the cycle if(state[2] % n_cycles == 0 && state[2] % 2 == 0) { // Big tuning step, but not at end of observation if(state[2] < allsteps) { i_freqcycles = i_freqcycles + 1; runningfreq = freqgrid[grouporder[1][0] + i_freqcycles * grouplen]; target = targetnames[i_freqcycles]; HIFIRetuneFsw(band,runningfreq,freq_throw,target); runintostate = true; } else { // final load measurement if requested if(final_load) { delay(readoutdead); SScanDoubleLoadMeasurement(band,runningfreq,reffreq,freq_throw,false,eff_resolution{0},data_time,backendreadoutparms); runintostate = true; } } } } // Active WBS HK if we have a nod slew without calibration if(state[2] % 2 == 1) { isinvalid = true; if(state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } } if(state[0] == 3) { // The POINT-state represents our source position i_phase = state[2] % 2; // ON integration runintostate = false; // long integrations not possible in last and first nod cycle if(n_cycles > 1 && state[2] % n_cycles != (state[2] % 2 + 1) % 2) { if(isinvalid || !islong) { HIFIConfigureFSwitchIntegration(data_time,n_long_on,band,reffreq,backendreadoutparms); islong = true; isinvalid = false; } HIFIFSwitchOnIntegration(data_time,n_long_on,band,reffreq,onrates); } else { if(isinvalid || islong) { HIFIConfigureFSwitchIntegration(data_time,n_per_on,band,reffreq,backendreadoutparms); islong = false; isinvalid = false; } HIFIFSwitchOnIntegration(data_time,n_per_on,band,reffreq,onrates); } // Other frequencies // Reset group counter i_group = 1; while(i_group <= grouplen - 1) { // retune runningfreq = freqgrid[grouporder[i_phase][i_group] + i_freqcycles * grouplen]; HIFIChangeFreqFsw(band,runningfreq,freq_throw); if(i_group == 1) { if(isinvalid || islong) { HIFIConfigureFSwitchIntegration(data_time,n_per_on,band,reffreq,backendreadoutparms); islong = false; isinvalid = false; } } HIFIFSwitchOnIntegration(data_time,n_per_on,band,reffreq,onrates); i_group = i_group + 1; } // Now we switch to the next frequency group or repeat the cycle if(state[2] % n_cycles == 0 && i_phase == 1) { // Big tuning step, but not at end of observation if(state[2] < allsteps) { i_freqcycles = i_freqcycles + 1; runningfreq = freqgrid[grouporder[0][0] + i_freqcycles * grouplen]; target = targetnames[i_freqcycles]; HIFIRetuneFsw(band,runningfreq,freq_throw,target); runintostate = true; } else { // final load measurement if requested if(final_load) { delay(readoutdead); SScanDoubleLoadMeasurement(band,runningfreq,reffreq,freq_throw,false,eff_resolution{0},data_time,backendreadoutparms); runintostate = true; } } } // Active WBS HK if we have a nod slew without calibration if(state[2] % 2 == 0) { isinvalid = true; if(state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } } if(state[0] == 9) { // Load switch delay(readoutdead); SScanDoubleLoadMeasurement(band,runningfreq,reffreq,freq_throw,false,eff_resolution{0},data_time,backendreadoutparms); isinvalid = true; runintostate = false; } // Danging load - already covered above // otherwise the instrument stops halftunelength before the telescope if(state[0] == 5) { // finished shift of instrument operations relative to pointing command runintostate = false; HIFICloseObs(); } } } // Get dead time for frequency switch double procedure GetFSwitchDeadTime { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency }{ double[] dead = CalibrationReader("fs_deadtime",["duration"],band,lo_freq); return dead[0]; } //Set LCU3a back to standby status, procedure procedure LCU3a_standby_proc_fm { string band = "3a"; // HIFI band double lo_freq = 810.0 in [807.0,848.0]; //LO frequency }{ error("This module is obsolete: use LCU_standby_proc_fm instead"); } // Compute the additional time needed for HK readout setting at first load int procedure HkReadoutTime { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // Readout parameters for HRS1,HRS2, WBS1,WBS2 bool fast = false; //whether fast chop is used }{ // get time added already for normal readout if(fast) { int readoutdead = FastChopReadoutDelay(band,lo_freq,backendreadoutparms); } else { readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); } // HK readout time int hkreadouttime = duration(HIFISetHK("normal",false)); int remain = imax(hkreadouttime - readoutdead,0); return remain; } // Procedure to compute all parameters needed in a Configure_spectroscopy {int,int,int,int,int,int,int,int,int,int} procedure ConfigureSpectroscopyParams { /* Integration time */ int data_time = 4; // Integration time between two data readouts int n_data = 2; // Integration time counter /* Parameters determining the delays - used in calibration reader */ string chopmode = "chop" in ["chop","lchop","fs","hot-cold","tp"]; // Chop mode determining the modulation dead time string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency /* Backend settings */ {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // HRS1/2 {used,resolution,subbands used}, WBS1/2 {used,channel windows} }{ // Get fixed parameters from configuration and calibration files // Command jitter time is the default delay {double,string}[] result = ConfigurationReader("name_delays",["add_jitter"],band,lo_freq); int add_jitter = iround(result[0]{0}); // WBS delta time // Default total power. This should be 0. int del_wbs = add_jitter; // WBS delta time given by switch dead time if(chopmode == "chop") { double res = GetSkyChopDeadTime(band,lo_freq); del_wbs = iceil(res * 1000.0); } if(chopmode == "lchop") { res = GetLoadChopDeadTime(band,lo_freq); del_wbs = iceil(res * 1000.0); } if(chopmode == "fs") { res = GetFSwitchDeadTime(band,lo_freq); del_wbs = iceil(res * 1000.0); } if(chopmode == "hot-cold") { bool wbsused = backendreadoutparms{2}{0} || backendreadoutparms{3}{0}; res = HotColdRelaxTime(band,lo_freq,wbsused); del_wbs = iceil(res * 1000.0); } // HRS delta time - should be zero as well int del_hrs = add_jitter; // Additional delays in the readout loops - given in OBS user manual result = ConfigurationReader("name_delays",["add_hrs","add_wbs","add_jitter","wbs_init","wbs_chunksize","tacc_add","hrs_phase","min_wbs_acc","scos_jitter"],band,lo_freq); int add_hrs = iround(result[0]{0}); int add_wbs = iround(result[1]{0}); int wbs_init = iround(result[3]{0}) + iround(result[8]{0}); int wbs_chunksize = iround(result[4]{0}); int tacc_add = iround(result[5]{0}); int hrs_phase = iround(result[6]{0}); // HRS standard phase length int min_wbs_acc = iround(result[7]{0}); // WBS transfer time // Split total integration time int tint = data_time * n_data * 1000; // dead time has to be an integer multiple of the 10ms chunk time int tdead = del_wbs + add_wbs + add_jitter; int nchunk = (tdead - 1) / wbs_chunksize + 1; int tcorr = nchunk * wbs_chunksize - tdead; del_wbs = del_wbs + tcorr; tdead = tdead + tcorr; // Accumulation time // Ignores that total power can be slightly more efficient int t_acc_wbs = (tint - wbs_init) / n_data - tdead; // discretize in 10ms chunks nchunk = (t_acc_wbs - tacc_add) / wbs_chunksize; t_acc_wbs = nchunk * wbs_chunksize + tacc_add; // Check relative to minimum accumulation tim if(t_acc_wbs + del_wbs + add_wbs < min_wbs_acc + add_jitter) { SError("WBS integration too short for readout. Increase duration."); } // No WBS addition in ICU int n_wbs_integr = 1; int n_wbs_start = n_data; // HRS int hrs_fullphase = hrs_phase + del_hrs + add_hrs; int r_hrs = (t_acc_wbs + hrs_fullphase - add_jitter) / hrs_fullphase; int t_acc_hrs = (t_acc_wbs - add_jitter) / r_hrs - del_hrs - add_hrs; // for n_wbs_integr=1 identical to r_hrs int n_hrs_integr = r_hrs; // Compute actual integration time and dead time per readout // If WBS is used count only the WBS time if(backendreadoutparms{2}{0} || backendreadoutparms{3}{0}) { int tint_act = nchunk * wbs_chunksize * n_data; tdead = tdead + tacc_add; } else { tint_act = t_acc_hrs * r_hrs * n_data; tdead = tdead + r_hrs * (del_hrs + add_hrs) + add_jitter; } // Return all config_spectroscopy timing parameters return {n_wbs_start,r_hrs,n_wbs_integr,n_hrs_integr,del_hrs,del_wbs,t_acc_wbs,t_acc_hrs,tdead,tint_act}; } // Check frequency throw relative to HRS bandwidth procedure CheckFswOutOfBand { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double freq_throw = -40.0; // throw of frequency switch in MHz {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // Readout parameters for HRS1,HRS2, WBS1,WBS2 }{ bool hrs1used = backendreadoutparms{0}{0}; // HRS1 to be used int hrs1resol = backendreadoutparms{0}{1}; // resolution bool hrs2used = backendreadoutparms{1}{0}; // HRS2 to be used int hrs2resol = backendreadoutparms{1}{1}; // resolution // get minimum bandwidth covered // Start from full IF double bw = GetBackendBandwidth(band,lo_freq,-1); // Both HRS if(hrs1used) { double hbw = GetBackendBandwidth(band,lo_freq,hrs1resol); bw = min(bw,hbw); } if(hrs2used) { hbw = GetBackendBandwidth(band,lo_freq,hrs2resol); bw = min(bw,hbw); } // Compare with frequency throw if(abs(freq_throw) > 0.5 * bw) { // Generate messages - first close previous paragraph message("

"); message("

Warning

"); message("

"); message("The chosen frequency throw of " + freq_throw + " MHz is large " + "compared to the HRS subband coverage. It is likely that the HRS " + "does not see some lines in both frequency-switch phases. In this " + "case, the actual S/N ratio will be lower by a factor two than the " + "predicted one."); } } //TM to control FDIR on LOU temp. block LO_Temp_FDIR_block_fm HIFI 3952 { string activate = "ON" in ["ON","OFF"]; //Whether FDIR is activated or not double tmin = 123.0; //Min threshold double tmax = 145.0; //Max threshold int nbreach = 10; //Number of breach }{ Start_block(); if(activate == "OFF") { Hifi_HIFI_LOU_T_check_off(); } else { Hifi_HIFI_LOU_T_check_on(nbreach,tmax,tmin); } delay(1); // } // Fast chop integration OFF-ON-OFF-ON... with telescope at OFF position block HIFIFastHalfChopOffIntegration HIFI 6054 { int data_time = 4; // Integration time between two data readouts int n_cycle = 1; // readout cycle number string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz int[] parms = [1,0]; // Parameters for chop cycles double[] rates = [120.0,1.0,2.0]; // Data rates between and during integrations }{ HIFI_Spectr_fast_chop_proc_aot(data_time,n_cycle,band,lo_freq,["chop_M3","chop_M3right"],parms,rates); } // Procedure to get timing in a spectroscopy measurement {double,double} procedure GetInstDeadFastChop { /* Integration time */ int data_time = 10 in [4,128]; // data dump interval int n_int = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_data = 2; // Integration time counter /* Parameters determining the delays - used in calibration reader */ string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency /* Backend settings */ {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // HRS1/2 {used,resolution,subbands used}, WBS1/2 {used,channel windows} }{ // Get timing parameters bool wbs_used = backendreadoutparms{2}{0} || backendreadoutparms{3}{0}; {int,int,int,int,int,int,int,int,int,int,int,int,int} timing = FastConfigureSpectroscopyParams(data_time,n_int,n_data,band,lo_freq,wbs_used); int tdead_chop = timing{10}; int tdead_data = timing{11}; int tint = timing{12}; // For the noise computation there is no difference between initial dead // and readout dead, they are all summed up // Return dead time per full integration double tintall = double(tint) / 1000.0; double tdeadphase = double(tdead_chop) / 1000.0; return {tintall,tdeadphase}; } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // The blocks //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //Write EEPROM , block block Write_EEPROM_block_ops HIFI 7930 { }{ mois_step("Write on EEPROM partition of relevance"); mois_spacon("Ask the HIFI support on which partition on the EEPROM the software must be written (either 1 or 2). The answer to this question corresponds to the formal parameter HP228197 (= hifi_HIF_partition_ID) of the next command."); mois_spacon("Similarly, ask the HIFI support which end address should be used (in consistency with applicable issue of SRON_U/HIFI/PR/2007-007). The answer to this question corresponds to the formal parameter HP005197 (= hifi_OBS_mem_end) of the next command."); // int hifi_OBS_mem_end = 0x185c1; //this is applicable to OBS5.8.1. int hifi_HIF_partition_ID = 1; int hifi_HIF_Npages_to_skip = 0; Hifi_HIFI_eeprom_write(hifi_OBS_mem_end,hifi_HIF_partition_ID,hifi_HIF_Npages_to_skip,[]); delay(1); mois_spacon("Please log the partition and end address that were used, together with the OBSW version"); } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // FM CUS scripts to assess various instrument settling // times (CAL UC-1.1.2) // // DT - 27 Oct 2005: first draft based on CAL UC doc. // //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //modes: see fm_testmodes.cus /////////////////////////////////// // Procedures /////////////////////////////////// // Chopper Response time with user input choice on angle, block block Chopper_Response_time_EXPERT_block_fm HIFI 3686 { double targetAngle = 0.1; // angle to move to int milliSecSample = 3; // interval between samples int samplesBefore = 30 in [0,50]; int samplesAfter = 100 in [0,1000]; }{ Start_block(); // targetAngle = Check_Chopper_Prime_Redundant(targetAngle); HIFI_Chopper_scan_fast_proc_fm(milliSecSample,targetAngle,samplesBefore,samplesAfter); // // delay calculation TBC int millisecondsUsed = 500 + milliSecSample * (samplesBefore + samplesAfter + 1); delay(iceil(0.0010 * double(millisecondsUsed))); // } //HIFI-COP-X-IF-FBk-Cal obs HifiEng_IF_FBk_Cal_COP { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string chopcase = "dbs" in ["dbs","csa","lsw"]; //chopper delta considered int testtime = 3600; //total test time in seconds }{ //General parameters in use string backend = "both"; string[] hrs_mode = ["wb1","wb1"]; double[] result_d = CalibrationReader("name_keyfreq",["keyfreq"],band,0.0); double lo_freq = result_d[0]; //For bands 6 and 7, use wb8 if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { hrs_mode = ["wb8","wb8"]; } // //Avoid high data-rates if(testtime % 3 == 0 && testtime % 4 == 0) { testtime = testtime + 4; } // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(IF_FBk_Cal_COP_proc_ops(band,lo_freq,hrs_mode,testtime,backend,chopcase)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution IF_FBk_Cal_COP_proc_ops(band,lo_freq,hrs_mode,testtime,backend,chopcase); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } {string,double,double}[] procedure HifiPointModeFSwitchNoRefSequencerInit { string modeName = "fs"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rates int n_cycles = 2 in [1,3600]; // number of half nu1-nu2-nu2-nu1 cycles on ON int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode // inherit from load-chop mode {string,double,double}[] retvalues = HifiPointProcLoadChopNoRefSequencerInit(naifid,ra,dec,band,lo_freq,effResolution,oneGHzReference,hrs1,hrs2,wbs1,wbs2,data_time,n_cycles,load_interval,docommands); return retvalues; } //Contingency for LOU temp FDIR modification mode HifiManCmd_LOU_FDIR_disable { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! }{ mois_comment("Procedure to disable the FDIR on limits for LOU operational temperatures"); //StartMode_block_ops(); // mois_step("Disable FDIR"); Disable_LO_FDIR_temperatures_block_mois(); // StopMode_block_ops(); // -> to issue last obsd/bbid } // Needs the chopper in open-loop mode !! block Chopper_openloop_scan_block_fm HIFI 3694 { int scan_portion = 1 in [1,3]; //indicates which part of scans is to be done }{ //Start_block (); //Hard-coded RAW values for end stops and rest position int low = 1298; //This is slightly further the low end-stop int high = 2548; //This is slightly further the high end-stop int zero = 2048; //This is the zero position int step = 50; // int chopper_pos = zero; //Scan from zero to end-stop high while(chopper_pos <= high) { if(scan_portion == 1) { HIFI_CPR_Chopper_Rot_RAW_proc_fm(chopper_pos); //Rotate chopper Hifi_HIFI_non_periodic_hk_FCU(); //To get sent value delay(2); } chopper_pos = chopper_pos + step; } //Scan from end-stop high to end-stop low chopper_pos = high - step; while(chopper_pos >= low) { if(scan_portion == 2) { HIFI_CPR_Chopper_Rot_RAW_proc_fm(chopper_pos); //Rotate chopper Hifi_HIFI_non_periodic_hk_FCU(); //To get sent value delay(2); } chopper_pos = chopper_pos - step; } //Scan from end-stop low to zero chopper_pos = low + step; while(chopper_pos <= zero) { if(scan_portion == 3) { HIFI_CPR_Chopper_Rot_RAW_proc_fm(chopper_pos); //Rotate chopper Hifi_HIFI_non_periodic_hk_FCU(); //To get sent value delay(2); } chopper_pos = chopper_pos + step; } } // Load calibration measurement procedure LoadMeasurement_FCal { string band = "4a"; // HIFI band (needed to estimate stabilization) double lo_freq = 978200.0; // LO frequency double deltanu = 1.0; // minimum effective resolution of the calibrated data int data_time = 4; // time between subsequent data readouts {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // Readout parameters for HRS1,HRS2, WBS1,WBS2 }{ // Initial computations {int,int,bool} calinit = HIFICalInit(band,lo_freq,deltanu,data_time); int used_datatime = calinit{0}; int n_inttime = calinit{1}; bool retuning = calinit{2}; // Perform zero and comb measurement ZeroCombMeasurement_FCal(band,lo_freq,used_datatime,backendreadoutparms); // No we perform the actual hot-cold measurement // slow_chop_spectroscopy int danglingreadout = HIFI_Calibrate_hot_cold(band,lo_freq,used_datatime,n_inttime,backendreadoutparms,retuning); // Retune and another load if we are in HEB bands if(retuning) { // we have to wait for readout delay(danglingreadout); // Another LO vector scan at the same frequency for a stable HEB operation HIFITuneFreq(band,lo_freq,false,""); danglingreadout = HIFI_Calibrate_hot_cold(band,lo_freq,used_datatime,n_inttime,backendreadoutparms,false); } } //Procedure checking the consistency of slow chop spectroscopy //parameters to be sent to configuration command. bool procedure Check_slow_chop_parameters_proc { int n_wbs_start = 4; //Nb of frames int r_hrs = 1; //Nb of HRS readout per WBS readout int n_wbs_integr = 1; //Number of wbs readout packetized per WBS frame int n_hrs_integr = 1; //Number of hrs readout packetized per HRS frame int del_hrs = 5; //Delay before starting HRS integration int del_wbs = 5; //Delay before starting WBS integration int t_acc_wbs = 4005; //Duration of WBS frame int t_acc_hrs = 1950; //Duration of HRS frame int wbsh_offset1 = 0; int wbsh_width1 = 2048; int wbsh_offset2 = 2048; int wbsh_width2 = 2048; int wbsh_offset3 = 4096; int wbsh_width3 = 2048; int wbsh_offset4 = 6144; int wbsh_width4 = 2048; int wbsv_offset1 = 0; int wbsv_width1 = 2048; int wbsv_offset2 = 2048; int wbsv_width2 = 2048; int wbsv_offset3 = 4096; int wbsv_width3 = 2048; int wbsv_offset4 = 6144; int wbsv_width4 = 2048; int hrs_rshift = 0; //HRS bit shift int wbs_rshift = 0; //WBS bit shift int hrsh_sel = 255; //HRS-H band selection int hrsv_sel = 255; //HRS-V band selection string wbs_packing = "24_bits_format"; string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4,wb5 string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ error("Procedure Check_slow_chop_parameters_proc is not used anymore."); return false; } // Standing wave study for FSW model //HIFI-COP-X-StWv-FSW obs HifiEng_StWv_FSW_COP { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(StWv_FSW_COP_proc_ops(band)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution StWv_FSW_COP_proc_ops(band); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } // Third part of FPSS FM functional test, block // Magnet scan fine, around expected optimal magnets // This differs from Magnet_scan_fine which scans over // the whole range. block FT_FPU_magnet_tune_fine_fm HIFI 3802 { string band = "1a"; double magnet_current_h = -5.7; //Central magnet current H double magnet_current_v = -9.4; //Central magnet current H double step_current = 0.1; //Current increment in mA int step_number = 10; //Number of steps int integ_time = 4; //Integation time in seconds double lo_freq = 500.0; //LO frequency string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); //Get nominal biases and magnets {double,string}[] result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); double bias_h = result[0]{0}; double bias_v = result[1]{0}; // //H polar double magnet_min_h = magnet_current_h - step_current * double(step_number) / 2.0; double magnet_max_h = magnet_current_h + step_current * double(step_number) / 2.0; //V polar double magnet_min_v = magnet_current_v - step_current * double(step_number) / 2.0; double magnet_max_v = magnet_current_v + step_current * double(step_number) / 2.0; // double magnet_min = max(magnet_min_h,magnet_min_h); double magnet_max = min(magnet_max_h,magnet_max_h); // double step_duration = 0.1; int steps = 0; int steps_done = 0; int max_per_command = 40; // int steps_wanted = step_number; // double step = Stepsize(magnet_min,magnet_max,steps_wanted,"hifi_HIF_mx_mg_step_C"); double margin = Stepmargin(magnet_min,magnet_max,"hifi_HIF_mx_mg_step_C"); steps_wanted = 1 + iceil((magnet_max - magnet_min) / step); // force the last portion to less than max_per_command if(max_per_command * (steps_wanted / max_per_command) == steps_wanted) { steps_wanted = steps_wanted - 1; } // //Set magnet to maximum to avoid hysteresis result = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,0.0); Hifi_HIFI_CH1_MX_MG_C($BBID,result[0]{0}); Hifi_HIFI_CV1_MX_MG_C($BBID,result[1]{0}); delay(2); // magnet_current_h = magnet_min_h; magnet_current_v = magnet_min_v; while(steps_done < steps_wanted) { steps = steps_wanted - steps_done; if(steps > max_per_command) { steps = max_per_command; } magnet_current_h = magnet_min_h + double(steps_done) * step; magnet_current_v = magnet_min_v + double(steps_done) * step; Hifi_HIFI_FCU_parameter_scan($BBID,1,1,step_duration,bias_h,bias_v,0.0,magnet_current_h,magnet_current_v,0.0); delay(2); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // steps_done = steps_done + 1; } } //HIFI-COP-1.2-LO_FT: for MTL in routine: uses single TM page TC procedure LO_FT_COP_proc_ops { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ mois_comment("Start of HIFI LO Functional Test for band " + band); mois_comment("Please check that instrument was switched on with the " + prime_or_redundant + " unit"); mois_tmcheck("Check content of AND LCU_temperatures_with HIFI expert."); //General parameters in use string multiplier = "ALL"; int operation_delay = 0; // double[] cresult_d = CalibrationReader("name_keyfreq",["keyfreq"],band,0.0); double lo_freq = cresult_d[0]; //applies to cold LO // mois_step("Init MSA"); string chop_startup_prime_red = "chop_startup_cold_prime"; if(prime_or_redundant == "Red") { chop_startup_prime_red = "chop_startup_cold_red"; } {double,string}[] result = ConfigurationReader("name_chopper",[chop_startup_prime_red],"0",0.0); Init_MSA_ops(band,"CLOSE",lo_freq,result[0]{0},"ON",prime_or_redundant); // //First switch off the band. LCU_switch_off_block_fm(); mois_tmcheck("Check that parameter HL_Channel_S is OFF"); // mois_step("Measure LCU IV curve"); Measure_LCU_IV_proc_fm(band,multiplier,operation_delay); // //Switch on with safe Vd2 mois_step("Switch on LO band"); LCU_switchon_proc_fm(band); mois_tmcheck("Check that parameter HL_MODE_S is normal"); mois_tmcheck("Check that parameter HL_Channel_S is " + band); // mois_step("LO SFT"); //This will switch on the chain again LO_SFT_proc_ops(band,prime_or_redundant); // mois_tmcheck("Check whether parameter HL_error_word_S has been FAULT at any time of the procedure. Communicate occurences to HIFI expert."); mois_tmcheck("Check content of AND LCU_status2 and LCU_" + band + " with HIFI expert."); } ///////////////////////////////////////////////////////////////// // Spectral scan in DBS observing modes // {string,double,double}[] procedure HifiSScanProcDBSSequencerInit { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz int redundancy = 4 in [1,12]; // Frequency scan redundancy {double,double} effResolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool wbs1Used = true; // whether WBS1 is used bool wbs2Used = true; // whether WBS2 is used /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_switch_on = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per frequency and pointing int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int n_cycles = 1 in [1,600]; // Number of half OFF-ON-ON-OFF cycles at one frequency int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,redundancy,wbs1Used,wbs2Used,data_time); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hr1{0},hr1{1},hr1{3}},{hr2{0},hr2{1},hr2{3}},wb1,wb2}; // Get frequency grid characteristic parameters {double,int,double} gfref = GetFReference(band,lo_freq,lo_freq_up); double reffreq = gfref{0}; int stdredun = gfref{1}; double stdstep = gfref{2}; int increment = stdredun / redundancy; // allowed group size double nocaliblen = GetFNoCalibLength(band,reffreq); int n_freq_point_guess = ifloor(nocaliblen / (stdstep * double(increment)) + 1.0); int n_freq_point_range = 1 - n_freq_point_guess; if(n_freq_point_range == 0) { n_freq_point_range = 1; } // Now general part of DBS modes {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // Get the drift parameters to compute the drift noise // spectral scans always use the full bandwidth for reference bool narrowReference = false; {double,double} phaselengths = DBSPhaseLengths(band,reffreq,effResolution,continuumDetection,narrowReference); // Compute derived quantities int data_time_guess = imin(imax(iceil(phaselengths{1}),datalimit),20); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } // remaining part for n_switch int n_switch_on_guess = iceil(phaselengths{0}) / (n_freq_point_guess * 2 * data_time_guess) + 1; int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)},{"n_freq_point",double(n_freq_point_guess),double(n_freq_point_range)}]; return retvalues; } //HIFI HK control, block block Switch_HK_block_ops HIFI 7605 { string hk_FCU = "ON" in ["ON","OFF"]; //Status of FCU HK string hk_LCU = "ON" in ["ON","OFF"]; //Status of LCU HK string hk_WBSV = "ON" in ["ON","OFF"]; //Status of WBSV HK string hk_WBSH = "ON" in ["ON","OFF"]; //Status of WBSH HK string hk_HRSV = "ON" in ["ON","OFF"]; //Status of HRSV HK string hk_HRSH = "ON" in ["ON","OFF"]; //Status of HRSH HK }{ StartBlock_ops(); //Get applicable HK rate {double,string}[] result_d = ConfigurationReader("name_delays",["hk_rate"],"0",0.0); string hk_rate = result_d[0]{1}; Hifi_HIFI_Housekeeping_on(hk_rate,hk_FCU,hk_LCU,hk_WBSV,hk_WBSH,hk_HRSV,hk_HRSH); delay(1); } // Fast chop integration OFF-ON-OFF-ON... with telescope at ON position block HIFIFastHalfChopOnIntegration HIFI 6053 { int data_time = 4; // Integration time between two data readouts int n_cycle = 1; // readout cycle number string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz int[] parms = [1,0]; // Parameters for chop cycles double[] rates = [120.0,1.0,2.0]; // Data rates between and during integrations }{ HIFI_Spectr_fast_chop_proc_aot(data_time,n_cycle,band,lo_freq,["chop_M3","chop_M3right"],parms,rates); } {string,double,double}[] procedure HifiMappingModeOTFSequencerInit { string modeName = "fly"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,5]; // chunk size given by the data rates and optimum speed int n_int_on = 1 in [1,1800]; // Supersamplingfactor int n_linesperscan = 1 in [1,32]; // Number of lines between two OFFs int n_switch_off = 3 in [1,3600]; // Number of data dumps for the OFF integration time int n_cycles = 1 in [1,1200]; // Number of map coverages int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // limits from noise section // Get the drift parameters to compute the drift noise // System Allan variance double[] allanparms = InterpolateSpecAllan(band,lo_freq,oneGHzReference); // rescale to frequency resolution double alpha = allanparms[1]; double binningexp = 1.0 / allanparms[2]; double allan_time_lores = allanparms[0] * pow(1.0 / effResolution{1},binningexp); // Compute derived quantities int main_phase = iceil(0.3 * allan_time_lores); // How many lines could we do at most using datalimit? int n_linesperscan_guess = main_phase / datalimit + 1; n_linesperscan_guess = imax(n_linesperscan_guess * n_linesperscan_guess / npoints,1); // restrict the scan size if(nlines == 1 && n_linesperscan_guess > 1) { n_linesperscan_guess = 2; } else { n_linesperscan_guess = IMultiple(n_linesperscan_guess,nlines); n_linesperscan_guess = imin(n_linesperscan_guess,nlines); } int n_linesperscan_range = 1 - n_linesperscan_guess; if(n_linesperscan_range == 0) { n_linesperscan_range = 1; } double n_pointsperscan = double(n_linesperscan * npoints); // Compute back int int_time_guess = imax(main_phase / iceil(sqrt(n_pointsperscan)),datalimit); int data_time_guess = imin(5,int_time_guess); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } int n_int_on_guess = imax(int_time_guess / data_time_guess,1); int n_int_on_range = 1 - n_int_on_guess; if(n_int_on_range == 0) { n_int_on_range = 1; } // OFF integration int n_switch_off_guess = ifloor(double(n_int_on) * 0.67 * sqrt(n_pointsperscan)); int n_switch_off_range = n_switch_off_guess / 3; if(n_switch_off_range == 0) { n_switch_off_range = 1; } // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"n_int_on",double(n_int_on_guess),double(n_int_on_range)},{"n_linesperscan",double(n_linesperscan_guess),double(n_linesperscan_range)},{"n_switch_off",double(n_switch_off_guess),double(n_switch_off_range)}]; return retvalues; } ///////////////////////////////////////////////////////////////// // Get valid table range {int,int} procedure GetFScanBoundaries { string band = "4a"; // HIFI band double freq_throw = -40.0; // throw of frequency switch in MHz }{ // read master file string calibfile = slookup("frequencystep_masterfile",band,"tablefile"); double[] allfpoints = dcolumn(calibfile,"stepfrequency"); // get table size int iindex1 = length(allfpoints); if(freq_throw < 0.0) { int istart = 1; int iend = iindex1 - 2; double goallo = allfpoints[1] - freq_throw; while(allfpoints[istart] < goallo) { istart = istart + 1; } } else { istart = 1; iend = iindex1 - 2; goallo = allfpoints[iindex1 - 2] - freq_throw; while(allfpoints[iend] > goallo) { iend = iend - 1; } } return {istart,iend}; } //Chopper health check test #1 of chopper during open loop, mode mode HifiManCmd_Chopper_openloop_set_health_check { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ mois_tmcheck("The instrument should be in Standby I mode in open loop context for this test"); //It is done after chopper has been switched on in open loop mois_tmcheck("The instrument must have been switched on with its " + prime_or_redundant + " electronics"); mois_tmcheck("Check that parameter HF_DPR_CHLOOP_S is set to OPEN"); mois_tmcheck("Check that parameter HF_DPR_CHSINE_S is set to ON"); // mois_comment("Performing part one of HIFI internal chopper health check"); StartMode_block_ops(); //Prepare LVDT readout check double c0 = -1.09; double err_C0 = 0.2; double c1 = 1.58; double err_C1 = 0.08; double err_C0_2 = 0.04; if(prime_or_redundant == "Redundant") { c0 = -2.315; err_C0 = 0.2; c1 = 1.555; err_C1 = 0.08; err_C0_2 = 0.4; } //Go to 2048 RAW Chopper_openloop_set_block_ops(0,prime_or_redundant); mois_tmcheck("Check that parameter HF_APR_CH_ROT is " + c0 + "V +/- " + err_C0 + "V. If not stop test and contact the HIFI ICC"); //Go to 2118 RAW Chopper_openloop_set_block_ops(1,prime_or_redundant); mois_tmcheck("Check that parameter HF_APR_CH_ROT has decreased by " + c1 + "V +/- " + err_C1 + "V with respect to its readout value at the previous step. If not stop test and contact the HIFI ICC"); //Back to 2048 RAW Chopper_openloop_set_block_ops(0,prime_or_redundant); mois_tmcheck("Check that parameter HF_APR_CH_ROT is " + c0 + "V +/- " + err_C0_2 + "V. If not stop test and contact the HIFI ICC"); // StopMode_block_ops(); mois_spacon("Write down the OBS_ID corresponding to this mode and communicate it to the HIFI ICC"); } //FSW hotcold, procedure procedure Hot_cold_FSW_fm { string band = "1a"; int integ_time = 8; //Total integration time for delay computation string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast }{ Hot_spectra_FSW_fm(band,integ_time,backend); Cold_spectra_FSW_fm(band,integ_time,backend); } // WBS stand-by, block block WBS_standby_block_ops HIFI 7703 { string band = "0"; // HIFI band string laser_H = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-V laser to be set ON }{ //Get default latchup level {double,string}[] result_d = ConfigurationReader("name_configwbs",["hwh_latchup_s","hwv_latchup_s"],"0",0.0); // //Set zero ON Hifi_HIFI_switch_zero_WBS_H($BBID,"ON"); Hifi_HIFI_switch_zero_WBS_V($BBID,"ON"); delay(1); //Will be done at end of procedure during instrument mode status check //mois_tmcheck("Check that parameter HWH_Zero_S is ON"); //mois_tmcheck("Check that parameter HWV_Zero_S is ON"); //Standby configuration //H-Polarization // string hwh_laser1_s = "OFF"; string hwh_laser2_s = "OFF"; if(laser_H == "Laser1") { hwh_laser1_s = "ON"; } if(laser_H == "Laser2") { hwh_laser2_s = "ON"; } int hwh_heater = 0; //000 string hwh_latchup_s = result_d[0]{1}; int hwh_att_band4 = 7; int hwh_att_band3 = 7; int hwh_att_band2 = 7; int hwh_att_band1 = 7; int hwh_att_in = 15; // //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); {double,string}[] result = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result[0]{0}); //delay(wbs_config_delay); //Wait for configuration to be applied // //V-Polarization // string hwv_laser1_s = "OFF"; string hwv_laser2_s = "OFF"; if(laser_V == "Laser1") { hwv_laser1_s = "ON"; } if(laser_V == "Laser2") { hwv_laser2_s = "ON"; } int hwv_heater = 0; //000 string hwv_latchup_s = result_d[1]{1}; int hwv_att_band4 = 7; int hwv_att_band3 = 7; int hwv_att_band2 = 7; int hwv_att_band1 = 7; int hwv_att_in = 15; // //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); delay(wbs_config_delay); //Wait for configuration to be applied // //Will be done at end of procedure during instrument mode status check //mois_tmcheck("Check that parameter HWH_Laser1_S is " + hwh_laser1_s); //mois_tmcheck("Check that parameter HWH_Laser2_S is " + hwh_laser2_s); //mois_tmcheck("Check that parameter HWV_Laser1_S is " + hwv_laser1_s); //mois_tmcheck("Check that parameter HWV_Laser2_S is " + hwv_laser2_s); //mois_tmcheck("Check that parameter HWH_IN_ATT is set to 15, and parameters HWH_Band_1_ATT, HWH_Band_2_ATT, HWH_Band_3_ATT, HWH_Band_4_ATT are set to 7"); //mois_tmcheck("Check that parameter HWV_IN_ATT is set to 15, and parameters HWV_Band_1_ATT, HWV_Band_2_ATT, HWV_Band_3_ATT, HWV_Band_4_ATT are set to 7"); } // Fast chop integration OFF-ON-OFF-ON... with telescope at OFF position block HIFIFastChopOffIntegration HIFI 6043 { int data_time = 4; // Integration time between two data readouts int n_cycle = 1; // readout cycle number string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz int[] parms = [1,0]; // Parameters for chop cycles double[] rates = [120.0,1.0,2.0]; // Data rates between and during integrations }{ HIFI_Spectr_fast_chop_proc_aot(data_time,n_cycle,band,lo_freq,["chop_M3left","chop_M3right"],parms,rates); } ////////////////////////////////////////////////////////////////////////// // Procedure to generate the composite position telescope command for the // observing mode {int,int,int,string,int,double,double,bool,double,double,double,int,double,int,int,int,int,int,int} procedure PositionSwitch_telescope { int naifid = 0; // Tracking object ID {double,double} onposition = {0.0,0.0}; // Coordinates of the source {double,double} offposition = {0.2,0.2}; // Coordinates of the OFF position string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int} timing = {16,16,16,16,21,11,1800,32,2,2,0,0,false,false,50,0}; int n_cycles = 2; // Number of half OFF-ON-ON-OFF cycles }{ // Assign values int on_pointing = timing{2}; // Pointing on on-position int off_pointing = timing{3}; // Pointing OFF on-position int loadlength = timing{4}; // Load duration int n_loadinterval = timing{7}; // Number of nods between load measurements int initlength = timing{14}; // Initial setup time int dangling = timing{15}; // Final load measurement // Create variables for telescope command string ib = GetBoresight(band,lo_freq,false); // A change of ra-dec depending on naifid may be needed double ra = onposition{0}; double dec = onposition{1}; // Compute offset: This is always in sky coordinates {double,double} offset = AngularOffset(onposition,offposition); double patt = AngleFromVector(offset); double slewlength = AngleVectorLength(offset); slewlength = max(slewlength * 3600.0,2.0); // Check parameter compatibility with pointing command for parameters // which are no direct input parameters if(on_pointing < 10) { SError("Source pointing phase length too short. Increase the number of integrations."); } if(off_pointing < 10) { SError("OFF pointing phase length too short. Increase the number of integrations."); } if(slewlength > 7200.0) { IError("Slew distance too long. Choose a closer OFF position."); } // repetition at multiple frequencies not yet implemented: int thold = 0; int nhold = 0; int n_repeat = n_cycles; // return parameters in required order return {initlength,0,dangling,ib,naifid,ra,dec,true,patt,0.0,0.0,n_repeat,slewlength,on_pointing,off_pointing,loadlength,n_loadinterval,thold,nhold}; } // Drift noise from an asymmetric two-phase observation // This is still to be scaled by a factor 1.0/(B_fluct_A*T_Allan) double procedure AsymmetricDrift { double xa = 0.1; // integration time in phase A relative to Allan time double xb = 0.1; // integration time in phase B relative to Allan time double d = 0.3; // delay relative to Allan time double alpha = 2.5; // drift exponent }{ if(xa >= 0.0) { double a1 = alpha + 1.0; double y = ((pow(xa + xb + d,a1) - pow(xa + d,a1) - pow(xb + d,a1) + pow(d,a1)) / (xa * xb) - pow(xa,a1) / (xa * xa) - pow(xb,a1) / (xb * xb)) / (pow(2.0,alpha) - 2.0); } else { // forbid x values <=0 y = 1.0E11 * (1.0 - xa); } return y; } // Drift noise from a symmetric two-phase observation // This is still to be scaled by a factor 1.0/(B_fluct*T_Allan) double procedure TwoPhaseDrift { double x = 0.1; // integration time relative to Allan time double d = 0.3; // delay relative to Allan time double alpha = 2.5; // drift exponent }{ if(x >= 0.0) { double a1 = alpha + 1.0; double y = (pow(2.0 * x + d,a1) - 2.0 * pow(x + d,a1) + pow(d,a1) - 2.0 * pow(x,a1)) / ((pow(2.0,alpha) - 2.0) * x * x); } else { // forbid x values <=0 y = 1.0E11 * (1.0 - x); } return y; } // Take total power spectra, block // Use AOT efficient timing block Spectro_total_power_AOTLike_block_fm HIFI 3930 { string band = "1a"; // HIFI band int[] timing_parms = [4,1]; //single readout time in sec. and n_wbs_start string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); int integ_time = timing_parms[0] * timing_parms[1]; //Compute data-rate double[] rates = ILT_datarate_proc_fm(band,backend,"tp",integ_time); //Take spectrum // set data rates non_ess_hk_data_rate(rates[2] / 1024.0); data_rate(rates[0] / 1024.0); // Hifi_HIFI_Spectr_total_power($BBID); delay(integ_time); // // reset data rates non_ess_hk_data_rate(rates[1] / 1024.0); data_rate(0.0); } /////////////////////////////////////////////////////// // Generic procedures to tune S/S in HIFI // Set magnet currents for both polarizations, procedure procedure Set_Magnet_current_proc_fm { double mag_curr_h = 1.0; //Magnet current H polarization double mag_curr_v = 1.0; //Magnet current V polarization }{ Hifi_HIFI_CH1_MX_MG_C($BBID,mag_curr_h); Hifi_HIFI_CV1_MX_MG_C($BBID,mag_curr_v); delay(1); } // Integrate only on internal hot, block // We take 1 spectrum per phase. block Stability_inthot_fm HIFI 3425 { string band = "1a"; // HIFI band int n = 100; //The number of integrations int integ_time = 4; //Total integration time in sec. to be set at end of test string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code string obsmode = "fastchop" in ["fastchop","tp"]; //tp or fastchop double chop_phase = 1.0 in [0.2,2.0]; // Chop phase length }{ Start_block(); Chopper_Rotation_proc_fm(band,"chop_M3_ang","chop_hot_ang"); //Look at HBB //Get chopper settings {double,string}[] result = ConfigurationReader("name_confilfpu",["chop_hot"],band,0.0); double chop_hot = result[0]{0}; //Do a long integration: // - for B1-5, use 2 sec. with wbs or hrs only, thus tp is OK // - for B6: use 1 sec. with reduced wbs (wbsFast), thus tp is OK //We implement a special spectroscopy configuration with fixed values if(obsmode == "tp") { Total_power_spectro_for_Stability_proc_fm(band,n,integ_time,backend,hrs_mode); } if(obsmode == "fastchop") { Fast_chop_spectro_for_Stability_proc_fm(band,n,integ_time * 2,backend,hrs_mode,chop_hot,chop_hot,chop_phase); } } //HIFI LO tuning, block //Target current is read from look-up table block LO_tuning_block_fm HIFI 3616 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency }{ //Clear potential failure mode Set_LO_Nominal_proc_fm(); // //Start_block(); {double,string}[] result = ConfigurationReader("name_confpolar4lotune",[band],band,lo_freq); string mixer_polarization = result[0]{1}; // //Get target mixer current result = ConfigurationReader("name_confilmix",["target_mx_c_h","target_mx_c_v"],band,lo_freq); double target_current = result[0]{0}; if(mixer_polarization == "V") { target_current = result[1]{0}; } if(mixer_polarization == "B") { target_current = 0.5 * (result[1]{0} + result[0]{0}); } // //Fetch LO parameters string name_configlcu = "name_configlcu_a"; string name_configlo = "name_configlo_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlcu = "name_configlcu_b"; name_configlo = "name_configlo_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; name_configlcutune = "name_configlcutune_b"; } // result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // result = ConfigurationReader(name_configlotune,["step_drain2_v","nsteps","step_time"],band,lo_freq); double step_drain2_v = result[0]{0}; int nsteps = iround(result[1]{0}); double step_time = result[2]{0}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // //Adjust scan cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); double drain2_safe = cresult[0]; // double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); // //For all bands, scan will be done with decreasing drain2 voltages //The best guess is taken from look-up table double tune_range = 0.1; result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lo_freq); double middle_d2 = result[0]{0}; double drain2_v_start = min(middle_d2 * (1.0 + tune_range / 2.0),drain2_bluemax); double drain2_v_end = (1.0 - tune_range / 2.0) / (1.0 + tune_range / 2.0) * drain2_v_start; step_drain2_v = (drain2_v_end - drain2_v_start) / double(nsteps - 1); // result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); // //Send command HIFI_Configure_LCU_proc_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,macro_checksum,config_lo_delay); // //delay(5); //to settle at this value // //Load vector scan //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Load_vector_safe_1a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "1b") { //Band 1b Hifi_HIFI_Load_vector_safe_1b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2a") { //Band 2a Hifi_HIFI_Load_vector_safe_2a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2b") { //Band 2b Hifi_HIFI_Load_vector_safe_2b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3a") { //Band 3a Hifi_HIFI_Load_vector_safe_3a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3b") { //Band 3b Hifi_HIFI_Load_vector_nom_3b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "4a") { //Band 4a Hifi_HIFI_Load_vector_safe_4a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "4b") { //Band 4b Hifi_HIFI_Load_vector_safe_4b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "5a") { //Band 5a Hifi_HIFI_Load_vector_nom_5a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "5b") { //Band 5b Hifi_HIFI_Load_vector_nom_5b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6a") { //Band 6a Hifi_HIFI_Load_vector_nom_6a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6b") { //Band 6b Hifi_HIFI_Load_vector_nom_6b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7a") { //Band 7a Hifi_HIFI_Load_vector_nom_7a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7b") { //Band 7b Hifi_HIFI_Load_vector_nom_7b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } // delay(1); // //Execute tuning: check which mixer is to be used if(mixer_polarization == "V") { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCV($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCV($BBID,target_current); } } else { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCH($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCH($BBID,target_current); } } // double time_needed = double(nsteps) * step_time; delay(iround(time_needed + 2.0 + 0.5)); //0.5s added for completion of load_vector // //Store settings into available register HIFI_HL_store_tm_only_proc_fm(); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } //LCU IV curves, procedure procedure Measure_LCU_IV_proc_fm { string band = "1a" in ["ALL","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string multiplier = "M1" in ["ALL","M1","M2","M3"]; //Multiplier to be measured: M1, M2 or M3 int operation_delay = 60; //When ALL is selected, Waiting delay between two measurements on a band (e.g. to change connector) }{ // //Array of names string[] band_array = ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; string[] multiplier_array = ["M1","M2","M3"]; // //Case of all bands done string band_loop = "1a"; string multiplier_loop = "M1"; // if(band == "ALL") { //loop on bands for(int i = 1 .. 14) { //Translate band name band_loop = band_array[i - 1]; if(multiplier == "ALL") { for(int j = 1 .. 3) { multiplier_loop = multiplier_array[j - 1]; Measure_LCU_IV_block_fm(band_loop,multiplier_loop); } } else { Measure_LCU_IV_block_fm(band_loop,multiplier); } delay(operation_delay); } } else { //do only one band if(multiplier == "ALL") { for(int k = 1 .. 3) { multiplier_loop = multiplier_array[k - 1]; Measure_LCU_IV_block_fm(band,multiplier_loop); } } else { Measure_LCU_IV_block_fm(band,multiplier); } delay(operation_delay); } // } //Get blue min double procedure Get_BLUE_MIN_D2_proc_fm { string band = "4a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978.2; //LO Frequency }{ //Anticipated implementation of SCR-2220 string name_configlcu = "name_configlcu_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlcu = "name_configlcu_b"; } {double,string}[] result = ConfigurationReader(name_configlcu,["drain2_v_blmn","drain2_v_blmx"],band,lo_freq); double drain2_min = 0.0; if(band == "1a") { drain2_min = result[0]{0}; } if(band == "1b") { drain2_min = result[0]{0}; } if(band == "2a") { drain2_min = result[0]{0}; } if(band == "2b") { drain2_min = result[0]{0}; } if(band == "3a") { drain2_min = result[0]{0}; } if(band == "3b") { drain2_min = result[0]{0}; } if(band == "4a") { drain2_min = result[0]{0}; } if(band == "4b") { drain2_min = result[0]{0}; } if(band == "5a") { drain2_min = result[0]{0}; } if(band == "5b") { drain2_min = result[0]{0}; } if(band == "6a") { drain2_min = result[0]{0}; } if(band == "6b") { drain2_min = result[0]{0}; } if(band == "7a") { drain2_min = result[0]{0}; } if(band == "7b") { drain2_min = result[0]{0}; } return drain2_min; } //////////////////////////////////// // Fast chop DBS raster - cross observing mode // {string,double,double}[] procedure HifiMappingProcFastDBSCrossSequencerInit { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source double stepsize = 0.0050 in [5.5556E-4,0.13333]; // Distance between subsequent points in the two raster lines int npoints = 10 in [2,100]; // Number of points per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power levels bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 10 in [4,80]; // data dump interval int n_int_on = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_switch_on = 1 in [1,1800]; // number of data transfer cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode // inherit from dbs-raster mode {string,double,double}[] retvalues = HifiMappingProcFastDBSRasterSequencerInit(naifid,ra,dec,{0.0,double(npoints / 2) * stepsize},2,stepsize,npoints,band,lo_freq,effResolution,continuumDetection,oneGHzReference,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_switch_on,n_pointsperscan,n_cycles,load_interval,docommands); return retvalues; } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // The blocks //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //Integration on Internal cold, block block Cold_spectra_fm HIFI 3222 { string band = "1a"; int integ_time = 4; //Total integration time in sec.: at least 2sec ! string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); //Rotate chopper: assume we come from M3 Chopper_Rotation_proc_fm(band,"chop_M3_ang","chop_cold_ang"); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // } //////////////////////////////////// // Routine to provide initial guesses for sequence parameters // Load chop mode without baseline calibration // {string,double,double}[] procedure HifiPointProcLoadChopNoRefSequencerInit { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rates int n_cycles = 2 in [1,3600]; // number of half load-sky-sky-load cycles on ON int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode // limit on data rate {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // limits from noise section // Get the drift parameters to compute the drift noise // System Allan variance double[] allanparms = InterpolateSpecAllan(band,lo_freq,oneGHzReference); // rescale to frequency resolution double alpha = allanparms[1]; double binningexp = 1.0 / allanparms[2]; double allan_time_lores = allanparms[0] * pow(1.0 / effResolution{1},binningexp); // Compute derived quantities int data_time_guess = imin(imax(iceil(0.3 * allan_time_lores),datalimit),20); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } // Contruct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)}]; return retvalues; } //Set DC bias without switching on the chain, block //All input parameters shall be given by the user block LCU_DC_health_check_block_fm HIFI 3699 { string band = "1a" in ["ALL","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double plevel_v = 0.0; // HL_PL_C double m1_v = 0.0; // HL_M1_V double m2_v = 0.0; // HL_M2_V double m3_v = 0.0; // HL_M3_V double gate1_v = 0.0; // HL_Gate1_V double gate2_v = 0.0; // HL_Gate2_V double drain1_v = 0.0; // HL_Drain1_V string curlim1_v = "1.5" in ["1.5","1.3","1.22","1.4"]; // HL_Curlim1 double drain2_v = 0.0; // HL_Drain2_1A_V string curlim2_v = "1.5" in ["1.5","1.3","1.22","1.4"]; // HL_Curlim2 }{ // //Start_block(); // //Execute configuration //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Conf_diag_LCU_ch1a($BBID,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "1b") { //Band 1b Hifi_HIFI_Conf_diag_LCU_ch1b($BBID,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "2a") { //Band 2a Hifi_HIFI_Conf_diag_LCU_ch2a($BBID,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "2b") { //Band 2b Hifi_HIFI_Conf_diag_LCU_ch2b($BBID,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "3a") { //Band 3a Hifi_HIFI_Conf_diag_LCU_ch3a($BBID,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "3b") { //Band 3b Hifi_HIFI_Conf_diag_LCU_ch3b($BBID,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "4a") { //Band 4a Hifi_HIFI_Conf_diag_LCU_ch4a($BBID,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "4b") { //Band 4b Hifi_HIFI_Conf_diag_LCU_ch4b($BBID,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "5a") { //Band 5a Hifi_HIFI_Conf_diag_LCU_ch5a($BBID,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "5b") { //Band 5b Hifi_HIFI_Conf_diag_LCU_ch5b($BBID,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "6a") { //Band 6a Hifi_HIFI_Conf_diag_LCU_ch6a($BBID,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "6b") { //Band 6b Hifi_HIFI_Conf_diag_LCU_ch6b($BBID,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "7a") { //Band 7a Hifi_HIFI_Conf_diag_LCU_ch7a($BBID,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "7b") { //Band 7b Hifi_HIFI_Conf_diag_LCU_ch7b($BBID,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } // //Then need to switch on band string band_new = Translate_band_name(band); Hifi_HIFI_HL_switchon($BBID,"channel_" + band_new); // {double,string}[] result = ConfigurationReader("name_delays",["switch_on_delay"],"0",0.0); int switch_on_delay = iround(result[0]{0}); delay(switch_on_delay); // //Switch off band to prepare for next band Hifi_HIFI_HL_Switch_off($BBID); // result = ConfigurationReader("name_delays",["switch_off_delay"],"0",0.0); int switch_off_delay = iround(result[0]{0}); delay(switch_off_delay); } // Noise ratio from an OTF observation // double procedure OtfNoiseRatio { double n = 10.0; // number of points in one scan double[] parameters = [0.02,0.4,0.05,0.667,2.5]; // Parameters: integration time, delay, slew from OFF relative to Allan time, ratio of t_off time to sqrt(n)*t_on, drift exponent }{ {double,double} noisevalues = OtfNoiseValues(n,parameters); double y = noisevalues{1} / noisevalues{0}; return y; } // Slow chop integration at OFF position ON-OFF-OFF-ON... block HIFISlowChopOffIntegration HIFI 6032 { int data_time = 4; // Integration time between two data readouts int n_cycle = 1; // chop cycle number string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double[] rates = [120.0,1.0,2.0]; // Data rates between and during integrations }{ HIFI_Spectr_slow_chop_proc_aot(data_time,n_cycle,band,lo_freq,["chop_M3left","chop_M3right"],rates); } // Procedure used by the spectral scan sequencer to compute the // maximum frequency group length int procedure SpotSpectralScanGroupLength { string band = "4a"; double lo_freq1 = 978.2; double lo_freq2 = 979.6; int redundancy = 4; }{ // start Volkers list double lo_freq = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz // general definitions double factorMHzPerGHz = 1000.0; // start translation lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; // Call CUS routine int grouplen = GetSpectralScanGroupLength(band,lo_freq,lo_freq_up,redundancy); return grouplen; } //Set LOU to diagnostic, block block Set_LO_Diagnostic_block_fm HIFI 3664 { }{ // //Start_block(); {double,string}[] result = ConfigurationReader("name_delays",["set_to_nominal_delay"],"0",0.0); int set_to_nominal_delay = iround(result[0]{0}); // Hifi_HIFI_HL_Diagnostic($BBID); delay(set_to_nominal_delay); // } ////////////////////////////////////////////// /// Blocks ////////////////////////////////////////////// //General LO configuration command // Uses SFT approach with old 5 TM TC call block HIFI_Configure_LCU_block_sft HIFI 3977 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency int freq_nx = 0; // HL_freq_nx int lsu_main = 0; // HL_LSU_main int lsu_offset = 0; // HL_LSU_offset int d2_step = 1; // HL_D2_step double plevel_v = 0.0; double m1_v = 9.0; double m2_v = -2.0; double m3_v = 0.0; double gate1_v = -2.5; double gate2_v = -2.5; double drain1_v = 2.8; string curlim1_v = "1.4"; double drain2_v = 2.6; string curlim2_v = "1.4"; int macro_checksum = 0; // HL_macro_checksum int config_lo_delay = 6; }{ //Check that Vd2 is within the blue limits drain2_v = Check_BLUE_LIMIT_D2_proc_fm(band,lo_freq,drain2_v); // //Start_block(); // //Execute configuration //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Conf_safe_LCU_ch1a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "1b") { //Band 1b Hifi_HIFI_Conf_safe_LCU_ch1b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "2a") { //Band 2a Hifi_HIFI_Conf_safe_LCU_ch2a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "2b") { //Band 2b Hifi_HIFI_Conf_safe_LCU_ch2b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "3a") { //Band 3a Hifi_HIFI_Conf_safe_LCU_ch3a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "3b") { //Band 3b Hifi_HIFI_Conf_safe_LCU_ch3b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "4a") { //Band 4a Hifi_HIFI_Conf_safe_LCU_ch4a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "4b") { //Band 4b Hifi_HIFI_Conf_safe_LCU_ch4b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "5a") { //Band 5a Hifi_HIFI_Conf_nom_LCU_ch5a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "5b") { //Band 5b Hifi_HIFI_Conf_nom_LCU_ch5b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "6a") { //Band 6a Hifi_HIFI_Conf_nom_LCU_ch6a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "6b") { //Band 6b Hifi_HIFI_Conf_nom_LCU_ch6b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "7a") { //Band 7a Hifi_HIFI_Conf_nom_LCU_ch7a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "7b") { //Band 7b Hifi_HIFI_Conf_nom_LCU_ch7b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } // delay(config_lo_delay); // //Store settings into available register //HIFI_HL_store_tm_proc_fm(); // //Additional read of TM pages LCU_Read_TM_pages_OLD_proc_fm(); } // Functional test with unpumped mixer, procedure // This case assumes no backend attenuator setting is done procedure FT_unpumped { string band = "1a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4,etc int integ_time = 4; //Integration time string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Do not switch-off LO, rather, use the 3b-dissipative mode //LCU_switch_off_block_fm(); string band_dissipate = "3b"; double lofreq_dissipate = 958.0; double[] cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band_dissipate,lofreq_dissipate); double drain2_v = cresult[0]; LCU_config_nominal_w_D2_proc_fm(band_dissipate,lofreq_dissipate,drain2_v); // Put heaters explicitly to 4 V HL_heater_block_aot(band_dissipate,"nominal"); //Fix for SPR-2520: init mixer band double[] result_d = CalibrationReader("name_keyfreq",["keyfreq"],band,0.0); double lo_freq = result_d[0]; Init_MSA_HBB_fm(band,"CLOSE",lo_freq,"ON"); // //WBS calibration if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band); } // //(Re)configure spectrometers integration Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); // //Measure IF noise IFcalibration(band,integ_time,backend); //IVcurve before and after magnet set to 0: not for band 6 if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { //IV curve with default parameters IVcurve_raw_fm(band); //Set magnet to zero and get IVcurve: only up to band 5 since band6-7 have no magnets IVcurve_with_zero_magnet_fm(band); //Heater Heater_fm(band); //Now sets back the magnet to nominal value //Set magnet to zero and get IVcurve: only up to band 5 since band6-7 have no magnets IVcurve_with_zero_magnet_fm(band); } //IVcurve after defluxing IVcurve_defluxed_fm(band); } //HIFI-COP-2.3-Param-Scan: 1 per pair of scanned parameters obs HifiEng_Parameter_Scan_COP { int index = 1 in [1,7]; // Test case index as of config_paramscan_COP.config int phase = 1 in [1,2]; //Measurement phase int m1_index = 1 in [1,5]; //Index of M1 value - only applicable is phase = 1. Index 1 is least negative int m2_index = 1 in [1,5]; //Index of M2 value - only applicable is phase = 1. Index 1 is least negative int bias_index = 1 in [1,3]; //Index of bias value - only applicable is phase = 2 int imix_index = 1 in [1,3]; //Index of Imix value - only applicable is phase = 2 }{ //Read corresponding band string tab = "config_paramscan_COP.config"; string band = slookup(tab,"" + index,"band"); //General parameters in use int integ_time = 4; //Integration time PER PHASE for the slowchop measurement string[] hrs_mode = ["wb1","wb1"]; //For bands 6 and 7, use wb8 if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { hrs_mode = ["wb8","wb8"]; } // // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Parameter_Scan_COP_proc_ops(index,phase,integ_time,hrs_mode,m1_index,m2_index,bias_index,imix_index)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Parameter_Scan_COP_proc_ops(index,phase,integ_time,hrs_mode,m1_index,m2_index,bias_index,imix_index); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } // Step 1 of QLA_Testcontrol fine magnet-tuning loop // Minimum IF power in the spectra block Magnet_scan_fine_fm HIFI 3203 { string band = "1a"; int integ_time = 4; //Integration time double lo_freq = 522.0; //LO frequency string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ Start_block(); {double,string}[] result_d = ConfigurationReader("name_confilfpu",["magnet_current_min_h","magnet_current_max_h","magnet_current_min_v","magnet_current_max_v","jitter_margin","magnet_steps_h","magnet_steps_v"],band,0.0); //H polar double magnet_min_h = result_d[0]{0}; double magnet_max_h = result_d[1]{0}; //V polar double magnet_min_v = result_d[2]{0}; double magnet_max_v = result_d[3]{0}; // double magnet_min = max(magnet_min_h,magnet_min_h); double magnet_max = min(magnet_max_h,magnet_max_h); // int jitter_margin = iround(result_d[4]{0}); int duration_scan = 0; double step_duration = double(2 + 2 * jitter_margin); int max_per_command = 40; int steps = 0; int steps_done = 0; // int steps_wanted_h = iround(result_d[5]{0}); int steps_wanted_v = iround(result_d[6]{0}); int steps_wanted = iround(max(double(steps_wanted_h),double(steps_wanted_v))); // double step = Stepsize(magnet_min,magnet_max,steps_wanted,"hifi_HIF_mx_mg_step_C"); double margin = Stepmargin(magnet_min,magnet_max,"hifi_HIF_mx_mg_step_C"); steps_wanted = 1 + iceil((magnet_max - magnet_min) / step); // force the last portion to less than max_per_command if(max_per_command * (steps_wanted / max_per_command) == steps_wanted) { steps_wanted = steps_wanted - 1; } // //Set magnet to maximum to avoid hysteresis Hifi_HIFI_CH1_MX_MG_C($BBID,magnet_max_h); Hifi_HIFI_CV1_MX_MG_C($BBID,magnet_max_v); delay(1); // double magnet_current_h = magnet_min_h; double magnet_current_v = magnet_min_v; // //We use special biasing to evidence the minima in the magnet scan result_d = ConfigurationReader("name_confilmix",["bias4magn_h","bias4magn_v"],band,lo_freq); double bias_h = result_d[0]{0}; double bias_v = result_d[1]{0}; // //Start scan: from max. to min. magnet downward. while(steps_done < steps_wanted) { steps = steps_wanted - steps_done; if(steps > max_per_command) { steps = max_per_command; } magnet_current_h = magnet_max_h - double(steps_done) * step; magnet_current_v = magnet_max_v - double(steps_done) * step; Hifi_HIFI_CH1_MX_MG_C($BBID,magnet_current_h); Hifi_HIFI_CV1_MX_MG_C($BBID,magnet_current_v); delay(1); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // steps_done = steps_done + 1; } //Back to nominal values //First set magnet to maximum to avoid hysteresis Hifi_HIFI_CH1_MX_MG_C($BBID,magnet_max_h); Hifi_HIFI_CV1_MX_MG_C($BBID,magnet_max_v); delay(1); //Nominal values result_d = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v","norm_bias_h","norm_bias_v"],band,lo_freq); magnet_current_h = result_d[0]{0}; magnet_current_v = result_d[1]{0}; bias_h = result_d[2]{0}; bias_v = result_d[3]{0}; Hifi_HIFI_FCU_parameter_scan($BBID,1,1,step_duration,bias_h,bias_v,0.0,magnet_current_h,magnet_current_v,0.0); delay(2); } // Sort array, bubblesort, maximum will be first element double[] procedure DSort { double[] x = [0.0]; // Input array int nlen = 1; // Array length (keep dan gling numbers untouched) }{ double tmpstore = 0.0; // double loop for(int i = 0 .. nlen - 2) { for(int j = 1 .. nlen - 1 - i) { if(x[j] > x[j - 1]) { tmpstore = x[j]; x[j] = x[j - 1]; x[j - 1] = tmpstore; } } } return x; } ///////////////////////////////////////////////////////////////// // Procedure to compute total dead times for the mode // {double,double,double} procedure FastDBSRaster_deadtimes { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // data dump interval int n_int = 20; // number of integrations in one data dump interval int n_data = 3; // number of chop cycles in one integration int n_load = 0; // number of integrations in one pointing phase int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase double tdead = 10.0; // Dead time from telescope }{ ////////////////////////////////////////////////////////////////////// // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Special meaning of n_load here if(n_load == 0) { int n_seq = 1; } else { n_seq = n_load; } // Compute parameters for the instrument timing {double,double} tinst = GetInstDeadFastChop(data_time,n_int,n_data,band,lo_freq,backendreadoutparms); // dead time double tdeadint = double(data_time * n_data) - tinst{0}; // subtract dead times in switches // only half of them are subtracted due to ABAB scheme tdeadint = tdeadint - double(n_int * n_data) * tinst{1}; // Total dead time per cycle, only one point still not covered double tdead_tot = tdead + double(2 * n_seq) * tdeadint; // Integration time double tphaseint = tinst{0} / double(2 * n_int * n_data); return {tdead_tot,tphaseint,tinst{1}}; } // Compute Slow Chop delay necessary for integration, procedure procedure Apply_Slow_Chop_delay { int total_time = 12; //single readout time * n_wbs_start string band = "1a"; // HIFI band string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Packet transfer time {double,string}[] result = ConfigurationReader("name_delays",["wbs_transfer_delay"],band,0.0); // int wbs_packet_transfer_time = iround(result[0]{0}); // //In case less channels are used, one must adapt the transfer time if(backend == "hrs" || backend == "wbs") { //wbs_packet_transfer_time = 0; //3000; } if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { //expect half backend //wbs_packet_transfer_time = 0; //2000; } // //Compute delay int delay_slow_chop = total_time + wbs_packet_transfer_time / 1000; //debug_print("Slow Chop delay: " + delay_slow_chop + " sec"); // //Apply delay delay(delay_slow_chop); // } ////////////////////////////////////////////////////////////////////// // Compatibility procedure to provide the same API as used in // the previous versions // // Returns the actual integration time and the dead time per phase {double,double} procedure ConfigSpectroscopySlowChop { /* Integration time */ int data_time = 4; // Integration time between two data readouts int n_data = 2; // Integration time counter /* Parameters determining the delays - used in calibration reader */ string chopmode = "chop" in ["chop","lchop","fs","hot-cold","tp"]; // Chop mode determining the modulation dead time string band = "1a"; // HIFI band double lo_freq = 522000.0; // LO frequency /* Backend settings */ {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // HRS1/2 {used,resolution,subbands used}, WBS1/2 {used,channel windows} bool docommands = false; // Whether instrument command is issued }{ // Get timing parameters {int,int,int,int,int,int,int,int,int,int} timing = ConfigureSpectroscopyParams(data_time,n_data,chopmode,band,lo_freq,backendreadoutparms); int n_wbs_start = timing{0}; int r_hrs = timing{1}; int n_wbs_integr = timing{2}; int n_hrs_integr = timing{3}; int del_hrs = timing{4}; int del_wbs = timing{5}; int t_acc_wbs = timing{6}; int t_acc_hrs = timing{7}; int tdead = timing{8}; int tint_act = timing{9}; // Transfer mode {int,int,int,int,int[],int[],string} backendconfigure = ConfigSpectroscopyBackends(data_time,backendreadoutparms); int wbs_rshift = backendconfigure{0}; int hrs_rshift = backendconfigure{1}; int hrsh_sel = backendconfigure{2}; int hrsv_sel = backendconfigure{3}; int[] wbsh_par = backendconfigure{4}; int[] wbsv_par = backendconfigure{5}; string packing = backendconfigure{6}; // Now call the command if(docommands) { Hifi_HIFI_config_spectroscopy($BBID,n_wbs_start,r_hrs,n_wbs_integr,n_hrs_integr,del_hrs,del_wbs,t_acc_wbs,t_acc_hrs,wbsh_par[0],wbsh_par[1],wbsh_par[2],wbsh_par[3],wbsh_par[4],wbsh_par[5],wbsh_par[6],wbsh_par[7],wbsv_par[0],wbsv_par[1],wbsv_par[2],wbsv_par[3],wbsv_par[4],wbsv_par[5],wbsv_par[6],wbsv_par[7],hrs_rshift,wbs_rshift,hrsh_sel,hrsv_sel,packing); } // Return actual integration time and dead time per readout return {double(tint_act) / 1000.0,double(tdead) / 1000.0}; } //HIFI-COP-2.1-CPR-RespTime procedure Chopper_Response_time_COP_proc_ops { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ mois_comment("This test needs the successful execution and analysis of the full chopper health check suite"); mois_comment("Start of HIFI Chopper response time test"); mois_comment("Please check that instrument was switched on with the " + prime_or_redundant + " unit"); //General parameters in use string band = "1a"; // HIFI band double lo_freq = 520.0; //LO frequency string hbb_heater = "ON"; //hot source on/off string chopper_loop = "CLOSE"; int milliSecSample = 3; // interval between samples int samplesBefore = 30; int samplesAfter = 1000; // string chop_startup_prime_red = "chop_startup_cold_prime"; if(prime_or_redundant == "Red") { chop_startup_prime_red = "chop_startup_cold_red"; } {double,string}[] result = ConfigurationReader("name_chopper",[chop_startup_prime_red],"0",0.0); if(chopper_loop == "OPEN") { result = ConfigurationReader("name_chopper",["chop_startup_warm"],"0",0.0); } // mois_step("Init FPU"); Init_MSA_ops(band,chopper_loop,lo_freq,result[0]{0},hbb_heater,prime_or_redundant); mois_step("Rotate to hot internal load"); //Rotate to HBB Chopper_Rotation_block_fm_COP(band,"chop_M3right_ang","chop_hot_ang",prime_or_redundant); mois_step("Response time sequence"); //Chopper response time Chopper_Response_time_block_COP(band,milliSecSample,samplesBefore,samplesAfter,prime_or_redundant); // } {int,double,double,double,double,double} procedure HifiIdealMode { string modeName = "pos"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode // Get parameters which are needed double center_lo_freq = 0.5 * (lo_freq + lo_freq_up); double tsys = InterpolateTsys(band,center_lo_freq); double eta_mb = InterpolateCoupling(band,center_lo_freq); double[] gssb = InterpolateGssb(band,center_lo_freq); double phasetime = double(goalTime); double noiseratio = 0.0; // Compute total double sideband noise double dsbnoise_lores = tsys * sqrt(1.0 / (effResolution{1} * 1000000.0 * phasetime)); double dsbnoise_hires = tsys * sqrt(1.0 / (effResolution{0} * 1000000.0 * phasetime)); // Translate to the main beam scale, correct for eta_mb // (This is typically not done at ground based telescopes, // but leads often to problems there - to be discussed.) dsbnoise_lores = dsbnoise_lores / eta_mb; dsbnoise_hires = dsbnoise_hires / eta_mb; // Get single sideband noise equivalent double usbnoise_lores = dsbnoise_lores / gssb[0]; double usbnoise_hires = dsbnoise_hires / gssb[0]; double lsbnoise_lores = dsbnoise_lores / gssb[1]; double lsbnoise_hires = dsbnoise_hires / gssb[1]; // return total time with initial slew int returntime = goalTime; // Originally I had added 180s from telescope // Now make corrections for maps or spectral scans if(npoints * nlines > 1) { double factor = sqrt(double(nlines * npoints)); usbnoise_lores = usbnoise_lores * factor; usbnoise_hires = usbnoise_hires * factor; lsbnoise_lores = lsbnoise_lores * factor; lsbnoise_hires = lsbnoise_hires * factor; } if(lo_freq_up > lo_freq) { {int,double,double[],int[][],int,bool} fqparms = MakeFreqGrid(band,lo_freq,lo_freq_up,redundancy,0.0,1); factor = sqrt(double(fqparms{0} / fqparms{4})); usbnoise_lores = usbnoise_lores * factor; usbnoise_hires = usbnoise_hires * factor; lsbnoise_lores = lsbnoise_lores * factor; lsbnoise_hires = lsbnoise_hires * factor; } // Return noise values and the maximum ratio of drift to radiometric noise return {returntime,usbnoise_lores,usbnoise_hires,lsbnoise_lores,lsbnoise_hires,noiseratio}; } // Routine to extract the settings for the two HK regimes string[] procedure QueryHKPattern { bool active = false; // Whether to actively query the spectrometers }{ // HK pattern according to SRON-U/HIFI/SP/2001-001 4.3.2 PDU status if(active) { int pattern = ifloor(dlookup("datarates","allreadpattern","value")); } else { pattern = ifloor(dlookup("datarates","noreadpattern","value")); } // translate into new mask of arguments string[] mask = ["OFF","OFF","OFF","OFF","OFF","OFF"]; for(int i = 0 .. 5) { if(pattern % 2 > 0) { mask[i] = "ON"; } else { mask[i] = "OFF"; } pattern = pattern / 2; } return mask; } ///////////////////////////////////////////////////////////////// // Slow chop dual beam switch observing mode - special version for Jupiter // // Implemented as procedure returning time and noise levels for HSPOT {int,double,double,double,double,double} obs HifiPointProcJupiterDBS { /* Setup parameters */ int naifid = 0; // Tracing object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_switch_on = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per pointing int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Engineering - Jupiter - DBS slowChop",{data_time,0,0,n_switch_on,0,0,0,0,n_cycles,load_interval}); // Call first part of the timing computer // Two changes relative to the normal DBS // 1) The longer load duration is enforced by zero resolution {double,double} loadResolution = {0.0,effResolution{1}}; // 2) I assume that the tuning duration does not depend on the tuning level // so that the normal pre_timing can be reused. {int,int,int,int,int,int,int,int,int,bool,int,int,int} pre_timing = DBS_pre_timing(band,lo_freq,loadResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_switch_on,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,int,int,int,int,int,int} tpar = DBS_telescope(naifid,onPosition,band,lo_freq,"",pre_timing,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = nodding_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},false); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,bool,int,int,int},bool,double,double} post_timing = DBS_post_timing(pre_timing,telescopetimes,n_cycles); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = DBS_telescope(naifid,onPosition,band,lo_freq,"",post_timing{1},n_cycles); // Call telescope command telescopetimes = nodding_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},false); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{3}; int n_load = post_timing{1}{6}; int n_seq = post_timing{1}{8}; int n_loadinterval = post_timing{1}{7}; bool end_load = post_timing{1}{9}; int shiftlength = post_timing{1}{10}; bool final_load = post_timing{2}; double tscan = post_timing{3}; double tdead = post_timing{4}; // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { JupiterDBS_commanding(band,lo_freq,loadResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_seq,n_load,n_loadinterval,end_load,final_load,startobs,telescopetimes,loadlength,shiftlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double} tact = DBS_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_seq,n_load,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = DBS_noisecomputer(band,lo_freq,effResolution,continuumDetection,oneGHzReference,n_cycles,tscan,tact); // Evaluate performance DBS_performance(band,lo_freq,effResolution,noisevalues,timeTaken,n_cycles,n_seq * (n_load + 1),tscan,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } //Set LOU to nominal, block //no channel selected block Set_LO_Nominal_block_ops HIFI 7626 { }{ // {double,string}[] result = ConfigurationReader("name_delays",["set_to_nominal_delay"],"0",0.0); int set_to_nominal_delay = iround(result[0]{0}); // Hifi_HIFI_HL_Normal($BBID); delay(set_to_nominal_delay); //Will be done at end of procedure during instrument mode status check //mois_tmcheck("Check that parameter HL_MODE_S is normal"); // } {string,double,double}[] procedure HifiMappingModeDBSRasterSequencerInit { string modeName = "raster"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_switch_on = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // Get the drift parameters to compute the drift noise {double,double} phaselengths = DBSPhaseLengths(band,lo_freq,effResolution,continuumDetection,oneGHzReference); // Compute derived quantities int data_time_guess = imin(imax(iceil(phaselengths{1}),datalimit),20); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } // Combine points for n_switch=1 int main_phase = iceil(phaselengths{0}); int n_pointsperscan_guess = imin(imax(main_phase / (2 * data_time_guess),1),npoints * nlines); int n_pointsperscan_range = 1 - n_pointsperscan_guess; if(n_pointsperscan_range == 0) { n_pointsperscan_range = 1; } // remaining part for n_switch int n_switch_on_guess = main_phase / (n_pointsperscan_guess * 2 * data_time_guess) + 1; int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } // Add pointing requirements condition: >=10s {int,int} new_data_time = MatchMinPointing(data_time_guess,data_time_range,2 * n_switch_on_guess); data_time_guess = new_data_time{0}; data_time_range = new_data_time{1}; // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)},{"n_pointsperscan",double(n_pointsperscan_guess),double(n_pointsperscan_range)}]; return retvalues; } // Change LO frequency but keep backend configuration - used in spectral scans // // Currently, no adaption to a full HK reading is implemented here procedure HIFIRetuneFsw { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency ion MHz double freq_throw = -40.0; // throw of frequency switch in MHz string level = "sscan_normal"; // Name of target level }{ ConfigureFPU(band,lo_freq + freq_throw / 2.0,false); HIFITuneFreqFsw(band,lo_freq,lo_freq + freq_throw,true,level); } // LCU switch-off, block block LCU_switch_off_block_ops HIFI 7631 { }{ // {double,string}[] result = ConfigurationReader("name_delays",["switch_off_delay"],"0",0.0); int switch_off_delay = iround(result[0]{0}); // //Send command: this is the effective switch-off Hifi_HIFI_Conf_nom_LCU_ch0($BBID); //Will be done at end of procedure during instrument mode status check //mois_tmcheck("Check that parameter HL_Channel_S is Off"); delay(switch_off_delay); // //Set heater to their stby value: should not depend on band HL_heater_proc_ops("1a","stby"); } //General script to clear error flags and set to nominal, block block LCU_disable_all_bands_block_fm HIFI 3767 { }{ // //switch to standby {double,string}[] result = ConfigurationReader("name_delays",["stdby_delay"],"0",0.0); int stdby_delay = iround(result[0]{0}); mois_comment("Set LOU to standby"); Hifi_HIFI_HL_Standby($BBID); delay(stdby_delay); //Disable bands mois_comment("Disable all bands"); mois_spacon("In the next TC, parameter HP443194 should be treated as FP"); Hifi_HIFI_Conf_LCU_internal($BBID,0,"RESET","RESET",256); //sets bandmask to 3FFF: all bands //LSU_delta_f: 256 = 88mV // } //Check that drain2 is below blue max and above blue min double procedure Check_BLUE_LIMIT_D2_proc_fm { string band = "4a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978.2; //LO Frequency double drain2_v = 1.4; //Current drain2 to compare to blue limits }{ //Check against blue max //Implementation of SCR-2220 double drain2_max = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); // double drain2_v_new = drain2_v; if(drain2_v > drain2_max) { drain2_v_new = drain2_max; //this already accounts for the margin message("Warning: drain2 (" + drain2_v + " V), was commanded above its blue max (" + drain2_max + " V)."); } //Check against blue min //Implementation of SCR-2220 double drain2_min = Get_BLUE_MIN_D2_proc_fm(band,lo_freq); // if(drain2_v < drain2_min) { drain2_v_new = drain2_min; message("Warning: drain2 (" + drain2_v + " V), was commanded below its blue min (" + drain2_min + " V)."); } return drain2_v_new; } // Step 2 of QLA_Testcontrol coarse magnet-tuning loop block Magnet_set_coarse_with_IVcurve_fm HIFI 3202 { string band = "1a"; }{ Start_block(); {double,string}[] result_d = ConfigurationReader("name_confilfpu",["bias_min_h","bias_max_h","bias_steps_h","bias_min_v","bias_max_v","bias_steps_v"],band,0.0); //H polar double bias_min_h = result_d[0]{0}; double bias_max_h = result_d[1]{0}; int steps_h = iround(result_d[2]{0}); //V polar double bias_min_v = result_d[3]{0}; double bias_max_v = result_d[4]{0}; int steps_v = iround(result_d[5]{0}); //Bias to set at end of IVC //Need a representative frequency: take keyfreq double[] result = CalibrationReader("name_keyfreq",["keyfreq"],band,0.0); double lo_freq = result[0]; // result_d = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v","norm_magn_h","norm_magn_v"],band,lo_freq); double bias_h = result_d[0]{0}; double bias_v = result_d[1]{0}; //Fetch magnets only if band is not band6 double magnetcurrent_h = 0.0; double magnetcurrent_v = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { magnetcurrent_h = result_d[2]{0}; magnetcurrent_v = result_d[3]{0}; } // //The IVCurve is done on the smallest range and the finest step double bias_min = max(bias_min_h,bias_min_v); double bias_max = min(bias_max_h,bias_max_v); int steps = iround(max(double(steps_h),double(steps_v))); // //Set magnet to maximum to avoid hysteresis result_d = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,0.0); double magnet_current_max_h = result_d[0]{0}; double magnet_current_max_v = result_d[1]{0}; Hifi_HIFI_CH1_MX_MG_C($BBID,magnet_current_max_h); Hifi_HIFI_CV1_MX_MG_C($BBID,magnet_current_max_v); delay(1); //Do IV curve IVcurve(band,bias_min,bias_max,steps,magnetcurrent_h,magnetcurrent_v,bias_h,bias_v); } //////////////////////////////////////// // Procedure to calculate the post timing // {int,{int,int,int,int,int,int,int,int,int,bool,int,int,int},bool,double,double} procedure DBS_post_timing { {int,int,int,int,int,int,int,int,int,bool,int,int,int} pre_timing = {4,10,4,21,11,1800,0,32,1,false,0,50,0}; // pre_timing parameter list int[] telescopetimes = [300,180,20,1,21,0]; int n_cycles = 1; // Number of half OFF-ON-ON-OFF pointing cycles }{ // Get all values from the pre_timing section int inttime = pre_timing{0}; int pointing = pre_timing{1}; int readouttime = pre_timing{2}; int loadlength = pre_timing{3}; int jitterdead = pre_timing{4}; int load_spacing = pre_timing{5}; int n_load = pre_timing{6}; int n_loadinterval = pre_timing{7}; int n_seq = pre_timing{8}; bool end_load = pre_timing{9}; int shiftlength = pre_timing{10}; int initlength = pre_timing{11}; int dangling = pre_timing{12}; // Get all values from the telescope section int telinit = telescopetimes[1]; // Initial slew time int slewtime = telescopetimes[2]; // Slew time to OFF int longslew = telescopetimes[4]; // Actual slew time for load slew int pointwaittime = telescopetimes[3]; // Idle time between two phases int tend = telescopetimes[5]; // Final deceleration time ////////////////////////////////////////////////////////////////// // Now we start the actual computations // Add pointwaittime to slew dead time in cycles slewtime = slewtime + pointwaittime; longslew = longslew + pointwaittime; // If load is performed between the cycles use pointwaittime for load if(end_load) { int halfloadlength = (loadlength - jitterdead + 1) / 2; int effhalfloadlength = (loadlength - jitterdead - pointwaittime + 1) / 2; int subtracted = halfloadlength - effhalfloadlength; pointing = pointing - subtracted; shiftlength = effhalfloadlength; } // Now we can compute the true scan time int scan_time = 2 * pointing + slewtime; // Finally I can compute the load interval n_loadinterval = imax((load_spacing + slewtime) / scan_time,1); // Compute duration of measurement and average scan length // Compute total dead time in one pointing cycle including load overhead int scan_time_long = 2 * pointing + longslew; int n_long = n_cycles / n_loadinterval; int looplength = (n_cycles - n_long) * scan_time + n_long * scan_time_long; double tscan = double(looplength) / double(n_cycles); // Get pointing dead time, instrument dead time is added later double tdead = tscan - double(2 * inttime); // Determine need for final load measurement double rest = double(n_cycles % n_loadinterval) + 0.5; bool final_load = rest > 0.5001 * double(n_loadinterval); // Compute total duration initlength = initlength - shiftlength; // The initial time is no longer contained in the total time // int totaltime=imax(initlength,telinit); int totaltime = looplength; // Add dangling load time, either of the two can apply, but // they are mutually exclusive, otherwise the readoutdelay applies if(final_load) { dangling = loadlength; } if(end_load) { dangling = loadlength - shiftlength; } int closelength = duration(HIFICloseObs()); dangling = imax(dangling + closelength - tend,0); // Compute total duration, remove pointwaittime for last slew totaltime = totaltime + dangling - pointwaittime + tend; // show gyro-propagation messages GCPMessages(pointing,2 * scan_time_long,tend); // Return all the times needed in the observing mode modules // The second tuple contains the modified pre_timing parameters, // the rest the newly computed parameters return {totaltime,{inttime,pointing,readouttime,loadlength,jitterdead,load_spacing,n_load,n_loadinterval,n_seq,end_load,shiftlength,initlength,dangling},final_load,tscan,tdead}; } ///////////////////////////////////////////////////////////////// // Spectral scan in load-chop with OFF calibration // {string,double,double}[] procedure HifiSScanProcLoadChopSequencerInit { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source double raoff = 0.0; // RA coordinate of the OFF position double decoff = 0.0; // DEC coordinate of the OFF position string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz int redundancy = 4 in [1,12]; // Frequency scan redundancy {double,double} effResolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz bool wbs1Used = true; // whether WBS1 is used bool wbs2Used = true; // whether WBS2 is used /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 2 in [1,900]; // number of half load-sky-sky-load cycles per frequency and pointing int n_switch_off = 1 in [1,900]; // number of half load-sky-sky-load cycles on OFF int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int n_cycles = 1 in [1,600]; // Number of half OFF-ON-ON-OFF cycles at one frequency int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,redundancy,wbs1Used,wbs2Used,data_time); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hr1{0},hr1{1},hr1{3}},{hr2{0},hr2{1},hr2{3}},wb1,wb2}; // Get frequency grid characteristic parameters {double,int,double} gfref = GetFReference(band,lo_freq,lo_freq_up); double reffreq = gfref{0}; int stdredun = gfref{1}; double stdstep = gfref{2}; int increment = stdredun / redundancy; // allowed group size double nocaliblen = GetFNoCalibLength(band,reffreq); int n_freq_point_guess = ifloor(nocaliblen / (stdstep * double(increment)) + 1.0); int n_freq_point_range = 1 - n_freq_point_guess; if(n_freq_point_range == 0) { n_freq_point_range = 1; } // Now general part of LoadChop modes {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // limits from noise section // spectral scans always use the full bandwidth for reference bool narrowReference = false; {double,double,double,double} phaselengths = LoadChopPhaseLengths(band,lo_freq,effResolution,narrowReference); // Compute derived quantities int data_time_guess = imin(imax(iceil(phaselengths{1}),datalimit),20); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } // How much time for single ON phase int n_switch_on_guess = imax(iceil(2.0 * phaselengths{0} / ((double(n_freq_point_guess) + sqrt(double(n_freq_point_guess))) * 2.0 * double(data_time_guess))),1); int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } // OFF phase int data_time_off_guess = imin(imax(iceil(phaselengths{2}),datalimit),20); int data_time_off_range = datalimit - data_time_off_guess; if(data_time_off_range == 0) { data_time_off_range = 1; } int n_switch_off_guess = imax(iceil(double(data_time_guess * n_switch_on_guess) * sqrt(double(n_freq_point_guess)) / (double(data_time_off_guess) * sqrt(phaselengths{3} / effResolution{1}))),1); int n_switch_off_range = 1 - n_switch_off_guess; if(n_switch_off_range == 0) { n_switch_off_range = 1; } // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"data_time_off",double(data_time_off_guess),double(data_time_off_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)},{"n_switch_off",double(n_switch_off_guess),double(n_switch_off_range)},{"n_freq_point",double(n_freq_point_guess),double(n_freq_point_range)}]; return retvalues; } //General script to clear error flags and set to nominal, block block LCU_disable_FreqTMY_check_block_fm HIFI 3667 { }{ // //Start_block(); //switch to standby Hifi_HIFI_HL_Standby($BBID); {double,string}[] result = ConfigurationReader("name_delays",["stdby_delay"],"0",0.0); int stdby_delay = iround(result[0]{0}); delay(stdby_delay); //Clear error flags Hifi_HIFI_Conf_LCU_internal($BBID,16383,"SET","RESET",256); //sets bandmask to 3FFF: all bands //LSU_delta_f: sets to 256 = 88mV //Switch back to nominal Hifi_HIFI_HL_Normal($BBID); int set_to_nominal_delay = stdby_delay; delay(set_to_nominal_delay); // } // WBS configuration with minimum attenuation, block // Laser setup as in config file block WBS_config_min_att_block_fm HIFI 3639 { string band = "1a"; // HIFI band }{ //Start_block(); //H-Polarization // {double,string}[] result_d = ConfigurationReader("name_configwbs",["hwh_laser1_s","hwh_laser2_s","hwh_heater","hwh_latchup_s"],band,0.0); string hwh_laser1_s = result_d[0]{1}; string hwh_laser2_s = result_d[1]{1}; int hwh_heater = iround(result_d[2]{0}); string hwh_latchup_s = result_d[3]{1}; int hwh_att_band4 = 0; int hwh_att_band3 = 0; int hwh_att_band2 = 0; int hwh_att_band1 = 0; int hwh_att_in = 0; // result_d = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result_d[0]{0}); //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); //delay(wbs_config_delay); //V-Polarization //Get configuration parameters // result_d = ConfigurationReader("name_configwbs",["hwv_laser1_s","hwv_laser2_s","hwv_heater","hwv_latchup_s"],band,0.0); string hwv_laser1_s = result_d[0]{1}; string hwv_laser2_s = result_d[1]{1}; int hwv_heater = iround(result_d[2]{0}); string hwv_latchup_s = result_d[3]{1}; int hwv_att_band4 = 0; int hwv_att_band3 = 0; int hwv_att_band2 = 0; int hwv_att_band1 = 0; int hwv_att_in = 0; //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // //Wait delay to allow all setting to be configured delay(wbs_config_delay); } // HRS partial configuration, block // Configures the resolution mode block HRS_config_resol_block_aot HIFI 6618 { string band = "4a"; // HIFI band string[] hrs_mode = ["wb","wb"]; //HRS resolution code }{ //////////////////////////////////////////////////////////////////// //Now Configure blocks //H-polar string hrs_filename_h = "name_confighrs_" + hrs_mode[0]; {double,string}[] result = ConfigurationReader(hrs_filename_h,["hrh_block_1","hrh_block_2","hrh_block_3","hrh_block_4","hrh_block_5","hrh_block_6","hrh_block_7","hrh_block_8"],band,0.0); string hrh_block_1 = result[0]{1}; string hrh_block_2 = result[1]{1}; string hrh_block_3 = result[2]{1}; string hrh_block_4 = result[3]{1}; string hrh_block_5 = result[4]{1}; string hrh_block_6 = result[5]{1}; string hrh_block_7 = result[6]{1}; string hrh_block_8 = result[7]{1}; // result = ConfigurationReader("name_delays",["hrs_config_delay"],band,0.0); int hrs_config_delay = iround(result[0]{0}); // Hifi_HIFI_Config_HRS_H_blocks($BBID,hrh_block_1,hrh_block_2,hrh_block_3,hrh_block_4,hrh_block_5,hrh_block_6,hrh_block_7,hrh_block_8); //delay(hrs_config_delay); // //V-polar string hrs_filename_v = "name_confighrs_" + hrs_mode[1]; result = ConfigurationReader(hrs_filename_v,["hrv_block_1","hrv_block_2","hrv_block_3","hrv_block_4","hrv_block_5","hrv_block_6","hrv_block_7","hrv_block_8"],band,0.0); string hrv_block_1 = result[0]{1}; string hrv_block_2 = result[1]{1}; string hrv_block_3 = result[2]{1}; string hrv_block_4 = result[3]{1}; string hrv_block_5 = result[4]{1}; string hrv_block_6 = result[5]{1}; string hrv_block_7 = result[6]{1}; string hrv_block_8 = result[7]{1}; // Hifi_HIFI_Config_HRS_V_blocks($BBID,hrv_block_1,hrv_block_2,hrv_block_3,hrv_block_4,hrv_block_5,hrv_block_6,hrv_block_7,hrv_block_8); // //Wait delay to allow all setting to be configured delay(hrs_config_delay); } ////////////////////////////////////////////////////////////////////////// // Procedure to compute detailed timing of peakup mode {int,int,int,int,int,double,int,int} procedure Peakup_pre_timing { int nlines_tot = 3 in [1,100]; // Number of rows in the map int npoints = 3 in [2,100]; // Number of points per row string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {bool,int,double[],bool[]} hrs1 = {false,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {false,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {false,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} }{ ////////////////////////////////////////////////////////////////////// // First check validity of frequencies CheckLOFrequencies(band,lo_freq,lo_freq); // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Fixed parameters for peak-up int data_time = 3; // Data dump period int n_chop = 1; // Number of chop cycles double eff_resolution = 1.6; // Reference resolution for load measurement int peakuptime = 3; // Time neede for peakup integration // First perform consistency checks // Check chunk size given by the data rates CheckDataTaking(backendreadoutparms,data_time); // Compute parameters for the instrument timing int jitterdead = GetMaxTimeJitter(band,lo_freq); int inttime = 2 * n_chop * data_time; // integer integration time int pointing = inttime + peakuptime + jitterdead; // Pointing time // compute load integration time int loadlength = duration(LoadMeasurement(band,lo_freq,eff_resolution,data_time,backendreadoutparms)); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); loadlength = loadlength + readoutdead; // Duration of initial set up int initlength = duration(HIFIInitObs()); initlength = initlength + duration(TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal")); initlength = initlength + duration(HifiPeakupConfigure(data_time,n_chop,true,band,lo_freq,0.0,backendreadoutparms)); // Add time for HK readout int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); initlength = initlength + hkduration; initlength = initlength + loadlength; // dangling time given by readout dead time int dangling = readoutdead; // Return all the times needed for telescope call and post_timing processing return {inttime,pointing,data_time,loadlength,n_chop,eff_resolution,initlength,dangling}; } ///////////////////////////////////////////////////////////////////// // Procedure to generate the fine pointing telescope command for the // observing mode {int,int,int,string,int,double,double,double,double,int} procedure Fine_telescope { int naifid = 0; // Tracking object ID {double,double} onposition = {0.0,0.0}; // Coordinates of the source string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {int,int,int,int,int,int,bool,int,int} timing = {16,16,21,1800,2,0,false,50,0}; // timing parameter list }{ // Assign values int on_pointing = timing{1}; // Pointing time int initlength = timing{7}; // Initial setup time int dangling = timing{8}; // Final load measurement // Create variables for telescope command string ib = GetBoresight(band,lo_freq,false); // A change of ra-dec depending on naifid may be needed double ra = onposition{0}; double dec = onposition{1}; // Check parameter compatibility with pointing command for parameters // which are no direct input parameters if(on_pointing > 50000) { IError("Pointing too long. Break up the observation into smaller pieces."); } // return parameters in required order return {initlength,0,dangling,ib,naifid,ra,dec,0.0,0.0,on_pointing}; } int block HIFI_DoubleCalibrate_hot_cold HIFI 6006 { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency int data_time = 4; // time between subsequent data readouts int n_data = 2; // Integration time counter {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // Readout parameters for HRS1,HRS2, WBS1,WBS2 bool staycal = false; // whether we should stay at the hot load at the end }{ // data rate and read-out time {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int readout = dataparms{0}; // send the configure spectroscopy command to configure the measurement // returned dead times not needed here ConfigureSpectroscopy(data_time,n_data,"hot-cold",band,lo_freq,backendreadoutparms); // Switch to first FSW register Hifi_HIFI_HL_set_FSW1($BBID); // Spectroscopy should start at first bus slot delay(1); // Perform first slow-chop HIFI_Spectr_slow_chop_proc_aot(data_time,n_data / 2,band,lo_freq,["chop_hot","chop_cold"],dataparms{1}); // Switch to second FSW register Hifi_HIFI_HL_set_FSW2($BBID); // delay required at the end int sdelay = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); // Clean up for next spectroscopy delay(sdelay); // integrate HIFI_Spectr_slow_chop_proc_aot(data_time,n_data / 2,band,lo_freq,["chop_hot","chop_cold"],dataparms{1}); if(!staycal) { // Switch to back FSW register Hifi_HIFI_HL_set_FSW1($BBID); // Move chopper back to the sky RotateChopper(band,lo_freq,"chop_M3"); } // have clean bus timing for next spectroscopy block delay(sdelay); return readout; } //!!!!!!!!!!!!!!!!!!!! // Associated blocks //!!!!!!!!!!!!!!!!!!!! // Procedure to compute the parameters needed in a Chopped HRS fast measurement block Stability_chopped_fasthrs_block HIFI 3439 { /* Integration time */ string band = "1a"; // HIFI band double lo_freq = 522.0; // LO frequency int data_time = 10; // Chop phase length int n_data = 10; // Number of phases double hrs_readout = 0.333; // HRS readout length }{ // Fixed backend configuration // No WBS int wbsh_offset1 = 0; int wbsh_width1 = 0; int wbsh_offset2 = 2048; int wbsh_width2 = 0; int wbsh_offset3 = 4096; int wbsh_width3 = 0; int wbsh_offset4 = 6144; int wbsh_width4 = 0; int wbsv_offset1 = 0; int wbsv_width1 = 0; int wbsv_offset2 = 2048; int wbsv_width2 = 0; int wbsv_offset3 = 4096; int wbsv_width3 = 0; int wbsv_offset4 = 6144; int wbsv_width4 = 0; string packing = "24_bits_format"; // HRS int hrsh_sel = 128; //10000000 = 1U only int hrsv_sel = 128; //10000000 = 1U only // No bitshift int hrs_rshift = 0; int wbs_rshift = 0; // Timing - copied from ConfigSpectroscopyParams // Command jitter time is the default delay {double,string}[] result = ConfigurationReader("name_delays",["add_jitter"],band,lo_freq); int add_jitter = iround(result[0]{0}); // WBS delta time given by switch dead time double res = GetLoadChopDeadTime(band,lo_freq); // minimum delay int del_wbs = iceil(res * 1000.0); // HRS delta time - should be zero as well int del_hrs = add_jitter; // Additional delays in the readout loops - given in OBS user manual result = ConfigurationReader("name_delays",["add_hrs","add_wbs","add_jitter","wbs_init","wbs_chunksize","tacc_add","min_wbs_acc","scos_jitter"],band,lo_freq); int add_hrs = iround(result[0]{0}); int add_wbs = iround(result[1]{0}); int wbs_init = iround(result[3]{0}) + iround(result[7]{0}); int wbs_chunksize = iround(result[4]{0}); int tacc_add = iround(result[5]{0}); int min_wbs_acc = iround(result[6]{0}); // WBS transfer time // Split total integration time int tint = data_time * n_data * 1000; // dead time has to be an integer multiple of the 10ms chunk time int tdead = del_wbs + add_wbs + add_jitter; int nchunk = (tdead - 1) / wbs_chunksize + 1; int tcorr = nchunk * wbs_chunksize - tdead; del_wbs = del_wbs + tcorr; tdead = tdead + tcorr; // Accumulation time int t_acc_wbs = (tint - wbs_init) / n_data - tdead; // discretize in 10ms chunks nchunk = (t_acc_wbs - tacc_add) / wbs_chunksize; t_acc_wbs = nchunk * wbs_chunksize + tacc_add; // No WBS addition in ICU int n_wbs_integr = 1; int n_wbs_start = n_data; // HRS int hrs_phase = iceil(1000.0 * hrs_readout); int hrs_fullphase = hrs_phase + del_hrs + add_hrs; int r_hrs = (t_acc_wbs + hrs_fullphase - add_jitter) / hrs_fullphase; int t_acc_hrs = (t_acc_wbs - add_jitter) / r_hrs - del_hrs - add_hrs; // for n_wbs_integr=1 identical to r_hrs int n_hrs_integr = 1; // Issue configuration Hifi_HIFI_config_spectroscopy($BBID,n_wbs_start,r_hrs,n_wbs_integr,n_hrs_integr,del_hrs,del_wbs,t_acc_wbs,t_acc_hrs,wbsh_offset1,wbsh_width1,wbsh_offset2,wbsh_width2,wbsh_offset3,wbsh_width3,wbsh_offset4,wbsh_width4,wbsv_offset1,wbsv_width1,wbsv_offset2,wbsv_width2,wbsv_offset3,wbsv_width3,wbsv_offset4,wbsv_width4,hrs_rshift,wbs_rshift,hrsh_sel,hrsv_sel,packing); // // Now call the spectroscopy //Get appropriate chopper voltages {bool,double,double} chopparms = GetChopVoltages(band,lo_freq,"chop_hot","chop_cold"); bool isPrime = chopparms{0}; // Call command if(isPrime) { Hifi_HIFI_P_Spectr_slow_chop($BBID,chopparms{1},chopparms{2}); } else { Hifi_HIFI_R_Spectr_slow_chop($BBID,chopparms{1},chopparms{2}); } delay(n_data * data_time + 3); } // Routines for calibration data handling ///////////////////////////////////////////////////////////////// // Routines using the generic reader // A possible frequency dependence is hidden behind the reader ///////////////////////////////////////////////////////////////// // Interpolate gain in corresponding sideband for the selected frequency double[] procedure InterpolateGssb { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency }{ double[] gssb = CalibrationReader("gain",["Gusb","Glsb"],band,lo_freq); return gssb; } ////////////////////////////////////////////////////////////////////////// // Procedure to generate the telescope command for the Peakup mode {int,int,int,string,int,double,double,bool,double,double,double,int,int,double,double,int,int,int,double,double} procedure Peakup_telescope { int naifid = 0; // Tracing object ID {double,double} mapcenter = {0.0,0.0}; // Coordinates of the center of the map double stepsize = 0.0050; // Distance between subsequent points in the raster line int nlines = 1; // Number of rows in the map; int npoints = 10; // Number of points per row string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {int,int,int,int,int,double,int,int} timing = {8,10,2,21,4,1.6,50,0}; // timing parameter list }{ // Assign values int pointing = timing{1}; int initlength = timing{6}; int dangling = timing{7}; // Create variables for telescope command string ib = GetBoresight(band,lo_freq,false); // A change of ra-dec depending on naifid may be needed double ra = mapcenter{0}; double dec = mapcenter{1}; // Map always in spacecraft coordinates, always start in +Z direction bool fixed = false; double patt = 0.0; // Map parameters double rowstep = 0.5 / 3600.0; double d1 = double(iceil(stepsize / rowstep)) * rowstep * 3600.0; // Exception for the "impossible" case of spacings below 2arcsec d1 = max(d1,2.0); // Always isotropic for peakup double d2 = d1; // Check parameter compatibility with pointing command for parameters // which are no direct input parameters if(pointing < 10) { SError("Pointing phase length too short. Increase the number of integrations."); } if(d1 > 480.0) { IError("Raster spacing too coarse. Increase the sampling."); } // parameters for OFF position - not used int koff = 0; int toff = 0; double raoff = 0.0; double decoff = 0.0; // return parameters in required order return {initlength,0,dangling,ib,naifid,ra,dec,fixed,patt,0.0,0.0,npoints,nlines,d1,d2,pointing,koff,toff,raoff,decoff}; } //TM to control FDIR on LOU temp block Set_LO_FDIR_temperatures_block_mois HIFI 3853 { }{ // BBID needs to be set manually as the main TC command has no BBID argument Hifi_HIFI_Set_OBS_ID($BBID,$OBSID); delay(1); //Fetch values to apply: band-independent so far double[] cresult = CalibrationReader("name_loheater",["tmin","tmax","nbreach"],"1a",0.0); double tmin = cresult[0]; //Min threshold double tmax = cresult[1]; //Max threshold int nbreach = iround(cresult[2]); //Number of breach // mois_spacon("In the next TC, the parameters HP460197 and HP461197 should be treated as FP"); Hifi_HIFI_LOU_T_check_on(nbreach,tmax,tmin); delay(1); // } // Configuration for continuous integration block HIFIConfigureContIntegration HIFI 6020 { int data_time = 4; // Integration time between two data readouts int n_int = 1; // Integration time counter string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // HRS1/2 {used,resolution,subbands used}, WBS1/2 {used, channel windows} }{ // Call procedure doing the work ConfigureSpectroscopy(data_time,n_int,"tp",band,lo_freq,backendreadoutparms); } //HIFI measurement of HEB spectra variation vs Imix, procedure //Takes spectra over the full Vd2 range procedure Vector_scan_BLUE_LIMIT_w_spectra_proc_COP { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency int intermediatetime = 900; //total time remaining to scan }{ //Configure Spectro in total power int[] res = [0,0]; string[] hrs_mode = ["wb1","wb1"]; int total_time = 4; string backend = "both"; res = Configure_Spectrometer_proc_fm(band,total_time,hrs_mode,backend); // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v_start = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); double drain2_safe = cresult[0]; drain2_v_start = drain2_safe; //Take lowest value from config_HEB_Imix_spec.config string tabimix = "config_HEB_Imix_spec.config"; double bandnb = GetBandCode(band); drain2_v_start = dlookup(tabimix,"" + iceil(bandnb),"vd2min"); drain2_v_start = Check_BLUE_LIMIT_D2_proc_fm(band,lo_freq,drain2_v_start); // double drain2_max = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); //Take highest value from config_HEB_Imix_spec.config drain2_max = dlookup(tabimix,"" + iceil(bandnb),"vd2max"); //Clip to blue max drain2_max = Check_BLUE_LIMIT_D2_proc_fm(band,lo_freq,drain2_max); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // //First step at max Vd2 result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lodelay = iround(result[0]{0}); int config_lo_delay = config_lodelay; // int starttime = time(); //First setting at max Vd2 double drain2_v_current = drain2_max; HIFI_Configure_LCU_proc_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_current,curlim2,macro_checksum,config_lo_delay); // //Take spectrum Spectro_total_power_block_fm(band,res,backend); int iterationtime = time() - starttime - 2; //remove 2 as further configlodelay are 2sec shorter //Clear flag in case we have entered failure mode in the first setting Set_LO_Nominal_proc_fm(); //From now on it's alea jacta est //Scan is performed from top to bottom //We compute the nb of step based on the time needed for one iteration int nbstep = intermediatetime / iterationtime; //Compute step size double step_drain2_v = -1.0 * (drain2_max - drain2_v_start) / double(nbstep - 1); // //debug_print(nbstep); //debug_print(step_drain2_v); //Increment step drain2_v_current = drain2_v_current + step_drain2_v; //If not the first setting, the configuration time should be smaller //as we don't change the frequency config_lo_delay = config_lodelay - 2; //Start loop on further settings for(int i = 1 .. nbstep - 1) { // while (drain2_v_current >= drain2_v_start) { //Configure Vd2 HIFI_Configure_LCU_proc_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_current,curlim2,macro_checksum,config_lo_delay); // //Take spectrum Spectro_total_power_block_fm(band,res,backend); //Increment step drain2_v_current = drain2_v_current + step_drain2_v; if(drain2_v_current < drain2_v_start) { drain2_v_current = drain2_v_start; } } } ////////////////////////////////////////////////////////////////////// // Procedure to perform the noise level evaluation for the observing mode {double,double,double,double,double} procedure FSwitchNoRef_noisecomputer { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF int n_cycles = 1; // Number of map coverages double tscan = 60.0; // Total average duration of one scan double tdead = 10.0; // Average dead time in one slew }{ // Call position switch noise computer {double,double,double,double,double} noisevalues = PositionSwitch_noisecomputer(band,lo_freq,eff_resolution,oneGHzReference,n_cycles,tscan,tdead); // Correct for signal in both phases double multiplier = sqrt(0.5); noisevalues{0} = noisevalues{0} * multiplier; noisevalues{1} = noisevalues{1} * multiplier; noisevalues{2} = noisevalues{2} * multiplier; noisevalues{3} = noisevalues{3} * multiplier; // Return noise values and the maximum ratio of drift to radiometric noise return {noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // Switch HIFI on, block // block HIFI_global_switch_on_block_ops HIFI 7925 { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ StartBlock_ops(); //Sequentially switches on, then notify PDU // //WBS-H mois_step("Switch ON WBS-H S/S"); PDU_switch_on_proc_ops("WBS_H"); mois_comment("Notify PDU status for WBS-H"); HIFI_notify_PDU_status_on_proc_ops("ON","OFF","OFF","ON","OFF","OFF","WBSH"); //WBS-V mois_step("Switch ON WBS-V S/S"); PDU_switch_on_proc_ops("WBS_V"); mois_comment("Notify PDU status for WBS-H"); HIFI_notify_PDU_status_on_proc_ops("ON","OFF","ON","ON","OFF","OFF","WBSV"); //HRS-H and HRS-V are first powered ON, FT#0 is done, then notify PDU mois_step("Switch ON HRS-H S/S"); PDU_switch_on_proc_ops("HRS_H"); mois_step("Switch ON HRS-V S/S"); PDU_switch_on_proc_ops("HRS_V"); //HRS FT#0 and special HK handling for this mois_step("HRS start-up"); mois_comment("House-keeping for HRS-H and HRS-V is de-selected"); Switch_HK_proc_ops("ON","ON","ON","ON","OFF","OFF"); mois_comment("Notify PDU status for HRS-H and HRS-V"); HIFI_notify_PDU_status_on_proc_ops("ON","OFF","ON","ON","OFF","ON","HRSH"); HIFI_notify_PDU_status_on_proc_ops("ON","OFF","ON","ON","ON","ON","HRSV"); HRS_functional_test_No_0_proc_ops(); mois_comment("House-keeping for HRS-H and HRS-V is selected again"); Switch_HK_proc_ops("ON","ON","ON","ON","ON","ON"); mois_comment("Initial configuration of HRS blocks and LO"); HRS_standby_proc_ops("0",["wb","wb"]); //LOU mois_step("Switch ON LO S/S"); string lo_subsys = "LO_Prime"; if(prime_or_redundant == "Red") { lo_subsys = "LO_Red"; } PDU_switch_on_proc_ops(lo_subsys); mois_comment("Notify PDU status for LCU"); HIFI_notify_PDU_status_on_proc_ops("ON","ON","ON","ON","ON","ON","LCU"); } {string,double,double}[] procedure HifiMappingModeFSwitchOTFSequencerInit { string modeName = "fs-raster"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // chunk size given by the data rates and optimum speed int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 1 in [1,1800]; // Supersamplingfactor int n_switch_off = 3 in [1,3600]; // Number of data dumps for the OFF integration time int n_linesperscan = 1 in [1,32]; // Number of lines between two OFFs int n_cycles = 1 in [1,1200]; // Number of map coverages int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode // limit on data rate {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // limits from noise section {double,double,double,double} phaselengths = FSwitchPhaseLengths(band,lo_freq,effResolution,oneGHzReference); // Compute derived quantities // Main loop int main_phase = iceil(phaselengths{0}); // How many lines could we do at most? int n_linesperscan_guess = main_phase / (2 * datalimit) + 1; n_linesperscan_guess = imax(n_linesperscan_guess * n_linesperscan_guess / npoints,1); // restrict the scan size if(nlines == 1 && n_linesperscan_guess > 1) { n_linesperscan_guess = 2; } else { n_linesperscan_guess = IMultiple(n_linesperscan_guess,nlines); n_linesperscan_guess = imin(n_linesperscan_guess,nlines); } int n_linesperscan_range = 1 - n_linesperscan_guess; if(n_linesperscan_range == 0) { n_linesperscan_range = 1; } double n_pointsperscan = double(n_linesperscan * npoints); // Compute back int int_time_guess = main_phase / iceil(sqrt(n_pointsperscan)); int data_time_guess = imin(imax(iceil(phaselengths{1}),datalimit),20); int n_switch_on_guess = imax(int_time_guess / (2 * data_time_guess),1); int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } data_time_guess = imax(imin(5,int_time_guess / (2 * n_switch_on_guess)),datalimit); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } // OFF phase int data_time_off_guess = imin(imax(iceil(phaselengths{2}),datalimit),20); int data_time_off_range = datalimit - data_time_off_guess; if(data_time_off_range == 0) { data_time_off_range = 1; } int n_switch_off_guess = imax(iceil(double(data_time_guess * n_switch_on_guess) * 0.67 * sqrt(n_pointsperscan) / (double(data_time_off_guess) * sqrt(phaselengths{3} / effResolution{1}))),1); int n_switch_off_range = 1 - n_switch_off_guess; if(n_switch_off_range == 0) { n_switch_off_range = 1; } // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"data_time_off",double(data_time_off_guess),double(data_time_off_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)},{"n_switch_off",double(n_switch_off_guess),double(n_switch_off_range)},{"n_linesperscan",double(n_linesperscan_guess),double(n_linesperscan_range)}]; return retvalues; } //HIFI-COP-2.1-Stab-IF obs HifiEng_stability_IF_system_COP { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band }{ //General parameters in use int n = 751; //Number of load pairs to be measured string mixer_polarization = "B"; //Polarization: H, V, or both (B) int integ_time = 4; string backend = "both"; string[] hrs_mode = ["wb1","wb1"]; //For bands 6 and 7, use wb8 if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { hrs_mode = ["wb8","wb8"]; } //Use high biases {double,string}[] result = ConfigurationReader("name_confilfpu",["bias_high_resistive_h"],band,0.0); // // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Proc_stability_IF_system(band,n,hrs_mode,mixer_polarization,integ_time,backend,result[0]{0})); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Proc_stability_IF_system(band,n,hrs_mode,mixer_polarization,integ_time,backend,result[0]{0}); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } //HIFI-COP-1.2-HRS_FT procedure HRS_FT_COP_proc_ops { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ mois_comment("Start of HIFI HRS Functional Test"); //General parameters in use: use band 5 string band = "5a"; double lo_freq = 1122.0; int integ_time = 4; string backend = "hrs"; string[] hrs_mode = ["wb1","wb1"]; string laser_H = "Laser2"; string laser_V = "Laser2"; // string hbb_heater = "ON"; //hot source on/off string chopper_loop = "CLOSE"; string chop_startup_prime_red = "chop_startup_cold_prime"; if(prime_or_redundant == "Red") { chop_startup_prime_red = "chop_startup_cold_red"; } {double,string}[] result = ConfigurationReader("name_chopper",[chop_startup_prime_red],"0",0.0); if(chopper_loop == "OPEN") { result = ConfigurationReader("name_chopper",["chop_startup_warm"],"0",0.0); } mois_step("Switch FPU band 5"); double chopper_voltage = result[0]{0}; Init_MSA_ops(band,chopper_loop,lo_freq,chopper_voltage,hbb_heater,prime_or_redundant); mois_tmcheck("Check that parameter HF_DH1_MXBAND and HF_DV1_MXBAND are both 5"); //Set mixer bias to 5mV mois_step("Turn on shot noise for band 5 mixers"); result = ConfigurationReader("name_confilfpu",["bias_low_resistive_h","bias_low_resistive_v"],band,0.0); double bias_low_h = result[0]{0}; double bias_low_v = result[1]{0}; //Set magnets to 0 Set_Magnet_current_block_fm(0.0,0.0); mois_tmcheck("Check that parameters HF_AH1_MXMG_C and HF_AV1_MXMG_C are both set to 0 mA"); // Mixerbias(bias_low_h,bias_low_v); mois_tmcheck("Check that parameters HF_AH1_MXBIAS_V and HF_AV1_MXBIAS_V are set to " + bias_low_h + " and " + bias_low_v + " mV respectively"); // mois_step("HRS FT#1"); HRS_functional_test_No_1_block_fm(); // mois_step("HRS to standby and tuning"); HRS_config_max_att_block_fm(band,hrs_mode); HRS_tune_block_fm(band); //To check final attenuator settings Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); Spectro_total_power_block_fm(band,[integ_time,1],backend); // mois_step("HRS FT#2 with square_s"); HRS_functional_test_No_2_Square_s_block_fm(band,hrs_mode,integ_time,backend); // mois_step("HRS FT#2 with square_m"); HRS_functional_test_No_2_Square_m_block_fm(band,hrs_mode,integ_time,backend); // mois_step("HRS FT#2 with sine"); HRS_functional_test_No_2_Sine_block_fm(band,hrs_mode,integ_time,backend); // mois_step("HRS FT#2 with correlation"); HRS_config_att_lo_block_fm(band,hrs_mode); HRS_tune_block_fm(band); HRS_functional_test_No_2_Corr_block_fm(band,hrs_mode,integ_time,backend); // mois_step("HRS FT#4"); HRS_functional_test_No_4_block_fm(band,hrs_mode,integ_time,backend); // mois_step("HRS linearity test"); HRS_linearity_indiv_block_cop(band,hrs_mode,integ_time,"hrs"); // mois_step("HRS cross-polar"); HRS_polar_switch_proc_fm(band,hrs_mode); // mois_step("HRS tuning"); HRS_tune_block_fm(band); //To check final attenuator settings Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); Spectro_total_power_block_fm(band,[integ_time,1],backend); // mois_step("Switch to FPU band 0"); Init_MSA_ops("0",chopper_loop,lo_freq,chopper_voltage,hbb_heater,prime_or_redundant); } ///////////////////////////////////////////////////////////////// // Spectral scan in frequency switch with OFF calibration // {string,double,double}[] procedure HifiSScanProcFSwitchSequencerInit { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source double raoff = 0.0; // RA coordinate of the OFF position double decoff = 0.0; // DEC coordinate of the OFF position string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz int redundancy = 4 in [1,12]; // Frequency scan redundancy double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} effResolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz bool wbs1Used = true; // whether WBS1 is used bool wbs2Used = true; // whether WBS2 is used /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles per frequency and pointing int n_switch_off = 1 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles on OFF int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int n_cycles = 1 in [1,600]; // Number of half OFF-ON-ON-OFF cycles at one frequency int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,redundancy,wbs1Used,wbs2Used,data_time); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hr1{0},hr1{1},hr1{3}},{hr2{0},hr2{1},hr2{3}},wb1,wb2}; // Get frequency grid characteristic parameters {double,int,double} gfref = GetFReference(band,lo_freq,lo_freq_up); double reffreq = gfref{0}; int stdredun = gfref{1}; double stdstep = gfref{2}; int increment = stdredun / redundancy; // allowed group size double nocaliblen = GetFNoCalibLength(band,reffreq); int n_freq_point_guess = ifloor(nocaliblen / (stdstep * double(increment)) + 1.0); int n_freq_point_range = 1 - n_freq_point_guess; if(n_freq_point_range == 0) { n_freq_point_range = 1; } // Now general part of Frequency switch modes {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // limits from noise section // spectral scans always use the full bandwidth for reference bool narrowReference = false; {double,double,double,double} phaselengths = FSwitchPhaseLengths(band,lo_freq,effResolution,narrowReference); // Compute derived quantities int data_time_guess = imin(imax(iceil(phaselengths{1}),datalimit),20); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } // How much time for single ON phase int n_switch_on_guess = imax(iceil(2.0 * phaselengths{0} / ((double(n_freq_point_guess) + sqrt(double(n_freq_point_guess))) * 2.0 * double(data_time_guess))),1); int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } // OFF phase int data_time_off_guess = imin(imax(iceil(phaselengths{2}),datalimit),20); int data_time_off_range = datalimit - data_time_off_guess; if(data_time_off_range == 0) { data_time_off_range = 1; } int n_switch_off_guess = imax(iceil(double(data_time_guess * n_switch_on_guess) * sqrt(double(n_freq_point_guess)) / (double(data_time_off_guess) * sqrt(phaselengths{3} / effResolution{1}))),1); int n_switch_off_range = 1 - n_switch_off_guess; if(n_switch_off_range == 0) { n_switch_off_range = 1; } // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"data_time_off",double(data_time_off_guess),double(data_time_off_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)},{"n_switch_off",double(n_switch_off_guess),double(n_switch_off_range)},{"n_freq_point",double(n_freq_point_guess),double(n_freq_point_range)}]; return retvalues; } {int,double,double,double,double,double} obs HifiMappingModeFastDBSCross { string modeName = "cross"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 10 in [4,80]; // data dump interval int n_int_on = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_switch_on = 1 in [1,1800]; // number of data transfer cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode OpenMessages("HIFI Mapping - DBS Cross Map fastChop",{data_time,0,n_switch_on,n_int_on,0,0,n_pointsperscan,0,n_cycles,load_interval}); // Call first part of the timing computer {int,int,int,int,int,int,int,int,int,int,int,int,int} pre_timing = FastDBSRaster_pre_timing(2,npoints,band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_switch_on,n_pointsperscan,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,bool,double,double,double,double[],double[],int[],double,double,int,int,int,int,int,int} tpar = DBSCross_telescope(naifid,onPosition,stepsize,npoints,band,lo_freq,"",pre_timing,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = custom_map_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21}); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,int},bool,double,double} post_timing = DBSCross_post_timing(pre_timing,telescopetimes,npoints,n_switch_on,n_cycles,load_interval,true); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = DBSCross_telescope(naifid,onPosition,stepsize,npoints,band,lo_freq,"",post_timing{1},n_cycles); telescopetimes = custom_map_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21}); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{3}; int n_load = post_timing{1}{6}; int n_loadinterval = post_timing{1}{7}; int n_seq = post_timing{1}{8}; int scansize = post_timing{1}{10}; int initlength = post_timing{1}{11}; int dangling = post_timing{1}{12}; bool final_load = post_timing{2}; double tscan = post_timing{3}; double tdead = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { FastDBSRaster_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_seq,n_cycles,scansize,n_loadinterval,n_load,final_load,startobs,telescopetimes,loadlength,true); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double} tact = FastDBSRaster_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_seq,n_load,scansize,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = DBS_noisecomputer(band,lo_freq,effResolution,continuumDetection,oneGHzReference,n_cycles,tscan,tact); // Evaluate performance DBSRaster_performance(band,lo_freq,effResolution,noisevalues,timeTaken,2,npoints,n_cycles,n_seq * n_int_on * imax(n_load,1),tact); // Correct for double counting of central point // The central point is returned only double multiplier = sqrt(0.5); noisevalues{0} = noisevalues{0} * multiplier; noisevalues{1} = noisevalues{1} * multiplier; noisevalues{2} = noisevalues{2} * multiplier; noisevalues{3} = noisevalues{3} * multiplier; noisevalues{4} = noisevalues{4} / multiplier; // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } //Generic procedure for slowchop using the adequate instrument side //It also converts prime voltage into redundant voltage procedure HIFI_Spectr_fast_chop_proc_fm { double chop_angle1 = 0.0; double chop_angle2 = 0.0; int n_wbs1 = 1; int n_hrs_trans = 1; }{ //Convert prime voltage into redundant voltage chop_angle1 = Check_Chopper_Prime_Redundant(chop_angle1); chop_angle2 = Check_Chopper_Prime_Redundant(chop_angle2); //check prime or redundant keyword {double,string}[] result_d = ConfigurationReader("name_chopper",["prime_or_redundant"],"0",0.0); if(result_d[0]{1} == "prime") { Hifi_HIFI_P_Spectr_fast_chop($BBID,chop_angle1,chop_angle2,n_wbs1,n_hrs_trans); } else { Hifi_HIFI_R_Spectr_fast_chop($BBID,chop_angle1,chop_angle2,n_wbs1,n_hrs_trans); } // } //HIFI-COP-X-Dip-FSW obs HifiEng_Dip_FSW_COP { string band = "3a" in ["3a","3b","4a","4b","6a","6b","7a","7b"]; // HIFI band string polarization = "H" in ["H","V"]; //The polarization on which the test is done int nb_pairs = 20; //number of FSW1-FSW2 pairs int throw_index = 1; //index of FSW throw as of stab FSW table of throws int freq_index = 1; //index of FSW throw as of stab FSW table of frequencies bool retune = true; //whether the diplexer is adjusted between frequencies or not }{ //General parameters in use string backend = "both"; string[] hrs_mode = ["wb1","wb1"]; int integ_time = 4; //For bands 6 and 7, use wb8 if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { hrs_mode = ["wb8","wb8"]; } // // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Dip_FSW_COP_proc_ops(band,throw_index,freq_index,hrs_mode,integ_time,backend,nb_pairs,polarization,retune)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Dip_FSW_COP_proc_ops(band,throw_index,freq_index,hrs_mode,integ_time,backend,nb_pairs,polarization,retune); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } //HRS Functional Test #0, block: right after switch on, BEFORE HK collection block HRS_functional_test_No_0_block_ops HIFI 7610 { }{ mois_comment("Performing HRS Functional Test #0"); //Use new command implemented in SCR-859 Hifi_HIFI_HRS_functional_test($BBID,0,"BOTH"); delay(5); // } // Take freq switch spectra, block block Spectro_freq_switch_block_fm HIFI 3612 { string band = "1a"; // HIFI band int[] timing_parms = [4,2]; //single readout time in sec. and n_wbs_start string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); //Compute data-rate int integ_time = timing_parms[0] * timing_parms[1]; double[] rates = ILT_datarate_proc_fm(band,backend,"fsw",integ_time); //Take spectrum // set data rates non_ess_hk_data_rate(rates[2] / 1024.0); data_rate(rates[0] / 1024.0); // Hifi_HIFI_Spectr_freq_switch($BBID); Apply_Slow_Chop_delay(integ_time,band,backend); // reset data rates non_ess_hk_data_rate(rates[1] / 1024.0); data_rate(0.0); } ////////////////////////////////////////////////////////////////////// // Procedure to display performance parameters of the observing mode procedure PositionSwitch_performance { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {double,double,double,double,double} noisevalues = {1.0,1.0,1.0,1.0,0.0}; // Noise values from noisecomputer int totaltime = 200; // Total observing time int n_cycles = 1; // Number of map coverages double tscan = 60.0; // Total average duration of one scan double tdead = 10.0; // Average dead time in one slew }{ double inttime = (tscan - tdead) / 2.0; // Integration time per pointing phase // Get performance of ideal instrument for comparison {int,double,double,double,double,double} idealvalues = IdealInstrument(band,lo_freq,eff_resolution,totaltime); double idealnoise = idealvalues{1} * idealvalues{1}; double obsnoise = noisevalues{0} * noisevalues{0}; double efficiency = idealnoise / obsnoise; // Compute integration time double posinttime = inttime * double(n_cycles); double timeefficiency = 2.0 * posinttime / double(totaltime); // Drift noise contribution double relnoise = noisevalues{4} / (1.0 + noisevalues{4}); // General messages PerformanceMessages(band,lo_freq,totaltime,posinttime,posinttime,timeefficiency,efficiency,relnoise,false); } //HIFI-COP-3-Deflux //Systematic deflux at beginning of each OD, or band switch procedure Deflux_COP_proc_ops { string band = "1a" in ["ALL","1a","1b","2a","2b","3a","3b","4a","4b"]; // HIFI band. ALL does all mixer bands }{ if(band != "ALL") { Deflux_SingleBand_proc_ops(band); } else { Deflux_SingleBand_proc_ops("1a"); Deflux_SingleBand_proc_ops("2a"); Deflux_SingleBand_proc_ops("3a"); Deflux_SingleBand_proc_ops("4a"); } } ///////////////////////////////////////////////////////////////// // Spectral scan in load-chop without OFF calibration // {string,double,double}[] procedure HifiSScanProcLoadChopNoRefSequencerInit { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz int redundancy = 4 in [1,12]; // Frequency scan redundancy {double,double} effResolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz bool wbs1Used = true; // whether WBS1 is used bool wbs2Used = true; // whether WBS2 is used /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_cycles = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles per frequency and pointing int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,redundancy,wbs1Used,wbs2Used,data_time); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; // Get frequency grid characteristic parameters {double,int,double} gfref = GetFReference(band,lo_freq,lo_freq_up); double reffreq = gfref{0}; int stdredun = gfref{1}; double stdstep = gfref{2}; int increment = stdredun / redundancy; // allowed group size double nocaliblen = GetFNoCalibLength(band,reffreq); int n_freq_point_guess = ifloor(nocaliblen / (stdstep * double(increment)) + 1.0); int n_freq_point_range = 1 - n_freq_point_guess; if(n_freq_point_range == 0) { n_freq_point_range = 1; } // inherit from fs-noref mode // spectral scans always use the full bandwidth for reference bool narrowReference = false; {string,double,double}[] retvalues = HifiPointProcLoadChopNoRefSequencerInit(naifid,ra,dec,band,reffreq,effResolution,narrowReference,hr1,hr2,wb1,wb2,data_time,n_cycles,load_interval,docommands); retvalues[1] = {"n_freq_point",double(n_freq_point_guess),double(n_freq_point_range)}; return retvalues; } //HIFI-COP-1.2-WBS_FT procedure WBS_FT_COP_proc_ops { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ mois_comment("Start of HIFI WBS Functional Test"); //General parameters in use string band = "0"; int integ_time = 4; string backend = "wbs"; double lo_freq = 500.0; //0. Ensure band0: no IF input power string hbb_heater = "ON"; //hot source on/off string chopper_loop = "CLOSE"; string chop_startup_prime_red = "chop_startup_cold_prime"; if(prime_or_redundant == "Red") { chop_startup_prime_red = "chop_startup_cold_red"; } {double,string}[] result = ConfigurationReader("name_chopper",[chop_startup_prime_red],"0",0.0); if(chopper_loop == "OPEN") { result = ConfigurationReader("name_chopper",["chop_startup_warm"],"0",0.0); } mois_step("FPU set to band0"); Init_MSA_ops(band,chopper_loop,lo_freq,result[0]{0},hbb_heater,prime_or_redundant); mois_tmcheck("Check that parameter HF_DH1_MXBAND and HF_DV1_MXBAND are both 0"); // string laser_H = "Lasers_off"; string laser_V = "Lasers_off"; // //1. Zero w/o laser mois_step("WBS Zero without Laser"); WBS_config_w_laser_block_fm(band,laser_H,laser_V); mois_tmcheck("Check that parameters HWH_Laser1_S, HWH_Laser2_S, HWV_Laser1_S and HWV_Laser2_S are all OFF"); WBS0_fm(band); WBS0_fm(band); //2. WBS FT //Configure WBS laser according to user inputs. laser_H = "Laser1"; laser_V = "Laser1"; mois_step("Configure WBS with Laser 1"); WBS_config_w_laser_block_fm(band,laser_H,laser_V); mois_tmcheck("Check that parameters HWH_Laser1_S and HWV_Laser1_S are ON"); //Wait 2 minutes for laser stabilization mois_comment("wait 2 minutes for stabilization"); delay(120); //Do zero mois_step("WBS Zero with Laser 1"); WBS0_fm(band); //Do zero and COMB mois_step("WBS Comb with Laser 1"); WBS_calib_fm(band); // Configure spectroscopy mois_step("Attenuator scans with Laser 1"); Configure_Spectrometer_proc_fm(band,integ_time,["wb1","wb1"],backend); //Set att. to min. and take spectrum WBS_config_min_att_w_laser_block_fm(band,laser_H,laser_V); Spectro_total_power_block_fm(band,[integ_time,1],backend); //Scan all attenuators to get attenuator steps FT_WBS_att_overall_fm(band,integ_time,laser_H,laser_V,backend); FT_WBS_att_individual_fm(band,integ_time,laser_H,laser_V,backend); //3. Linearity test mois_step("WBS linearity test with Laser 1"); FT_WBS_linearity(band,integ_time,laser_H,laser_V,backend); //4. Lacthup test mois_step("WBS latchup test with Laser 1"); WBS_set_Latchup_block_fm(band,"high",laser_H,laser_V); mois_tmcheck("Check that parameters HWH_LUP_level_S and HWV_LUP_level_S are both High"); WBS_set_Latchup_block_fm(band,"low",laser_H,laser_V); mois_tmcheck("Check that parameters HWH_LUP_level_S and HWV_LUP_level_S are both Low"); //5. Tuning mois_step("WBS tuning with Laser 1"); band = "5a"; lo_freq = 1122.0; Init_MSA_ops(band,chopper_loop,lo_freq,result[0]{0},hbb_heater,prime_or_redundant); mois_tmcheck("Check that parameter HF_DH1_MXBAND and HF_DV1_MXBAND are both 5"); WBS_tune_proc_fm(band); //To check final attenuator settings Configure_Spectrometer_proc_fm(band,integ_time,["wb1","wb1"],backend); Spectro_total_power_block_fm(band,[integ_time,1],backend); // //Repeat with laser 2 laser_H = "Laser2"; laser_V = "Laser2"; // // mois_step("FPU set to band0"); band = "0"; lo_freq = 500.0; Init_MSA_ops(band,chopper_loop,lo_freq,result[0]{0},hbb_heater,prime_or_redundant); mois_tmcheck("Check that parameter HF_DH1_MXBAND and HF_DV1_MXBAND are both 0"); //2. WBS FT //Configure WBS laser according to user inputs. mois_step("Configure WBS with Laser 2"); WBS_config_w_laser_block_fm(band,laser_H,laser_V); mois_tmcheck("Check that parameters HWH_Laser2_S and HWV_Laser2_S are ON"); //Wait 2 minutes for laser stabilization mois_comment("wait 2 minutes for stabilization"); delay(120); //Do zero mois_step("WBS Zero with Laser 2"); WBS0_fm(band); //Do zero and COMB mois_step("WBS Comb with Laser 2"); WBS_calib_fm(band); // Configure spectroscopy mois_step("Attenuator scans with Laser 2"); Configure_Spectrometer_proc_fm(band,integ_time,["wb1","wb1"],backend); //Set att. to min. and take spectrum WBS_config_min_att_w_laser_block_fm(band,laser_H,laser_V); Spectro_total_power_block_fm(band,[integ_time,1],backend); //Scan all attenuators to get attenuator steps FT_WBS_att_overall_fm(band,integ_time,laser_H,laser_V,backend); FT_WBS_att_individual_fm(band,integ_time,laser_H,laser_V,backend); //3. Linearity test mois_step("WBS linearity test with Laser 2"); FT_WBS_linearity(band,integ_time,laser_H,laser_V,backend); //4. Lacthup test mois_step("WBS latchup test with Laser 2"); WBS_set_Latchup_block_fm(band,"high",laser_H,laser_V); mois_tmcheck("Check that parameters HWH_LUP_level_S and HWV_LUP_level_S are both High"); WBS_set_Latchup_block_fm(band,"low",laser_H,laser_V); mois_tmcheck("Check that parameters HWH_LUP_level_S and HWV_LUP_level_S are both Low"); //5. Tuning mois_step("WBS tuning with Laser 2"); band = "5a"; lo_freq = 1122.0; Init_MSA_ops(band,chopper_loop,lo_freq,result[0]{0},hbb_heater,prime_or_redundant); mois_tmcheck("Check that parameter HF_DH1_MXBAND and HF_DV1_MXBAND are both 5"); WBS_tune_proc_fm(band); //To check final attenuator settings Configure_Spectrometer_proc_fm(band,integ_time,["wb1","wb1"],backend); Spectro_total_power_block_fm(band,[integ_time,1],backend); // } // Routine to compute the periodic HK parameters {string,int,double,double,double,double} procedure PeriodicHKParms { string speed = "normal" in ["fast","normal","slow"]; // Select HK rate }{ // HK rate value accoring to IFSI/OBS/MA/2005-001 int ratevalue = ifloor(dlookup("datarates",speed + "_hkrate_value","value")); // Assign // No exception handling here - CUS internals only string[] allowedvalues = ["1_pkt_per_5_s","1_pkt_per_10_s","1_pkt_per_s","1_pkt_per_3_s","1_pkt_per_4_s"]; int[] allowedperiods = [5,10,1,3,4]; string hk_string = allowedvalues[ratevalue]; int hk_period = allowedperiods[ratevalue]; // Get all relevant parameters int pmax = ifloor(dlookup("datarates","maxbuspackets","value")); int per_hkpackets = iceil(dlookup("datarates","periodic_hkpackets","value")); int per_hksize = iceil(dlookup("datarates","periodic_hksize","value")); int ess_hkpackets = iceil(dlookup("datarates","ess_hkpackets","value")); int ess_hksize = iceil(dlookup("datarates","ess_hksize","value")); int osize = ifloor(dlookup("datarates","packetoverhead","value")); // Compute rates double per_packetrate = double(per_hkpackets) / double(hk_period); double per_datarate = double(per_hkpackets * (per_hksize + osize)) / double(hk_period); double ess_packetrate = double(ess_hkpackets) / double(hk_period); double ess_datarate = double(ess_hkpackets * (ess_hksize + osize)) / double(hk_period); // return everything return {hk_string,hk_period,per_packetrate,per_datarate,ess_packetrate,ess_datarate}; } procedure SError { string errormessage = "Bad sequence parameters."; // Error message }{ string fullmessage = "Invalid sequence parameter combination:
" + errormessage + "
Rerun the sequencer to obtain a valid observing request."; error(fullmessage); } // Broadcast OBSID block BroadcastOBSID HIFI 900 { }{ //These are ILT-EGSE commands, not ruled by the 2TC/sec. //HifiIltEgse_PDU_set_OBS_ID($OBSID); //HifiIltEgse_PDU_set_BB_ID($BBID); //delay(1); //HifiIltEgse_FPU_set_OBS_ID($OBSID); //HifiIltEgse_FPU_set_BB_ID($BBID); //delay(1); //SpireIltEgse_QCC_SETOBSID($OBSID); //SpireIltEgse_QCC_SETBBID($BBID); //delay(1); Hifi_HIFI_Set_OBS_ID($BBID,$OBSID); Hifi_HIFI_non_periodic_hk_FCU(); delay(1); } // Get maximum delay needed for backend readout after SlowChopSpectroscopy int procedure SlowChopReadoutDelay { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // HRS1/2 {used,resolution,subbands used}, WBS1/2 {used, channel windows} }{ // Currently the delay applies independent from the spectrometer selection // if (backendreadoutparms{2}{0} || backendreadoutparms{3}{0}) { double[] dead = CalibrationReader("slowchopreadout",["slowchopreadout"],band,lo_freq); // } return iceil(dead[0]); } //LCU IV curves, block //The LO needs to be switched off prior to the IV curve block Measure_LCU_IV_block_fm HIFI 3663 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string multiplier = "M1" in ["M1","M2","M3"]; //Multiplier to be measured: M1, M2 or M3 }{ // //Start_block(); //Translate band name string band_new = Translate_band_name(band); string multiplier_code = multiplier + "_" + band_new; // {double,string}[] result = ConfigurationReader("name_delays",["lcu_iv_delay_m1","lcu_iv_delay_m2","lcu_iv_delay_m3"],"0",0.0); int lcu_iv_delay_m1 = iround(result[0]{0}); int lcu_iv_delay_m2 = iround(result[1]{0}); int lcu_iv_delay_m3 = iround(result[2]{0}); //For M2_6b, 7a and 7b, we need 19 sec. more if(multiplier == "M2" && (band == "6b" || band == "7a" || band == "7b")) { lcu_iv_delay_m2 = lcu_iv_delay_m2 + 19; } if(multiplier == "M3" && band == "3b") { lcu_iv_delay_m3 = lcu_iv_delay_m3 + 11; } //We will use this delay as input for the TC. //Check M3 not called for inadequate bands bool go_ahead = true; if(multiplier == "M3" && band != "2a" && band != "2b" && band != "3a" && band != "3b" && band != "6a") { go_ahead = false; } if(go_ahead) { if(multiplier == "M1") { Hifi_HIFI_measure_LCU_IV($BBID,multiplier_code,lcu_iv_delay_m1); delay(lcu_iv_delay_m1); } if(multiplier == "M2") { Hifi_HIFI_measure_LCU_IV($BBID,multiplier_code,lcu_iv_delay_m2); delay(lcu_iv_delay_m2); } if(multiplier == "M3") { Hifi_HIFI_measure_LCU_IV($BBID,multiplier_code,lcu_iv_delay_m3); delay(lcu_iv_delay_m3); } // allow for the OBS to collect data AdJ 18-apr-2008 delay(2); } // } // Procedure to compute the parameters needed in a Chopped HRS fast measurement block Stability_chopped_fasthrs_block_ops HIFI 3440 { /* Integration time */ string band = "1a"; // HIFI band double lo_freq = 522.0; // LO frequency int data_time = 10; // Chop phase length int n_data = 10; // Number of phases double hrs_readout = 0.333; // HRS readout length string chopper_pair = "load" in ["load","sky"]; //internal load or sky on-off }{ // Fixed backend configuration // No WBS int wbsh_offset1 = 0; int wbsh_width1 = 0; int wbsh_offset2 = 2048; int wbsh_width2 = 0; int wbsh_offset3 = 4096; int wbsh_width3 = 0; int wbsh_offset4 = 6144; int wbsh_width4 = 0; int wbsv_offset1 = 0; int wbsv_width1 = 0; int wbsv_offset2 = 2048; int wbsv_width2 = 0; int wbsv_offset3 = 4096; int wbsv_width3 = 0; int wbsv_offset4 = 6144; int wbsv_width4 = 0; string packing = "24_bits_format"; // HRS int hrsh_sel = 128; //10000000 = 1U only int hrsv_sel = 128; //10000000 = 1U only // No bitshift int hrs_rshift = 0; int wbs_rshift = 0; // Timing - copied from ConfigSpectroscopyParams // Command jitter time is the default delay {double,string}[] result = ConfigurationReader("name_delays",["add_jitter"],band,lo_freq); int add_jitter = iround(result[0]{0}); // WBS delta time given by switch dead time double res = GetLoadChopDeadTime(band,lo_freq); // minimum delay int del_wbs = iceil(res * 1000.0); // HRS delta time - should be zero as well int del_hrs = add_jitter; // Additional delays in the readout loops - given in OBS user manual result = ConfigurationReader("name_delays",["add_hrs","add_wbs","add_jitter","wbs_init","wbs_chunksize","tacc_add","min_wbs_acc","scos_jitter"],band,lo_freq); int add_hrs = iround(result[0]{0}); int add_wbs = iround(result[1]{0}); int wbs_init = iround(result[3]{0}) + iround(result[7]{0}); int wbs_chunksize = iround(result[4]{0}); int tacc_add = iround(result[5]{0}); int min_wbs_acc = iround(result[6]{0}); // WBS transfer time // Split total integration time int tint = data_time * n_data * 1000; // dead time has to be an integer multiple of the 10ms chunk time int tdead = del_wbs + add_wbs + add_jitter; int nchunk = (tdead - 1) / wbs_chunksize + 1; int tcorr = nchunk * wbs_chunksize - tdead; del_wbs = del_wbs + tcorr; tdead = tdead + tcorr; // Accumulation time int t_acc_wbs = (tint - wbs_init) / n_data - tdead; // discretize in 10ms chunks nchunk = (t_acc_wbs - tacc_add) / wbs_chunksize; t_acc_wbs = nchunk * wbs_chunksize + tacc_add; // No WBS addition in ICU int n_wbs_integr = 1; int n_wbs_start = n_data; // HRS int hrs_phase = iceil(1000.0 * hrs_readout); int hrs_fullphase = hrs_phase + del_hrs + add_hrs; int r_hrs = (t_acc_wbs + hrs_fullphase - add_jitter) / hrs_fullphase; int t_acc_hrs = (t_acc_wbs - add_jitter) / r_hrs - del_hrs - add_hrs; // for n_wbs_integr=1 identical to r_hrs int n_hrs_integr = 1; // Issue configuration Hifi_HIFI_config_spectroscopy($BBID,n_wbs_start,r_hrs,n_wbs_integr,n_hrs_integr,del_hrs,del_wbs,t_acc_wbs,t_acc_hrs,wbsh_offset1,wbsh_width1,wbsh_offset2,wbsh_width2,wbsh_offset3,wbsh_width3,wbsh_offset4,wbsh_width4,wbsv_offset1,wbsv_width1,wbsv_offset2,wbsv_width2,wbsv_offset3,wbsv_width3,wbsv_offset4,wbsv_width4,hrs_rshift,wbs_rshift,hrsh_sel,hrsv_sel,packing); // // Now call the spectroscopy //Get appropriate chopper voltages {bool,double,double} chopparms = GetChopVoltages(band,lo_freq,"chop_hot","chop_cold"); if(chopper_pair == "sky") { chopparms = GetChopVoltages(band,lo_freq,"chop_M3right","chop_M3left"); } bool isPrime = chopparms{0}; // Call command if(isPrime) { Hifi_HIFI_P_Spectr_slow_chop($BBID,chopparms{1},chopparms{2}); } else { Hifi_HIFI_R_Spectr_slow_chop($BBID,chopparms{1},chopparms{2}); } delay(n_data * data_time + 3); } ///////////////////////////////////////////////////////////////// // Procedure to compute the detailed frequency grid for a // spectral scan {int,double,double[],int[][],int,bool} procedure MakeFreqGrid { string band = "4a"; // HIFI band double lo_freq_low = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz int redundancy = 4; // Frequency scan redundancy double freq_throw = 0.0; // Frequency throw in case of FSW observations int grouplen = 1; // Number of frequency steps before pointing to second phase }{ // First check validity of frequencies CheckLOFrequencies(band,lo_freq_low,lo_freq_up); // Rigid check - not needed as scan will be reduced below // CheckLOFrequencies(band,lo_freq_low+min(freq_throw,0.0), // lo_freq_up+max(freq_throw,0.0)); // Get frequency grid characteristic parameters // Perform the check for the redundancy {double,int,double} gfref = GetFReference(band,lo_freq_low,lo_freq_up); double reffreq = gfref{0}; int stdredun = gfref{1}; double stdstep = gfref{2}; int increment = stdredun / redundancy; // Check that redundancy is allowed if(redundancy * increment != stdredun) { IError("The selected redundancy is no factor of " + stdredun + "!"); } // Perform check for allowed group size double nocaliblen = GetFNoCalibLength(band,reffreq); int maxgrouplen = ifloor(nocaliblen / (stdstep * double(increment)) + 1.0); if(grouplen > maxgrouplen) { SError("The group size exceeds the frequency range possible without recalibration."); } // We set up the frequency grid in four steps // Separate edges and main part of spectral scan {int,double,double} edgeampl = GetEdgeEnhance(redundancy,band); int highredun = edgeampl{0}; int inchigh = stdredun / highredun; // Check that redundancy is allowed if(highredun * inchigh != stdredun) { IError("The required redundancy at the band edges cannot be satisfied!"); } double nu1 = lo_freq_low; double nu2 = lo_freq_low + edgeampl{1}; double nu3 = lo_freq_up - edgeampl{1}; double nu4 = lo_freq_up; // Check for very small scans if(nu2 > nu4) { nu2 = nu4; } if(nu3 < nu1) { nu3 = nu1; } // Get frequency grid indices {int,int} ffindex = GetFScanBoundaries(band,freq_throw); {int,int} gfindex_lo = GetFIndex(band,nu1,nu2); {int,int} gfindex_up = GetFIndex(band,nu3,nu4); int index1 = gfindex_lo{0}; int index2 = gfindex_lo{1}; int index3 = gfindex_up{0}; int index4 = gfindex_up{1}; // Make frequency grid self-consistent and monotoneous // Shift if needed by frequency switch if(index1 < ffindex{0}) { index2 = index2 + ffindex{0} - index1; index1 = ffindex{0}; } if(index4 > ffindex{1}) { index3 = index3 + ffindex{1} - index4; index4 = ffindex{1}; } // Check again for very small scans if(index2 > index4) { index2 = index4; } if(index3 < index1) { index3 = index1; } // // lower frequency end with high redundancy int nstep1 = (index2 - index1 + inchigh - 1) / inchigh; index2 = index1 + nstep1 * inchigh; // Check again that we do not exceed the band boundary in this step if(index2 > ffindex{1}) { // No check here, we cannot exceed both boundaries index1 = index1 - index2 + ffindex{1}; index2 = ffindex{1}; } // upper end with high redundancy // Exception handling for small scans int nstep3 = imax((index4 - imax(index3,index2) + inchigh - 1) / inchigh - 1,0); index3 = index4 - nstep3 * inchigh; // main part inbetween, edges already covered int nstep2 = imax((index3 - index2 + increment - 1) / increment - 1,0); int index5 = index2 + nstep2 * increment; // Number of points int nfreq = nstep1 + nstep2 + nstep3 + 1; // Now we can construct the frequency grid from the index markers double[] freqgrid = GetFScanPoints(band,index1,index2,inchigh); // Consistency check if(nstep1 + 1 != length(freqgrid)) { CError("Frequency grid error. First frequency steps inconsistent."); } double[] addpoints = GetFScanPoints(band,index2,index5,increment); // Consistency check if(nstep2 + 1 != length(addpoints)) { CError("Frequency grid error. Main frequency steps inconsistent."); } for(int ia2 = 1 .. nstep2) { freqgrid[nstep1 + ia2] = addpoints[ia2]; } addpoints = GetFScanPoints(band,index3,index4,inchigh); // Consistency check if(nstep3 + 1 != length(addpoints)) { CError("Frequency grid error. Last frequency steps inconsistent."); } if(nstep3 > 0) { for(int ia3 = 1 .. nstep3) { freqgrid[nstep1 + nstep2 + ia3] = addpoints[ia3]; } } // Initial definition of the frequency grid finished // Check vs. system temperature and attenuators - modify if required double tsys = InterpolateTsys(band,reffreq); double[] tsysarray = GetAllTsys(band,freqgrid); // Search for frequencies with too high tsys double tsyslimit = GetTsysVariationLimit(band,reffreq); tsyslimit = tsys * tsyslimit; bool[] hightsys = []; int nadd = 0; for(int in1 = 0 .. nfreq - 1) { hightsys[in1] = tsysarray[in1] > tsyslimit; if(hightsys[in1]) { nadd = nadd + 1; } } // Add some integrations to make the total number of points an // integer multiple of the group size int groupnumber = (nfreq + nadd + grouplen - 1) / grouplen; int nrest = groupnumber * grouplen - nfreq - nadd; // add integrations at points of highest system temperature not yet covered for(int ng = 1 .. nrest) { int curmax = -1; double tsysmax = 0.0; for(int in2 = 0 .. nfreq - 1) { // dont duplicate points which are already duplicated if(!hightsys[in2]) { // search for maximum if(tsysarray[in2] > tsysmax) { curmax = in2; tsysmax = tsysarray[in2]; } } } if(curmax >= 0) { // Add point hightsys[curmax] = true; } else { // Giving up string obscure = "Perfect observation! You managed to set up the " + "observation that will explain life, the universe, and everything. " + "However, as this would drastically lower future research funding, " + "the observation is rejected. "; // Throw message IError(obscure + "Please, increase frequency interval or reduce redundancy!"); } } // Actually expand frequency grid int newindex = 0; double[] newgrid = []; for(int in3 = 0 .. nfreq - 1) { newgrid[newindex] = freqgrid[in3]; newindex = newindex + 1; if(hightsys[in3]) { newgrid[newindex] = freqgrid[in3]; newindex = newindex + 1; } } // Consistency check nfreq = nfreq + nadd + nrest; if(nfreq != length(newgrid)) { CError("Frequency grid error. Expanded frequency grid inconsistent."); } // Information about frequency grid message("Actually covered frequency range: " + newgrid[0] / 1000.0 + " - " + newgrid[nfreq - 1] / 1000.0 + "GHz.
"); // Summary message message("Total number of LO settings: " + nfreq + "
"); // Create index for frequency stepping within a group int[][] grouporder = GetFrequencyGroupSteps(grouplen); // Check for very small scans if(lo_freq_up - lo_freq_low >= edgeampl{1} + edgeampl{2}) { bool dsb = true; int nfreq_if = redundancy; } else { if(lo_freq_up - lo_freq_low >= edgeampl{2}) { dsb = false; nfreq_if = highredun; } else { dsb = false; nfreq_if = nfreq; } } // Final sanity check CheckSpectralScanRange(band,reffreq,newgrid[0],newgrid[nfreq - 1]); // Return all frequency parameters return {groupnumber,reffreq,newgrid,grouporder,nfreq_if,dsb}; } //Set LOU to nominal, procedure //Set LOU in nominal mode with no channel selected procedure Set_LO_Nominal_proc_aot { }{ {double,string}[] result = ConfigurationReader("name_delays",["set_to_nominal_delay"],"0",0.0); int set_to_nominal_delay = iround(result[0]{0}); // Hifi_HIFI_HL_Normal($BBID); delay(set_to_nominal_delay); // } // Compute minimum nod time in a nod used for loads // Used only in case of scansize > 1 int procedure GetMinLoadNod { int[] telescopetimes = [300,180,20,0,21,0,4,10,10,10]; int scansize = 2; // Number of points measured in one scan int n_cycles = 1; // Number of half OFF-ON-ON-OFF pointing cycles int n_loadinterval = 1; // Number of nods to include loads }{ // Use telescope return parameters int numpoints = telescopetimes[6]; // Scan return field int n_scans = numpoints / (2 * scansize); int n_loadnods = n_scans / n_loadinterval; int longslew = 180; // guarantee that all nods are shorter for(int i1 = 0 .. n_loadnods - 1) { int theindex = 6 + scansize + i1 * (n_loadinterval * 2 * scansize); longslew = imin(longslew,telescopetimes[theindex]); } return longslew; } // WBS attenuator tuning, procedure // Both polarizations are treated procedure WBS_tune_proc_fm { string band = "1a"; // HIFI band }{ // {double,string}[] result_d = ConfigurationReader("name_configwbs",["tune_target"],band,0.0); int tune_target = iround(result_d[0]{0}); // //Now tune attenuators. WBS_tune_block_fm(band,tune_target); // } //Set LCU4b back to standby status, procedure procedure LCU4b_standby_proc_fm { string band = "4b"; // HIFI band double lo_freq = 1100.0 in [1056.0,1113.0]; //LO frequency }{ error("This module is obsolete: use LCU_standby_proc_fm instead"); } // Step 1 of QLA_Testcontrol coarse magnet-tuning loop // Bias current at low bias block Magnet_scan_coarse_fm HIFI 3201 { string band = "1a"; }{ Start_block(); {double,string}[] result_d = ConfigurationReader("name_confilfpu",["magnet_current_min_h","magnet_current_max_h","magnet_steps_h","magnet_step_duration_h","bias_very_low_h","magnet_current_min_v","magnet_current_max_v","magnet_steps_v","magnet_step_duration_v","bias_very_low_v"],band,0.0); //H polar double magnet_min_h = result_d[0]{0}; double magnet_max_h = result_d[1]{0}; int steps_h = iround(result_d[2]{0}); double step_time_h = result_d[3]{0}; double bias_h = result_d[4]{0}; //V polar double magnet_min_v = result_d[5]{0}; double magnet_max_v = result_d[6]{0}; int steps_v = iround(result_d[7]{0}); double step_time_v = result_d[8]{0}; double bias_v = result_d[9]{0}; // double step_time = max(step_time_h,step_time_v); // Magnet_scan(band,magnet_min_h,magnet_max_h,steps_h,step_time,bias_h,magnet_min_v,magnet_max_v,steps_v,bias_v); } //HIFI Housekeeping ON, block //I set 1 fixed rate of 1 packet per sec. block HIFI_Housekeeping_on_block_fm HIFI 3656 { }{ Start_block_no_hk_request(); //Get applicable HK rate {double,string}[] result_d = ConfigurationReader("name_delays",["hk_rate"],"0",0.0); string hk_rate = result_d[0]{1}; Hifi_HIFI_Housekeeping_on(hk_rate,"ON","ON","ON","ON","ON","ON"); delay(1); } //HIFI-COP-7.1-FT: Regular FT during Commissioning for Temp. trend monitoring procedure TrendMon_FT_COP_proc_ops { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ string[] band = ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // //1. FT unpumped //General parameters in use int integ_time = 4; string backend = "both"; string[] hrs_mode = ["wb1","wb1"]; for(int i = 0 .. 6) { //For bands 6 and 7, use wb8 if(band[2 * i] == "6a" || band[2 * i] == "7a") { hrs_mode = ["wb8","wb8"]; } FT_unpumped(band[2 * i],hrs_mode,integ_time,backend); } //2. IF feeb-back in one band: band 5a double lo_freq = 1116.0; hrs_mode = ["wb1","wb1"]; integ_time = 604; IF_FBk_COP_proc_ops(band[8],lo_freq,hrs_mode,integ_time,backend); //3. IF stability in one SIS band: band 1a int n = 751; //Number of load pairs to be measured string mixer_polarization = "B"; //Polarization: H, V, or both (B) integ_time = 4; //Use high biases {double,string}[] result = ConfigurationReader("name_confilfpu",["bias_high_resistive_h"],band[0],0.0); Proc_stability_IF_system(band[0],n,hrs_mode,mixer_polarization,integ_time,backend,result[0]{0}); //Repeat for band 6a result = ConfigurationReader("name_confilfpu",["bias_high_resistive_h"],band[10],0.0); Proc_stability_IF_system(band[10],n,hrs_mode,mixer_polarization,integ_time,backend,result[0]{0}); } // Get the standard chop angle difference from calibration file double[] procedure GetSkyChopThrow { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency string throw = ""; // Identifier for chop throw, empty is standard }{ string lstring = throw + "length"; string astring = throw + "angle"; // We chop now from plusZ tu minusZ, i.e. in negative direction // The nodding has to go into the opposite direction double[] nodpatt = CalibrationReader("skychopthrow",[lstring,astring],band,lo_freq); // restrict to allowed range double patt = (nodpatt[1] + 360.0) % 360.0; return [nodpatt[0],patt]; } ////////////////////////////////////////////////////////////////////////// // Procedure to generate the telescope command inherited from DBS mode //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the observing mode procedure FastDBS_commanding { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 10 in [4,80]; // data dump interval int n_int = 20; // number chop cycles to integrate in ICU before transfer int n_seq = 1; // Number of continuous data transfer cycles int n_load = 0; // additional load measurements in one pointing phase int n_loadinterval = 10; // number of nods before a load measurement bool end_load = false; // Need for load after each pointing phase bool final_load = false; // Need for final load measurement int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,20,1,21,0]; // Timing of the observation from telescope int loadlength = 21; // Load duration int shiftlength = 10; // Shift of the loop start relative to the pointing }{ // Auxiliary variables // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Fixed timings in the fast-chop mode int load_datatime = GetStdLoadReadout(band,lo_freq); // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time int tnodslew = telescopetimes[2]; // slew dead time between points //////////////////////////////////////////////////////////////////////// // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // // Clustering is currently not implemented in MPS - switched off here int clustered = 0; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time / 2); double[] rates = dataparms{1}; int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,true); int readoutdead = FastChopReadoutDelay(band,lo_freq,backendreadoutparms); //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; int[] choppars = [2 * n_int,0]; bool runintostate = false; while(state[0] >= 0) { if(runintostate) { state = next_state_no_check(); } else { state = next_state(); } if(state[0] == 1) { // Initialization if(clustered != 1) { HIFIInitObs(); TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal"); } delay(tinitslew - (time() - startobs) - loadlength + shiftlength - hkduration); // First load measurement HIFISetHK("normal",false); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); if(shiftlength > 0) { runintostate = true; } else { runintostate = false; } } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 3) { // First nodding position choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_seq,band,lo_freq,backendreadoutparms); // Loop for load cycles for(int i1 = 1 .. n_load) { HIFIFastChopOnIntegration(data_time,n_seq,band,lo_freq,choppars,rates); // Perform load calibration delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_seq,band,lo_freq,backendreadoutparms); } // Last cycle - no load HIFIFastChopOnIntegration(data_time,n_seq,band,lo_freq,choppars,rates); // Second phase in first nod position // occurs for even cycle numbers runintostate = false; if(state[2] % 2 == 0) { if(end_load) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); runintostate = true; } } else { // A nod slew follows - active HK if not used by load measurement if(state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } } if(state[0] == 7) { // second nod position choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_seq,band,lo_freq,backendreadoutparms); // Loop for load cycles for(int i2 = 1 .. n_load) { HIFIFastChopOffIntegration(data_time,n_seq,band,lo_freq,choppars,rates); // Perform load calibration delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_seq,band,lo_freq,backendreadoutparms); } // Last cycle - no load HIFIFastChopOffIntegration(data_time,n_seq,band,lo_freq,choppars,rates); // First phase in second nod position // occurs for odd cycle numbers runintostate = false; if(state[2] % 2 == 1) { if(end_load) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); runintostate = true; } } else { // A nod slew follows - active HK if not used by load measurement if(state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } } if(state[0] == 9) { // Load nod delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); runintostate = false; } if(state[0] == 5) { delay(readoutdead); if(final_load) { // Perform final load measurement // ( Does not occur if end_load is set) LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); } runintostate = false; HIFICloseObs(); } } } // Very fast sampling stability measurement combined with int-load-chop // Uses only the HRS in wb mode procedure Stability_chopped_fasthrs_proc_ops { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 522.0; // LO frequency int phaselength = 10; // Chop phase length int nchop = 10; // Number of phases double readout = 0.333; // HRS readout length double[] hrs_subband = [5.0,5.0,5.0,5.0]; //Positions in IF of HRS sub-bands string chopper_pair = "load" in ["load","sky"]; //internal load or sky on-off string polarization = "B"; //mixer to be sampled: H, V or B. If B, they are done successively int milliSecSample = 3; // interval between samples int samplesBefore = 50; int samplesAfter = 1000; string with_lo_on = "true" in ["true","false"]; //Whether measurement with LO ON or not }{ // Clean HK treatment for controlled data rates HIFISetHK("fast",false); {string,int,double,double,double,double} hkparms = PeriodicHKParms("fast"); // HK data: stdrate=7744+864+2*272, IF packets=2*(592+272) int allhkbits = 1782; double hkrate = hkparms{3} + double(allhkbits) / readout; // Science data: 2*(2*258*24+1376+3*272) int allbits = 29152; double sciencerate = double(allbits) / readout; // set data rates ess_hk_data_rate(hkparms{5} / 1024.0); non_ess_hk_data_rate(hkrate / 1024.0); data_rate(sciencerate / 1024.0); //Configure HRS: regardless of selected bands HRS_config_resol_block_fm(band,["wb1","wb1"]); HRS_config_att_lo_w_lo_input_block_fm(band,["wb1","wb1"],hrs_subband); //Prepare chopper position for HRS attenuator tuning if(chopper_pair == "load") { Chopper_Rotation_block_fm(band,"chop_M3_ang","chop_hot_ang"); //Look at HBB } else { Chopper_Rotation_block_fm(band,"chop_hot_ang","chop_M3_ang"); //Look at sky } //measurement without LO if(with_lo_on == "false") { //Force LO swith-off LCU_switch_off_block_fm(); //FPU configuration if(chopper_pair == "load") { Init_MSA_HBB_fm(band,"CLOSE",lo_freq,"ON"); } else { Init_MSA_SKY_fm(band,"CLOSE",lo_freq,"ON"); } //For HEBs, set bias to 3mV if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { {double,string}[] result = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,lo_freq); Mixerbias_block_fm(result[0]{0},result[1]{0}); result = ConfigurationReader("name_confilfpu",["bias_dipscan_h","bias_dipscan_v"],band,lo_freq); Mixerbias_block_fm(result[0]{0},result[1]{0}); } //Fast Imix measurement: only if option load if(chopper_pair == "load") { Fast_Imix_block_fm(band,polarization,milliSecSample,samplesBefore,samplesAfter); } //Backend tuning without LO HRS_tune_block_fm(band); // Run the actual chopped fast-HRS interation Stability_chopped_fasthrs_block_ops(band,lo_freq,phaselength,nchop,readout,chopper_pair); } else { //measurement with LO //LO swith-on LCU_switchon_proc_fm(band); //Wait an extra delay of 1 min for short term stabilization delay(60); //FPU configuration if(chopper_pair == "load") { Init_MSA_HBB_fm(band,"CLOSE",lo_freq,"ON"); } else { Init_MSA_SKY_fm(band,"CLOSE",lo_freq,"ON"); } //LO tuning LO_tuning_block_fm(band,lo_freq); //Fast Imix measurement: only if option load if(chopper_pair == "load") { Fast_Imix_block_fm(band,polarization,milliSecSample,samplesBefore,samplesAfter); } //Backend tuning with LO HRS_tune_block_fm(band); // Run the actual chopped fast-HRS interation Stability_chopped_fasthrs_block_ops(band,lo_freq,phaselength,nchop,readout,chopper_pair); } // reset data rates non_ess_hk_data_rate(hkparms{3} / 1024.0); data_rate(0.0); } // IV curve, block block IVcurve_general_fm HIFI 3210 { string band = "1a"; double lo_freq = 522.0; //LO frequency double bias_min = -6.0; double bias_max = 6.0; int steps = 131; }{ //Start_block() ; //Fetch values for magnets and bias if(band == "0") { {double,string}[] result_d = ConfigurationReader("name_confilfpu",["bias_standby_h","bias_standby_v","magnet_standby_h","magnet_standby_v"],band,0.0); } else { if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v","norm_magn_h","norm_magn_v"],band,lo_freq); } else { result_d = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); } } double bias_h = result_d[0]{0}; double bias_v = result_d[1]{0}; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { double magnet_current_h = result_d[2]{0}; double magnet_current_v = result_d[3]{0}; } else { magnet_current_h = 0.0; magnet_current_v = 0.0; } // IVcurve(band,bias_min,bias_max,steps,magnet_current_h,magnet_current_v,bias_h,bias_v); } //////////////////////////////////////// // Procedure to calculate the pre timing // {int,int,int,int,int,int,int,int,int,bool,int,int,int} procedure FastDBS_pre_timing { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 10 in [4,80]; // data dump interval int n_int = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_data = 1 in [1,1800]; // number of data transfer cycles per pointing int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // First check validity of frequencies CheckLOFrequencies(band,lo_freq,lo_freq); // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Fixed timings in the fast-chop mode int load_datatime = GetStdLoadReadout(band,lo_freq); // It should be investigated wehther we can use fast-chop on loads as well // Perform consistency checks int single_data = data_time / 2; // Check chunk size given by the data rates CheckDataTaking(backendreadoutparms,single_data); // Check chopper frequency CheckFastChopFrequency(band,lo_freq,data_time,n_int,n_data); // Telescope-instrument communication jitter int jitterdead = GetMaxTimeJitter(band,lo_freq); // Compute parameters for the instrument timing int readouttime = data_time; int inttime = data_time * n_data; // compute load integration time int loadlength = duration(LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms)); int readoutdead = FastChopReadoutDelay(band,lo_freq,backendreadoutparms); loadlength = loadlength + readoutdead; // For double phases I can use the added jitterdead in both phases for load int halfloadlength = (loadlength - jitterdead + 1) / 2; // Compare load interval and nodding interval // This determines the order of the loops int load_spacing = CheckedLoadSpacing(load_interval - loadlength,8); if(load_spacing < data_time) { SError("Load period shorter than backend readout period."); } int n_load = inttime / load_spacing; if(load_spacing > 2 * inttime) { int n_seq = n_data; bool end_load = false; int pointing = inttime + jitterdead; int shiftlength = 0; } else { n_seq = n_data / (n_load + 1); if(n_seq < 1) { SError("Transfer cycle too long relative to load period."); } end_load = true; inttime = n_seq * (n_load + 1) * data_time; pointing = inttime + halfloadlength + n_load * loadlength + jitterdead; shiftlength = halfloadlength; } // Duration of initial set up // determine exact duration only in case of full commanding if(docommands) { int initlength = duration(HIFIInitObs()); initlength = initlength + duration(TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal")); // Add time for HK readout int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,true); initlength = initlength + hkduration; } else { initlength = GetRoughInitLength(band,lo_freq,false); } initlength = initlength + loadlength; // Compute the overall cycle length // First estimate of the load interval int n_loadinterval = imax(load_interval / (2 * pointing),1); // dangling time given by readout dead time int dangling = readoutdead; // Return all the times needed for telescope call and post_timing processing return {inttime,pointing,readouttime,loadlength,jitterdead,load_spacing,n_load,n_loadinterval,n_seq,end_load,shiftlength,initlength,dangling}; } ////////////////////////////////////////////////////////////////////////// // Procedure to generate the telescope command is inherited from load chop //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the observing mode procedure FSwitchNoRef_commanding { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // data dump interval limited by the data rates int n_per_on = 1; // number of half load-sky-sky-load cycles on ON int n_load_on = 0; // additional load measurements in ON pointing phase bool end_load_on = false; // Need for load after ON pointing phase int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,0]; // Timing of observation from telescope int loadlength = 50; // Load duration }{ ////////////////////////////////////////////////////////////////////// // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time //////////////////////////////////////////////////////////////////////// // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // // Clustering is currently not implemented in MPS - switched off here int clustered = 0; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] rates = dataparms{1}; int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 1) { // Initialization if(clustered != 1) { HIFIInitObs(); TuneHIFIFsw(band,lo_freq,freq_throw,hrs1,hrs2,wbs1{0},wbs2{0},"normal"); } delay(tinitslew - (time() - startobs) - loadlength - hkduration); // First load measurement HIFISetHK("normal",false); DoubleLoadMeasurement(band,lo_freq,freq_throw,eff_resolution{0},data_time,backendreadoutparms); } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 3) { // ON integration HIFIConfigureFSwitchIntegration(data_time,n_per_on,band,lo_freq,backendreadoutparms); // Loop for load cycles for(int i1 = 1 .. n_load_on) { HIFIFSwitchOnIntegration(data_time,n_per_on,band,lo_freq,rates); // Perform load calibration delay(readoutdead); DoubleLoadMeasurement(band,lo_freq,freq_throw,eff_resolution{0},data_time,backendreadoutparms); HIFIConfigureFSwitchIntegration(data_time,n_per_on,band,lo_freq,backendreadoutparms); } // Last cycle - no load HIFIFSwitchOnIntegration(data_time,n_per_on,band,lo_freq,rates); } if(state[0] == 5) { delay(readoutdead); if(end_load_on) { // Perform final load measurement DoubleLoadMeasurement(band,lo_freq,freq_throw,eff_resolution{0},data_time,backendreadoutparms); } HIFICloseObs(); } } } // get HRS efficiency double procedure GetHrsEfficiency { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency }{ double[] resol = CalibrationReader("backendresolution",["hrs_efficiency"],band,lo_freq); return resol[0]; } // Initialisation of FPU, block with both MSA in use // It is for warm context ! block Init_MSA_fm_dummy HIFI 3220 { string band = "1a"; // HIFI band string chop_loop = "CLOSE"; double lo_freq = 522.0; //LO frequency }{ Start_block(); //Get parameters {double,string}[] result_d = ConfigurationReaderWarm("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,lo_freq); int band_nb = iround(result_d[0]{0}); double diplex_H = 0.0; double diplex_V = 0.0; int diplex_h_ctrl_mode = 0; int diplex_v_ctrl_mode = 0; // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // result_d = ConfigurationReaderWarm("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,lo_freq); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // string chop_sine_s = "ON"; // string chop_loop = "CLOSE" ; result_d = ConfigurationReaderWarm("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,lo_freq); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // double calibcurrent = result_d[7]{0}; // //Get biases result_d = ConfigurationReaderWarm("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); double bias_H = result_d[0]{0}; double bias_V = result_d[1]{0}; // //Get magnets: not applicable to bands 6 and 7 double magnetcurrent_H = 0.0; double magnetcurrent_V = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReaderWarm("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); magnetcurrent_H = result_d[0]{0}; magnetcurrent_V = result_d[1]{0}; } //Diplexer is interpolated from a table for Bands 3, 4, 6L and 6H if(band_nb <= 2 || band_nb == 5) { diplex_H = 0.0; //For bands 1, 2 and 5 diplex_V = 0.0; diplex_h_ctrl_mode = 0; diplex_v_ctrl_mode = 0; } else { //Get diplexer currents result_d = ConfigurationReaderWarm("name_confilfpu",["diplex_h_ctrl_mode","diplex_v_ctrl_mode","diplexer_current_normal_h","diplexer_current_normal_v"],band,lo_freq); diplex_h_ctrl_mode = iround(result_d[0]{0}); diplex_v_ctrl_mode = iround(result_d[1]{0}); //double[] result_dip = Get_Diplexer_setting(band,lo_freq); diplex_H = result_d[2]{0}; //result_dip[0]; diplex_V = result_d[3]{0}; //result_dip[1]; } // result_d = ConfigurationReader("name_chopper",["chop_startup_warm"],band,0.0); double chopper = result_d[0]{0}; //For this configuration we won't convert prime chopper voltage into redundant voltage //Just checking we are in range. //chopper = Check_Chopper_Prime_Redundant(chopper); chopper = Check_Chopper_Range(chopper); // //Switch on upconverter, assuming chopper and mixers are also ON Hifi_HIFI_Configure_FCU_Power($BBID,"ON","ON","ON","ON","ON"); // // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result_d = ConfigurationReaderWarm("name_delays",["config_fpu_delay"],band,lo_freq); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // Hifi_HIFI_non_periodic_hk_FCU(); } // WBS stand-by, block block WBS_standby_fm HIFI 3703 { string band = "1a"; // HIFI band string laser_H = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-V laser to be set ON }{ //Start_block(); //Set zero ON Hifi_HIFI_switch_zero_WBS_H($BBID,"ON"); Hifi_HIFI_switch_zero_WBS_V($BBID,"ON"); delay(1); //Standby configuration //H-Polarization // string hwh_laser1_s = "OFF"; string hwh_laser2_s = "OFF"; if(laser_H == "Laser1") { hwh_laser1_s = "ON"; } if(laser_H == "Laser2") { hwh_laser2_s = "ON"; } int hwh_heater = 0; //000 string hwh_latchup_s = "Level1"; int hwh_att_band4 = 7; int hwh_att_band3 = 7; int hwh_att_band2 = 7; int hwh_att_band1 = 7; int hwh_att_in = 15; // //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); {double,string}[] result = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result[0]{0}); //delay(wbs_config_delay); //Wait for configuration to be applied // //V-Polarization // string hwv_laser1_s = "OFF"; string hwv_laser2_s = "OFF"; if(laser_V == "Laser1") { hwv_laser1_s = "ON"; } if(laser_V == "Laser2") { hwv_laser2_s = "ON"; } int hwv_heater = 0; //000 string hwv_latchup_s = "Level1"; int hwv_att_band4 = 7; int hwv_att_band3 = 7; int hwv_att_band2 = 7; int hwv_att_band1 = 7; int hwv_att_in = 15; // //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); delay(wbs_config_delay); //Wait for configuration to be applied // } ///////////////////////////////////////////////////////////////// // Auxiliary routine to determine the two loop phase durations for all // DBS modes {double,double} procedure DBSPhaseLengths { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF }{ // Get the drift parameters to compute the drift noise if(continuumDetection) { double[] allanparms = InterpolateTpAllan(band,lo_freq,oneGHzReference); } else { allanparms = InterpolateSpecAllan(band,lo_freq,oneGHzReference); } // rescale to frequency resolution double alpha = allanparms[1]; double binningexp = 1.0 / allanparms[2]; double allan_time_lores = allanparms[0] * pow(1.0 / effResolution{1},binningexp); // Differential Allan variance if(continuumDetection) { allanparms = InterpolateTpChopAllan(band,lo_freq,oneGHzReference); } else { allanparms = InterpolateSpecChopAllan(band,lo_freq,oneGHzReference); } // rescale to frequency resolution double dalpha = allanparms[1]; binningexp = 1.0 / allanparms[2]; double dallan_time_lores = allanparms[0] * pow(1.0 / effResolution{1},binningexp); // phase lengths double main_phase = 0.3 * dallan_time_lores; double chop_phase = 0.3 * allan_time_lores; // Constrain by load period int loadper = LoadPeriod(band,lo_freq,effResolution{0}); main_phase = min(main_phase,0.4 * double(loadper)); return {main_phase,chop_phase}; } // Get main beam size for message double procedure GetTsysVariationLimit { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency }{ double[] fwhm = CalibrationReader("tsysvariation",["tsysvariation"],band,lo_freq); return fwhm[0]; } // WBS comb, block block WBS_comb_fm HIFI 3605 { string band = "1a"; // HIFI band }{ //Start_block(); //Two options are possible: CUS sequence or automatic OBS command //Option1: CUS sequence //WBS_comb_fm_proc(band,backend); //Option2: OBS command. It takes attenuators as input as well. //We have to set attenuators to values different from max. //Initial configuration //H-Polarization // {double,string}[] result_d = ConfigurationReader("name_configwbs",["hwh_att_band4_comb","hwh_att_band3_comb","hwh_att_band2_comb","hwh_att_band1_comb","hwh_att_in_comb","hwv_att_band4_comb","hwv_att_band3_comb","hwv_att_band2_comb","hwv_att_band1_comb","hwv_att_in_comb"],band,0.0); int hwh_att_band4 = iround(result_d[0]{0}); int hwh_att_band3 = iround(result_d[1]{0}); int hwh_att_band2 = iround(result_d[2]{0}); int hwh_att_band1 = iround(result_d[3]{0}); int hwh_att_in = iround(result_d[4]{0}); int hwv_att_band4 = iround(result_d[5]{0}); int hwv_att_band3 = iround(result_d[6]{0}); int hwv_att_band2 = iround(result_d[7]{0}); int hwv_att_band1 = iround(result_d[8]{0}); int hwv_att_in = iround(result_d[9]{0}); // Hifi_HIFI_WBS_Comb($BBID,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); //Apply delay result_d = ConfigurationReader("name_delays",["wbs_comb_delay"],band,0.0); int wbs_comb_delay = iround(result_d[0]{0}); delay(wbs_comb_delay); // } //Notify PDU status ON, block //I assume all S/S are present block HIFI_notify_PDU_status_on_block_fm HIFI 3655 { string status_FCU = "ON" in ["ON","OFF"]; //Status of FCU string status_LCU = "ON" in ["ON","OFF"]; //Status of LCU string status_WBSV = "ON" in ["ON","OFF"]; //Status of WBSV string status_WBSH = "ON" in ["ON","OFF"]; //Status of WBSH string status_HRSV = "ON" in ["ON","OFF"]; //Status of HRSV string status_HRSH = "ON" in ["ON","OFF"]; //Status of HRSH }{ Start_block_no_hk_request(); Hifi_HIFI_notify_PDU_status(status_FCU,status_LCU,status_WBSV,status_WBSH,status_HRSV,status_HRSH); delay(1); } //Load new OBSW , block block Load_OBSW_block_ops HIFI 7927 { }{ mois_comment("Assign obsid number to procedure execution"); mois_spacon("In the following command, the second parameter (OBS_ID) shall be replaced by a Formal Parameter value according to the list provided by the instrument ICC."); Hifi_HIFI_Set_OBS_ID($BBID,$OBSID); // mois_step("Construct the OBSW copy"); mois_spacon("Use the OBSM to prepare the HIFI_load_PRAM TC list to build the new version of the OBSW that is to be loaded and started"); // mois_step("Upload the OBSW copy to PM-high"); mois_spacon("Use the OBSM to run the TC list previously prepared to load the new version of the OBSW. Please be aware at the copy should start from address 0x3ffff."); // mois_step("Verify integrity of copied OBSW: three checks are involved"); //Check PM memory for OBS 6.2.1: need to put offsets of starting address for PM high mois_spacon("In the following command, the three parameters will be replaced by Formal Parameters provided by the instrument ICC."); int check_start = 0x3ffff + 0x3ffff; int check_end = 0x400fe + 0x3ffff; int check_crc = 0x9598; Hifi_HIFI_check_PM_memory(check_start,check_end,check_crc); delay(3); mois_spacon("Checks that no (1,8) has been generated"); // check_start = 0x43fff + 0x3ffff; check_end = 0x454f1 + 0x3ffff; check_crc = 0xf5f7; Hifi_HIFI_check_PM_memory(check_start,check_end,check_crc); delay(3); mois_spacon("Checks that no (1,8) has been generated"); // check_start = 0x454ff + 0x3ffff; check_end = 0x5852a + 0x3ffff; check_crc = 0x9793; Hifi_HIFI_check_PM_memory(check_start,check_end,check_crc); delay(3); mois_spacon("Checks that no (1,8) has been generated"); // mois_step("Dis-activate HK polling before copying new S/W to DM-low"); HIFI_notify_PDU_status_off_proc_ops("OFF","OFF","OFF","OFF","OFF","OFF"); // mois_step("Copying uploaded OBSW to DM-low"); int hifi_OBS_destination = 0x3ffff; // OBS_destination: start of PM high int hifi_OBS_copy_length = 0x20000; // OBS_copy_length Hifi_HIFI_copy_mem_to_low(hifi_OBS_destination,hifi_OBS_copy_length); delay(1); //The new OBSW should be booted mois_tmcheck("Check that the new OBSW release numbers have been updated (HI_SW_Version, HI_SW_Revision and HI_SW_Patch)"); // mois_step("Re-activate HK polling before copying new S/W to DM-low"); HIFI_notify_PDU_status_on_proc_ops("ON","ON","ON","ON","ON","ON","ALL"); } // Perform frequency-switch integration at ON position block HIFIFSwitchOnIntegration HIFI 6038 { int data_time = 4; // Integration time between two data readouts int n_cycle = 1; // chop cycle number string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double[] rates = [120.0,1.0,2.0]; // Data rates between and during integrations }{ HIFI_Spectr_fswitch_proc_aot(data_time,n_cycle,band,lo_freq,rates); } ////////////////////////////////////////////////////////////////////// // Compatibility procedure to provide the same API as used in // the previous versions // // Returns the actual integration time and the dead time per phase {{double,double,double},{int,int}} procedure ConfigSpectroscopyFastChop { /* Integration time */ double data_chop = 0.5 in [0.1,2.0]; // Length of a single chop phase int n_int = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_data = 2; // Integration time counter /* Parameters determining the delays - used in calibration reader */ string band = "1a"; // HIFI band double lo_freq = 522000.0; // LO frequency /* Backend settings */ {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // HRS1/2 {used,resolution,subbands used}, WBS1/2 {used,channel windows} }{ // Translate data_chop into new parameter data_time (approximate) // Get auxiliary quantities {double,string}[] result = ConfigurationReader("name_delays",["add_wbs","add_jitter","wbs_readout","wbs_init","scos_jitter"],band,lo_freq); int add_wbs = iround(result[0]{0}); int add_jitter = iround(result[1]{0}); int wbs_readout = iround(result[2]{0}); int wbs_init = iround(result[3]{0}) + iround(result[4]{0}); int tdead_data = 2 * (wbs_readout + add_jitter) + add_wbs - add_jitter; int totaltime = (iceil(1000.0 * data_chop) * 2 * n_int + tdead_data) * n_data + wbs_init; totaltime = iceil(double(totaltime) / 1000.0); int data_time = (totaltime + n_data - 1) / n_data; // Check CheckFastChopFrequency(band,lo_freq,data_time,n_int,n_data); // Get timing parameters bool wbs_used = backendreadoutparms{2}{0} || backendreadoutparms{3}{0}; {int,int,int,int,int,int,int,int,int,int,int,int,int} timing = FastConfigureSpectroscopyParams(data_time,n_int,n_data,band,lo_freq,wbs_used); int n_wbs_start = timing{0}; int r_hrs = timing{1}; int n_wbs_integr = timing{2}; int n_hrs_integr = timing{3}; int del_hrs = timing{4}; int del_wbs = timing{5}; int t_acc_wbs = timing{6}; int t_acc_hrs = timing{7}; int n_wbs1 = timing{8}; int n_hrs_trans = timing{9}; int tdead_chop = timing{10}; tdead_data = timing{11}; int tint_act = timing{12}; {int,int,int,int,int[],int[],string} backendconfigure = ConfigSpectroscopyBackends(data_time,backendreadoutparms); int wbs_rshift = backendconfigure{0}; int hrs_rshift = backendconfigure{1}; int hrsh_sel = backendconfigure{2}; int hrsv_sel = backendconfigure{3}; int[] wbsh_par = backendconfigure{4}; int[] wbsv_par = backendconfigure{5}; string packing = backendconfigure{6}; // Now call the command Hifi_HIFI_config_spectroscopy($BBID,n_wbs_start,r_hrs,n_wbs_integr,n_hrs_integr,del_hrs,del_wbs,t_acc_wbs,t_acc_hrs,wbsh_par[0],wbsh_par[1],wbsh_par[2],wbsh_par[3],wbsh_par[4],wbsh_par[5],wbsh_par[6],wbsh_par[7],wbsv_par[0],wbsv_par[1],wbsv_par[2],wbsv_par[3],wbsv_par[4],wbsv_par[5],wbsv_par[6],wbsv_par[7],hrs_rshift,wbs_rshift,hrsh_sel,hrsv_sel,packing); // // Return dead times and comand parameters return {{double(tint_act) / 1000.0,double(tdead_chop) / 1000.0,double(data_time * n_data)},{n_wbs1,n_hrs_trans}}; } ////////////////////////////////////////////////////////////////////////////// // routines from ILT not used in observing modes ////////////////////////////////////////////////////////////////////////////// //Configure LCU in nominal mode at frequency of interest procedure ConfigureLOUnominal { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz }{ LCU_config_nominal_proc_aot(band,lo_freq / 1000.0); } // ======================================================= // These are the CUS by Moncef - extracted from the CUS // import done by Albrecht. // Modifications wrt Albrecht´s corrections: // - I have suppressed all the capital letters in order to // be compatible with the name in the configuration files // - Some BBID are already used by other blocks. I set // everything to 1501 upwards. // DT - 24 Sept 2004 // 29 Sept 2004: Remark: nothing is done for V polar ! // 18 July 2005: Adapted for FM - both polar treated // ======================================================== //Modes: see fm_testmodes.cus //======================================================== // BLOCKS //======================================================== // BLOCK : Functional Test No 0 (HRS Switch ON) block HRS_functional_test_No_0_block_fm HIFI 3610 { }{ //Start_block(); // //Use new command implemented in SCR-859 Hifi_HIFI_HRS_functional_test($BBID,0,"BOTH"); delay(5); // } // LCU5b configuration and tuning, procedure procedure LCU5b_config_tune_proc_fm { string band = "5b"; // HIFI band double lo_freq = 1200.0 in [1192.0,1242.0]; //LO frequency double drain_2_factor = 100.0; //Percentage factor of the targetted drain voltage }{ error("This module is obsolete: use LO_tuning_block_fm instead"); } //HIFI investigation of spurs in 1a and 4b obs HifiEng_Spur_Investigation_COP { string band = "1a" in ["1a","4b"]; // HIFI band int freq_index = 1 in [0,3]; //Frequency index: string parm = "G1" in ["G1","G2","D1","D2","M1","M2"]; //Parameter to scan: G1,G2,D1,D2,M1,M2 }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Spur_Investigation_proc_fm_COP(band,freq_index,parm)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Spur_Investigation_proc_fm_COP(band,freq_index,parm); } if(state[0] == 5) { HIFISetHK("normal",true); StopMode_block_ops(); } } } ////////////////////////////////////////////////////////////////////// // Procedure to display performance parameters of the observing mode procedure SScanChopNoRef_performance { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz int nfreq = 4; // Number of frequency points per IF bool dsb = true; // Both sidebands covered {double,double} eff_resolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz {double,double,double,double,double} noisevalues = {1.0,1.0,1.0,1.0,0.0}; // Noise values from noisecomputer int totaltime = 200; // Total observing time int n_cycles = 1; // Number of chop cycles int freqsteps = 4; // Total number of frequencies bool fs = false; // whether frequency switch used double tscan = 10.0; // Total average duration of one scan double tdead = 0.05; // Average dead time in one chop cycle }{ // Get performance of ideal instrument for comparison {int,double,double,double,double,double} idealvalues = IdealInstrument(band,lo_freq,eff_resolution,totaltime); // Use DSB noise for long spctral scans if(dsb) { double idealnoiselsb = idealvalues{1} * idealvalues{1}; double idealnoiseusb = idealvalues{3} * idealvalues{3}; double idealnoise = idealnoiselsb * idealnoiseusb / (idealnoiselsb + idealnoiseusb); } else { idealnoise = idealvalues{1} * idealvalues{1}; } double obsnoise = noisevalues{0} * noisevalues{0}; // rescale for range coverage double accumulation = double(freqsteps) / double(nfreq); idealnoise = idealnoise * accumulation; double efficiency = idealnoise / obsnoise; // Compute the actual integration time double inttime = (tscan - tdead) / 2.0; double posinttime = double(n_cycles) * 2.0 * inttime * double(freqsteps); double posofftime = 0.0; int instrumenttime = iceil(double(freqsteps) * tscan); // Check total integration time double timeefficiency = (posinttime + posofftime) / double(totaltime); // Noise contribution double relnoise = noisevalues{4} / (1.0 + noisevalues{4}); // General messages PerformanceMessages(band,lo_freq,totaltime,posinttime,posofftime,timeefficiency,efficiency,relnoise,fs); } //General LO configuration command block HIFI_Configure_LCU_ALL_block_fm HIFI 3670 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency int freq_nx = 0; // HL_freq_nx int lsu_main = 0; // HL_LSU_main int lsu_offset = 0; // HL_LSU_offset int d2_step = 1; // HL_D2_step double plevel_v = 0.0; double m1_v = 9.0; double m2_v = -2.0; double m3_v = 0.0; double gate1_v = -2.5; double gate2_v = -2.5; double drain1_v = 2.8; string curlim1_v = "1.4"; double drain2_v = 2.6; string curlim2_v = "1.4"; int macro_checksum = 0; // HL_macro_checksum int config_lo_delay = 6; }{ //Check that Vd2 is within the blue limits drain2_v = Check_BLUE_LIMIT_D2_proc_fm(band,lo_freq,drain2_v); // //Start_block(); // //Execute configuration //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Conf_nom_LCU_ch1a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "1b") { //Band 1b Hifi_HIFI_Conf_nom_LCU_ch1b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "2a") { //Band 2a Hifi_HIFI_Conf_nom_LCU_ch2a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "2b") { //Band 2b Hifi_HIFI_Conf_nom_LCU_ch2b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "3a") { //Band 3a Hifi_HIFI_Conf_nom_LCU_ch3a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "3b") { //Band 3b Hifi_HIFI_Conf_nom_LCU_ch3b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "4a") { //Band 4a Hifi_HIFI_Conf_nom_LCU_ch4a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "4b") { //Band 4b Hifi_HIFI_Conf_nom_LCU_ch4b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "5a") { //Band 5a Hifi_HIFI_Conf_nom_LCU_ch5a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "5b") { //Band 5b Hifi_HIFI_Conf_nom_LCU_ch5b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "6a") { //Band 6a Hifi_HIFI_Conf_nom_LCU_ch6a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "6b") { //Band 6b Hifi_HIFI_Conf_nom_LCU_ch6b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "7a") { //Band 7a Hifi_HIFI_Conf_nom_LCU_ch7a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "7b") { //Band 7b Hifi_HIFI_Conf_nom_LCU_ch7b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } // delay(config_lo_delay); // //Store settings into available register HIFI_HL_store_tm_only_proc_fm(); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } //HIFI-COP-7.1-FT: Regular FT during Commissioning for Temp. trend monitoring obs HifiEng_TrendMon_FT_COP { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(TrendMon_FT_COP_proc_ops(prime_or_redundant)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution TrendMon_FT_COP_proc_ops(prime_or_redundant); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } //Chopper health check: step#2 procedure Chopper_FT2_COP_proc_ops { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ //Chopper health check: needs to start in open loop double lo_freq = 0.0; double chopper_voltage = 0.0; Init_MSA_ops("0","OPEN",lo_freq,chopper_voltage,"ON",prime_or_redundant); Chopper_openloop_scan_block_ops(prime_or_redundant); // //Close the loop string chop_startup_prime_red = "chop_startup_cold_prime"; if(prime_or_redundant == "Red") { chop_startup_prime_red = "chop_startup_cold_red"; } {double,string}[] result = ConfigurationReader("name_chopper",[chop_startup_prime_red],"0",0.0); Init_MSA_ops("0","CLOSE",lo_freq,result[0]{0},"ON",prime_or_redundant); } // Frequency of load measurements // This is no longer computed, but tabulated as it does not depend // on user parameters - deltanu is a dummy parameter int procedure LoadPeriod { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency double deltanu = 1.0; // maximum effective resolution of the calibrated data }{ // Get the stability parameters double[] allanparms = CalibrationReader("loaddiff_stability",["tp_stability_time"],band,lo_freq); int period = ifloor(allanparms[0]); return period; } //HIFI-COP-2.1-DipCal1 obs HifiEng_Diplexer_calibration_vs_D2_COP { string band = "3" in ["3","4","6","7"]; // HIFI mixer band }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Diplexer_calibration_vs_D2_proc_fm(band)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Diplexer_calibration_vs_D2_proc_fm(band); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } // HRS attenuator tuning, block // Both polarizations are treated block HRS_tune_fast_block_fm HIFI 3991 { string band = "1a"; // HIFI band int hrstunedelay = 2; //delay used to perform the HRS tuning }{ //Start_block(); //First //de-select HRS HK Hifi_HIFI_Housekeeping_on("1_pkt_per_s","ON","ON","ON","ON","OFF","OFF"); //Now tune attenuators: it sets the HRS to ultra_wide Hifi_HIFI_Tune_HRS($BBID); delay(hrstunedelay); // //Switch on HRS HK polling back Hifi_HIFI_Housekeeping_on("1_pkt_per_s","ON","ON","ON","ON","ON","ON"); } //Force boot, block block HIFI_force_boot_block_ops HIFI 7600 { int partition_ID = 0; //0 if forceboot_default. Partition ID in case it should be used. }{ if(partition_ID == 0) { mois_comment("ICU booted using default partition."); Hifi_HIFI_force_bootdefault(); } else { mois_comment("ICU booted using partition # " + partition_ID); Hifi_HIFI_force_bootpartition(partition_ID); } mois_tmcheck("Verify HIFI HK telemetry packets (3,25,1025) - HIFI_PERIODIC_HK - are arriving every 4 seconds."); //mois_tmcheck("Verify that no (5,4) telemetry packet has been received from HIFI."); //Increase delay - SPR-1354 delay(5); //This is not standard practice but here we can only start //to stamp HKs with obsid/bbid pair after ICU is up and running //StartBlock_ops(); //removed for moc_cus_1.3 because the next block asks for this already } //Retune HIFI for frequency switch - keep magnet and backends procedure HIFITuneFreqNoretuneFsw { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq_1 = 978200.0; //LO frequency for FSW1 phase double lo_freq_2 = 978300.0; //LO frequency for FSW2 phase }{ // Setting with no retune for first frequency, and store in FSW1 register LCU_config_nominal_noretune_block_aot(band,lo_freq_1 / 1000.0,true); // // Second frequency setup, and stored in FSW2 register LCU_config_nominal_noretune_block_aot(band,lo_freq_2 / 1000.0,true); // } //Startblock procedure Start_block_no_hk_request { }{ //These are ILT-EGSE commands, not ruled by the 2TC/sec. //HifiIltEgse_FPU_set_BB_ID($BBID); //HifiIltEgse_PDU_set_BB_ID($BBID); //SpireIltEgse_QCC_SETBBID($BBID); //delay(1); Hifi_HIFI_Set_OBS_ID($BBID,$OBSID); //Hifi_HIFI_non_periodic_hk_FCU(); delay(1); } //HIFI LO tuning only for M1 and M2 investigation in 7b, block //Target current is read from look-up table block LCU_config_w_paramscan_block_fm HIFI 3018 { string band = "1a" in ["1a","4b"]; // HIFI band double lo_freq = 551.0; //LO frequency string parm = "G1" in ["G1","G2","D1","D2","M1","M2"]; //Parameter to scan: G1,G2,D1,D2,M1,M2 double param_value = -6.0; //Value of parameter to set }{ //Clear potential failure mode Set_LO_Nominal_proc_fm(); // {double,string}[] result = ConfigurationReader("name_confpolar4lotune",[band],band,lo_freq); string mixer_polarization = result[0]{1}; //Get target mixer current result = ConfigurationReader("name_confilmix",["target_mx_c_h","target_mx_c_v"],band,lo_freq); double target_current = result[0]{0}; if(mixer_polarization == "V") { target_current = result[1]{0}; } if(mixer_polarization == "B") { target_current = 0.5 * (result[1]{0} + result[0]{0}); } // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; name_configlcutune = "name_configlcutune_b"; } // result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; // result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lo_freq); double drain2_v = result[0]{0}; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // //Update parameter to scan if(parm == "G1") { gate1_v = param_value; } if(parm == "G2") { gate1_v = param_value; } if(parm == "D1") { drain1_v = param_value; } if(parm == "D2") { drain2_v = param_value; } if(parm == "M1") { m1_v = param_value; } if(parm == "M2") { m2_v = param_value; } // //If something else than Vd2 is scanned, a proper tuning is needed if(parm != "D2") { result = ConfigurationReader(name_configlotune,["step_drain2_v","nsteps","step_time"],band,lo_freq); double step_drain2_v = result[0]{0}; int nsteps = iround(result[1]{0}); double step_time = result[2]{0}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); double tune_range = 0.1; result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lo_freq); double middle_d2 = result[0]{0}; double drain2_v_start = min(middle_d2 * (1.0 + tune_range / 2.0),drain2_bluemax); double drain2_v_end = (1.0 - tune_range / 2.0) / (1.0 + tune_range / 2.0) * drain2_v_start; step_drain2_v = (drain2_v_end - drain2_v_start) / double(nsteps - 1); drain2_v = drain2_v_start; // } result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); //Send command if(band == "1a") { Hifi_HIFI_Conf_nom_LCU_ch1a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v,curlim2,macro_checksum); //Command delay delay(config_lo_delay); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } if(band == "4b") { Hifi_HIFI_Conf_nom_LCU_ch4b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v,curlim2,macro_checksum); //Command delay delay(config_lo_delay); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } //If Vd2 not scanned, do the vector scan if(parm != "D2") { if(band == "1a") { //Band 1a Hifi_HIFI_Load_vector_nom_1a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "4b") { //Band 4b Hifi_HIFI_Load_vector_nom_4b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } // delay(1); // //Execute tuning: check which mixer is to be used if(mixer_polarization == "V") { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCV($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCV($BBID,target_current); } } else { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCH($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCH($BBID,target_current); } } // double time_needed = double(nsteps) * step_time; delay(iround(time_needed + 2.0 + 0.5)); //0.5s added for completion of load_vector // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } } // LCU switch-off, procedure procedure LCU_switch_off_proc_fm { }{ // //Automatic failure mode clearance. //Should take <0.5s so time included in the switch-off delay Hifi_HIFI_HL_Normal($BBID); // {double,string}[] result = ConfigurationReader("name_delays",["switch_off_delay"],"0",0.0); int switch_off_delay = iround(result[0]{0}); // //Send command: this is the effective switch-off Hifi_HIFI_Conf_nom_LCU_ch0($BBID); // delay(switch_off_delay); // //Set heater to their stby value: should not depend on band HL_heater_proc_fm("1a","stby"); } //Chopper health check test#2 during open loop, mode mode HifiManCmd_Chopper_openloop_scan_health_check { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ mois_tmcheck("The instrument can be in Standby I, Standby II or Primary mode in open loop context for this test"); //It is done after chopper has been switched on in open loop mois_spacon("Check that procedure HIFI_Chopper_openloop_set_health_check has been performed previously and analysed as PASS"); if(prime_or_redundant == "Prime") { mois_tmcheck("The instrument must have been switched on with the PRIME side"); } else { mois_tmcheck("The instrument must have been switched on with the REDUNDANT side"); } mois_tmcheck("Check that parameter HF_DPR_CHLOOP_S is set to OPEN"); mois_tmcheck("Check that parameter HF_DPR_CHSINE_S is set to ON"); // mois_comment("Performing part two of HIFI internal chopper health check"); StartMode_block_ops(); // mois_step("Perform chopper scan in open loop"); Chopper_openloop_scan_block_ops(prime_or_redundant); // StopMode_block_ops(); mois_spacon("Write down the OBS_ID corresponding to this mode and communicate it to the HIFI ICC"); } // messages giving gyro-calibration information procedure GCPMessages { int gcp_time = 15; // pointing time at GCP int gcp_period = 500; // period for visiting the GCP int tend = 0; // final decelleration time as indication for planet }{ // Constants hard coded int tend_fixed = 0; int critical = 0; int min_gcp_time = 15; int max_gcp_period = 2000; // close any previous messages message("

"); message("

Gyro-calibration

"); message("

"); // Actual messages if(gcp_time > critical) { if(tend > tend_fixed) { message("A-posteriori pointing improvement is not possible for " + "solar system objects."); } else { if(gcp_time >= min_gcp_time && gcp_period <= max_gcp_period) { message("A-posteriori relative pointing improvement can be obtained " + "from a gyro-calibration taking " + gcp_time + "s every " + gcp_period + "s."); } else { message("The AOR is not optimized for gyro-calibration."); message("It is not clear whether any a-posteriori relative " + "pointing improvement can be obtained from a " + "gyro-calibration taking " + gcp_time + "s every " + gcp_period + "s."); } } } else { message("No a-posteriori pointing improvement possible for this AOR."); } } // HRS partial configuration with choice of central freq for hr sub-band, block // Configures the LO and attenuators block FSW_Response_time_HRSConfig_block_fm HIFI 3689 { string band = "1a"; // HIFI band string[] hrs_mode = ["hr","hr"]; //HRS resolution code double hr_central_freq = 5.0; //IF freq of HRS hr sub-band in GHz }{ //Start_block(); // Fetch HRS configuration parameters //=================================== //H-polar string hrs_filename_h = "name_confighrs_" + hrs_mode[0]; {double,string}[] result = ConfigurationReader(hrs_filename_h,["hrh_switch","hrh_1u_att","hrh_1l_att","hrh_2u_att","hrh_2l_att","hrh_3u_att","hrh_3l_att","hrh_4u_att","hrh_4l_att","hrh_up_ol1","hrh_up_ol2","hrh_up_ol3","hrh_up_ol4","hrh_down_ol5","hrh_down_ol6","hrh_down_ol7"],band,0.0); string hrs_polarization_h = result[0]{1}; double hrsH_ATT_U1 = result[1]{0}; double hrsH_ATT_L1 = result[2]{0}; double hrsH_ATT_U2 = result[3]{0}; double hrsH_ATT_L2 = result[4]{0}; double hrsH_ATT_U3 = result[5]{0}; double hrsH_ATT_L3 = result[6]{0}; double hrsH_ATT_U4 = result[7]{0}; double hrsH_ATT_L4 = result[8]{0}; double[] hrsH_LO = [hr_central_freq,result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; //V-polar string hrs_filename_v = "name_confighrs_" + hrs_mode[1]; result = ConfigurationReader(hrs_filename_v,["hrv_switch","hrv_1u_att","hrv_1l_att","hrv_2u_att","hrv_2l_att","hrv_3u_att","hrv_3l_att","hrv_4u_att","hrv_4l_att","hrv_up_ol1","hrv_up_ol2","hrv_up_ol3","hrv_up_ol4","hrv_down_ol5","hrv_down_ol6","hrv_down_ol7"],band,0.0); string hrs_polarization_v = result[0]{1}; double hrsV_ATT_U1 = result[1]{0}; double hrsV_ATT_L1 = result[2]{0}; double hrsV_ATT_U2 = result[3]{0}; double hrsV_ATT_L2 = result[4]{0}; double hrsV_ATT_U3 = result[5]{0}; double hrsV_ATT_L3 = result[6]{0}; double hrsV_ATT_U4 = result[7]{0}; double hrsV_ATT_L4 = result[8]{0}; double[] hrsV_LO = [hr_central_freq,result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; // result = ConfigurationReader("name_delays",["hrs_config_delay"],band,0.0); int hrs_config_delay = iround(result[0]{0}); //Convert IF frequencies into A and M parameters //Truncate wb or hr keyword: string[] output_hrs_mode = GetHrsMode_proc_fm(hrs_mode); string hrs_mode_h = output_hrs_mode[0]; string hrs_mode_v = output_hrs_mode[1]; // int[] a_m_parameter = ComputeA_M_parameters([hrs_mode_h,hrs_mode_v],hrsH_LO[0],hrsH_LO[1],hrsH_LO[2],hrsH_LO[3],hrsH_LO[4],hrsH_LO[5],hrsH_LO[6],hrsV_LO[0],hrsV_LO[1],hrsV_LO[2],hrsV_LO[3],hrsV_LO[4],hrsV_LO[5],hrsV_LO[6]); //H-polar int hrsH_LO1_M = a_m_parameter[1]; int hrsH_LO1_A = a_m_parameter[0]; int hrsH_LO2_M = a_m_parameter[3]; int hrsH_LO2_A = a_m_parameter[2]; int hrsH_LO3_M = a_m_parameter[5]; int hrsH_LO3_A = a_m_parameter[4]; int hrsH_LO4_M = a_m_parameter[7]; int hrsH_LO4_A = a_m_parameter[6]; int hrsH_LO5_M = a_m_parameter[9]; int hrsH_LO5_A = a_m_parameter[8]; int hrsH_LO6_M = a_m_parameter[11]; int hrsH_LO6_A = a_m_parameter[10]; int hrsH_LO7_M = a_m_parameter[12]; Hifi_HIFI_Config_HRS_H_att_lo($BBID,hrs_polarization_h,hrsH_ATT_U1,hrsH_ATT_L1,hrsH_ATT_U2,hrsH_ATT_L2,hrsH_ATT_U3,hrsH_ATT_L3,hrsH_ATT_U4,hrsH_ATT_L4,hrsH_LO1_M,hrsH_LO1_A,hrsH_LO2_M,hrsH_LO2_A,hrsH_LO3_M,hrsH_LO3_A,hrsH_LO4_M,hrsH_LO4_A,hrsH_LO5_M,hrsH_LO5_A,hrsH_LO6_M,hrsH_LO6_A,hrsH_LO7_M); // //delay(hrs_config_delay); //V-polar int hrsV_LO1_M = a_m_parameter[14]; int hrsV_LO1_A = a_m_parameter[13]; int hrsV_LO2_M = a_m_parameter[16]; int hrsV_LO2_A = a_m_parameter[15]; int hrsV_LO3_M = a_m_parameter[18]; int hrsV_LO3_A = a_m_parameter[17]; int hrsV_LO4_M = a_m_parameter[20]; int hrsV_LO4_A = a_m_parameter[19]; int hrsV_LO5_M = a_m_parameter[22]; int hrsV_LO5_A = a_m_parameter[21]; int hrsV_LO6_M = a_m_parameter[24]; int hrsV_LO6_A = a_m_parameter[23]; int hrsV_LO7_M = a_m_parameter[25]; Hifi_HIFI_Config_HRS_V_att_lo($BBID,hrs_polarization_v,hrsV_ATT_U1,hrsV_ATT_L1,hrsV_ATT_U2,hrsV_ATT_L2,hrsV_ATT_U3,hrsV_ATT_L3,hrsV_ATT_U4,hrsV_ATT_L4,hrsV_LO1_M,hrsV_LO1_A,hrsV_LO2_M,hrsV_LO2_A,hrsV_LO3_M,hrsV_LO3_A,hrsV_LO4_M,hrsV_LO4_A,hrsV_LO5_M,hrsV_LO5_A,hrsV_LO6_M,hrsV_LO6_A,hrsV_LO7_M); // delay(hrs_config_delay); } // FPU Standby with chopper switched on. HBB is also ON per default, procedure procedure Band0_chopper_on_proc_fm { string band = "0"; // HIFI band string chop_loop = "CLOSE"; // Chopper Loop status }{ //Start_block(); //Get parameters {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,0.0); int band_nb = iround(result_d[0]{0}); // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,0.0); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // string chop_sine_s = "ON"; // string chop_loop = "CLOSE" ; result_d = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current_on"],band,0.0); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // double calibcurrent = result_d[7]{0}; // result_d = ConfigurationReader("name_confilfpu",["bias_standby_h","diplexer_standby_h","bias_standby_v","diplexer_standby_v","diplex_h_ctrl_mode","diplex_v_ctrl_mode","chop_cold"],band,0.0); // double bias_H = result_d[0]{0}; double diplex_H = result_d[1]{0}; double bias_V = result_d[2]{0}; double diplex_V = result_d[3]{0}; int diplex_h_ctrl_mode = iround(result_d[4]{0}); int diplex_v_ctrl_mode = iround(result_d[5]{0}); // //Retrieve magnets Magnet are so far at maximum value. Now set to nominal double magnetcurrent_H = result_d[1]{0}; double magnetcurrent_V = result_d[4]{0}; // if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilfpu",["magnet_standby_h","magnet_standby_v"],band,0.0); magnetcurrent_H = result_d[0]{0}; magnetcurrent_V = result_d[1]{0}; } // result_d = ConfigurationReader("name_chopper",["chop_startup_cold"],band,0.0); double chopper = result_d[0]{0}; //For this configuration we won't convert prime chopper voltage into redundant voltage //Just checking we are in range. //chopper = Check_Chopper_Prime_Redundant(chopper); chopper = Check_Chopper_Range(chopper); // //Switch on upconverter, assuming chopper and mixers are also ON Hifi_HIFI_Configure_FCU_Power($BBID,"ON","ON","ON","ON","ON"); // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result_d = ConfigurationReader("name_delays",["config_fpu_delay"],band,0.0); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // } ////////////////////////////////////////////////////////////////// // HRS complete configuration with maximum attenuation, procedure // Both polarizations are treated procedure HRS_standby_proc_ops { string band = "0"; // HIFI band string[] hrs_mode = ["wb","wb"]; //HRS resolution code }{ // Fetch HRS configuration parameters //=================================== //H-polar string hrs_filename_h = "name_confighrs_" + hrs_mode[0]; {double,string}[] result = ConfigurationReader(hrs_filename_h,["hrh_switch","hrh_1u_att","hrh_1l_att","hrh_2u_att","hrh_2l_att","hrh_3u_att","hrh_3l_att","hrh_4u_att","hrh_4l_att","hrh_up_ol1","hrh_up_ol2","hrh_up_ol3","hrh_up_ol4","hrh_down_ol5","hrh_down_ol6","hrh_down_ol7"],band,0.0); string hrs_polarization_h = result[0]{1}; double[] hrsH_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; //V-polar string hrs_filename_v = "name_confighrs_" + hrs_mode[1]; result = ConfigurationReader(hrs_filename_v,["hrv_switch","hrv_1u_att","hrv_1l_att","hrv_2u_att","hrv_2l_att","hrv_3u_att","hrv_3l_att","hrv_4u_att","hrv_4l_att","hrv_up_ol1","hrv_up_ol2","hrv_up_ol3","hrv_up_ol4","hrv_down_ol5","hrv_down_ol6","hrv_down_ol7"],band,0.0); string hrs_polarization_v = result[0]{1}; double[] hrsV_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; // result = ConfigurationReader("name_delays",["hrs_config_delay"],band,0.0); int hrs_config_delay = iround(result[0]{0}); // //Convert IF frequencies into A and M parameters //Truncate wb or hr keyword: string[] output_hrs_mode = GetHrsMode_proc_ops(hrs_mode); string hrs_mode_h = output_hrs_mode[0]; string hrs_mode_v = output_hrs_mode[1]; // int[] a_m_parameter = ComputeA_M_parameters([hrs_mode_h,hrs_mode_v],hrsH_LO[0],hrsH_LO[1],hrsH_LO[2],hrsH_LO[3],hrsH_LO[4],hrsH_LO[5],hrsH_LO[6],hrsV_LO[0],hrsV_LO[1],hrsV_LO[2],hrsV_LO[3],hrsV_LO[4],hrsV_LO[5],hrsV_LO[6]); //H-polar int hrh_up_ol1_m = a_m_parameter[1]; int hrh_up_ol1_a = a_m_parameter[0]; int hrh_up_ol2_m = a_m_parameter[3]; int hrh_up_ol2_a = a_m_parameter[2]; int hrh_up_ol3_m = a_m_parameter[5]; int hrh_up_ol3_a = a_m_parameter[4]; int hrh_up_ol4_m = a_m_parameter[7]; int hrh_up_ol4_a = a_m_parameter[6]; int hrh_down_ol5_m = a_m_parameter[9]; int hrh_down_ol5_a = a_m_parameter[8]; int hrh_down_ol6_m = a_m_parameter[11]; int hrh_down_ol6_a = a_m_parameter[10]; int hrh_down_ol7_m = a_m_parameter[12]; //V-polar int hrv_up_ol1_m = a_m_parameter[14]; int hrv_up_ol1_a = a_m_parameter[13]; int hrv_up_ol2_m = a_m_parameter[16]; int hrv_up_ol2_a = a_m_parameter[15]; int hrv_up_ol3_m = a_m_parameter[18]; int hrv_up_ol3_a = a_m_parameter[17]; int hrv_up_ol4_m = a_m_parameter[20]; int hrv_up_ol4_a = a_m_parameter[19]; int hrv_down_ol5_m = a_m_parameter[22]; int hrv_down_ol5_a = a_m_parameter[21]; int hrv_down_ol6_m = a_m_parameter[24]; int hrv_down_ol6_a = a_m_parameter[23]; int hrv_down_ol7_m = a_m_parameter[25]; //Attenuators are fixed //H-polar double hrh_1u_att = 15.5; double hrh_1l_att = 15.5; double hrh_2u_att = 15.5; double hrh_2l_att = 15.5; double hrh_3u_att = 15.5; double hrh_3l_att = 15.5; double hrh_4u_att = 15.5; double hrh_4l_att = 15.5; //V-polar double hrv_1u_att = 15.5; double hrv_1l_att = 15.5; double hrv_2u_att = 15.5; double hrv_2l_att = 15.5; double hrv_3u_att = 15.5; double hrv_3l_att = 15.5; double hrv_4u_att = 15.5; double hrv_4l_att = 15.5; //Configure HRS-H Hifi_HIFI_Config_HRS_H_att_lo($BBID,hrs_polarization_h,hrh_1u_att,hrh_1l_att,hrh_2u_att,hrh_2l_att,hrh_3u_att,hrh_3l_att,hrh_4u_att,hrh_4l_att,hrh_up_ol1_m,hrh_up_ol1_a,hrh_up_ol2_m,hrh_up_ol2_a,hrh_up_ol3_m,hrh_up_ol3_a,hrh_up_ol4_m,hrh_up_ol4_a,hrh_down_ol5_m,hrh_down_ol5_a,hrh_down_ol6_m,hrh_down_ol6_a,hrh_down_ol7_m); //delay(hrs_config_delay); // //Configure HRS-V Hifi_HIFI_Config_HRS_V_att_lo($BBID,hrs_polarization_v,hrv_1u_att,hrv_1l_att,hrv_2u_att,hrv_2l_att,hrv_3u_att,hrv_3l_att,hrv_4u_att,hrv_4l_att,hrv_up_ol1_m,hrv_up_ol1_a,hrv_up_ol2_m,hrv_up_ol2_a,hrv_up_ol3_m,hrv_up_ol3_a,hrv_up_ol4_m,hrv_up_ol4_a,hrv_down_ol5_m,hrv_down_ol5_a,hrv_down_ol6_m,hrv_down_ol6_a,hrv_down_ol7_m); delay(hrs_config_delay); // //Now Configure blocks HRS_config_resol_proc_ops(band,hrs_mode); // //Check attenuator values mois_tmcheck("Check that parameters HRH_1U_ATT, HRH_1L_ATT, HRH_2U_ATT, HRH_2L_ATT, HRH_3U_ATT, HRH_3L_ATT, HRH_4U_ATT and HRH_4L_ATT are set to 15.5"); mois_tmcheck("Check that parameters HRV_1U_ATT, HRV_1L_ATT, HRV_2U_ATT, HRV_2L_ATT, HRV_3U_ATT, HRV_3L_ATT, HRV_4U_ATT and HRV_4L_ATT are set to 15.5"); //Check LO locks and values mois_tmcheck("Check that parameters HRH_LOCK_LO1_S, HRH_LOCK_LO2_S, HRH_LOCK_LO3_S, HRH_LOCK_LO4_S, HRH_LOCK_LO5_S, HRH_LOCK_LO6_S, and HRH_LOCK_LO7_S are all Locked"); mois_tmcheck("Check that parameters HRV_LOCK_LO1_S, HRV_LOCK_LO2_S, HRV_LOCK_LO3_S, HRV_LOCK_LO4_S, HRV_LOCK_LO5_S, HRV_LOCK_LO6_S, and HRV_LOCK_LO7_S are all Locked"); Check_HRS_LO_proc_ops([hrs_mode_h,hrs_mode_v],hrsH_LO[0],hrsH_LO[1],hrsH_LO[2],hrsH_LO[3],hrsH_LO[4],hrsH_LO[5],hrsH_LO[6],hrsV_LO[0],hrsV_LO[1],hrsV_LO[2],hrsV_LO[3],hrsV_LO[4],hrsV_LO[5],hrsV_LO[6]); } //Chopper rotation procedure. Reduced version without overshooting treatment // Always one step procedure RotateChopper { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency string chop_target = "chop_cold"; //Targetted chopper position }{ {bool,double,double} chopparms = GetChopVoltages(band,lo_freq,chop_target,chop_target); bool isPrime = chopparms{0}; // Call command if(isPrime) { Hifi_HIFI_P_Chopper_Rot($BBID,chopparms{1}); } else { Hifi_HIFI_R_Chopper_Rot($BBID,chopparms{1}); } // No delays should be required here } //Procedure to store currently tuned frequency, procedure //Only applicable to non-FSW obs. procedure HIFI_HL_store_tm_only_proc_fm { }{ Hifi_HIFI_HL_store_tm($BBID); delay(1); } // General version used in most observingmodes procedure LoadMeasurement { string band = "4a"; // HIFI band (needed to estimate stabilization) double lo_freq = 978200.0; // LO frequency double deltanu = 1.0; // minimum effective resolution of the calibrated data int data_time = 4; // time between subsequent data readouts {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // Readout parameters for HRS1,HRS2, WBS1,WBS2 }{ // Call generic version with fixed parameters SScanLoadMeasurement(band,lo_freq,lo_freq,true,deltanu,data_time,backendreadoutparms); } //Set to rescue from switched off mode HifiManCmd_HIFI_SwitchedOff_to_Rescue { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ Mode_status_check_switched_off(); mois_comment("Switching to rescue mode"); mois_step("Power ON the ICU - start up the BSW"); string icu_subsys = "ICU_Prime"; if(prime_or_redundant == "Red") { icu_subsys = "ICU_Red"; } PDU_switch_on_block_ops(icu_subsys); Mode_status_check_rescue("normal"); } {string,double,double}[] procedure HifiMappingModeLoadChopOTFNoRefSequencerInit { string modeName = "load-raster"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // chunk size given by the data rates and optimum speed int n_switch_on = 1 in [1,1800]; // Supersamplingfactor int n_cycles = 1 in [1,1200]; // Number of map coverages int load_interval = 1800 in [10,7200]; // load period defines number of lines between two loads }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode // limit on data rate {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // limits from noise section // Get the drift parameters to compute the drift noise // System Allan variance double[] allanparms = InterpolateSpecAllan(band,lo_freq,oneGHzReference); // rescale to frequency resolution double alpha = allanparms[1]; double binningexp = 1.0 / allanparms[2]; double allan_time_lores = allanparms[0] * pow(1.0 / effResolution{1},binningexp); // Compute derived quantities int data_time_guess = imin(imax(iceil(0.3 * allan_time_lores),datalimit),20); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } // n_switch limited by load_interval - 2 lines should be possible int n_switch_on_guess = load_interval / (4 * npoints * data_time_guess); int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } // Contruct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)}]; return retvalues; } //Diplexer FSW investigation: phase-block procedure Dip_FSW_B_phase { string band = "3a" in ["3a","3b","4a","4b","6a","6b","7a","7b"]; // HIFI band bool retune = true; //whether the diplexer is adjusted between frequencies or not double lo_freq2 = 810.0; double lo_freq_ref = 810.0; int[] res = [4,1]; string backend = "both"; string polarization = "H" in ["H","V"]; //The polarization on which the test is done bool modulate = true; //whether we change FSW register and DPACT }{ //Integrate at FSW1 if(modulate) { Activate_FSW_register_block_fm("FSW2"); if(retune) { Set_Single_Diplexer_current_block_fm(band,lo_freq2,polarization); } else { Set_Single_Diplexer_current_block_fm(band,lo_freq_ref,polarization); } } else { //Hifi_HIFI_noop(); } Spectro_total_power_AOTLike_block_fm(band,res,backend); //Add 2sec for investigation of SPR-2404 delay(2); } ////////////////////////////////////////////////////////////////////// // Procedure to perform the noise level evaluation for the observing mode {double,double,double,double,double} procedure SScanChopNoRef_noisecomputer { string band = "4a"; // HIFI band double reffreq = 978300.0; // Reference LO frequency in scan center int nfreq = 4; // Number of frequency points per IF bool dsb = true; // Both sidebands covered {double,double} eff_resolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz int n_cycles = 1; // Number of map coverages bool fs = false; // whether frequency switch used double tscan = 60.0; // Total average duration of one scan double tdead = 10.0; // Average dead time in one slew }{ // spectral scans always use the full bandwidth for reference bool oneGHzReference = false; // Call position switch noise computer {double,double,double,double,double} noisevalues = PositionSwitch_noisecomputer(band,reffreq,eff_resolution,oneGHzReference,n_cycles,tscan,tdead); // Correct for multiple frequencies and signal in both phases in case of FSW if(fs) { double multiplier = sqrt(0.5 / double(nfreq)); } else { multiplier = sqrt(1.0 / double(nfreq)); } noisevalues{0} = noisevalues{0} * multiplier; noisevalues{1} = noisevalues{1} * multiplier; // Check for double sideband coverage if(dsb) { // Combine LSB-USB noise // In spectral scans we have only a combined noise temperature for both // sidebands, so that the USB/LSB separation is not used double[] gssb = InterpolateGssb(band,reffreq); double usbnoise_lores = noisevalues{0} / sqrt(1.0 + gssb[1] / gssb[0] * (gssb[1] / gssb[0])); double usbnoise_hires = noisevalues{1} / sqrt(1.0 + gssb[1] / gssb[0] * (gssb[1] / gssb[0])); double lsbnoise_lores = usbnoise_lores; double lsbnoise_hires = usbnoise_hires; } else { // Get single sideband noise equivalent usbnoise_lores = noisevalues{0}; usbnoise_hires = noisevalues{1}; lsbnoise_lores = noisevalues{2}; lsbnoise_hires = noisevalues{3}; } // Return noise values and the maximum ratio of drift to radiometric noise return {usbnoise_lores,usbnoise_hires,lsbnoise_lores,lsbnoise_hires,noisevalues{4}}; } //Switch off upconverter, block //It assumes that mixer and chopper are also to be switched off block Upconverter_switch_off_block_fm HIFI 3645 { }{ Start_block(); Hifi_HIFI_Configure_FCU_Power($BBID,"OFF","OFF","OFF","OFF","OFF"); delay(1); } // LCU3b configuration into SAFE mode, procedure procedure LCU3b_config_safe_proc_fm { string band = "3b"; // HIFI band double lo_freq = 900.0 in [852.0,953.0]; //LO frequency }{ error("This module is obsolete: use LCU_config_nominal_proc_fm instead"); } // Get dead time for chopper motion double procedure GetSkyChopDeadTime { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency }{ double[] dead = CalibrationReader("chop_deadtime",["skychop"],band,lo_freq); return dead[0]; } // Magnet current scan, slow, procedure // IF power as function of magnet current procedure Magnet_scan_slow_proc { string band = "1a"; // HIFI band //Setting file double magnet_current_min_h = -10.0; //minimum magnet current H double magnet_current_max_h = 15.0; //maximum magnet current H double magnet_current_min_v = -10.0; //minimum magnet current V double magnet_current_max_v = 15.0; //maximum magnet current V int n_steps = 100; //number of steps string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3 int integ_time = 4; //Total integration time in sec.: at least 2sec ! string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast double lo_freq = 522.0; //LO frequency int tune_target_magnet = 40 in [10,85]; //Target WBS illumination percentage during magnet tuning double shapiro_bias = 1.8; //Shapiro Mixer bias, same used for both polarization }{ // //WBS calibration //Configure backends to max. attenuation for magnet scan if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band); } // //Configure spectrometers integration Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); // Magnet_scan_slow_fm(band,magnet_current_min_h,magnet_current_max_h,magnet_current_min_v,magnet_current_max_v,n_steps,integ_time,lo_freq,backend,tune_target_magnet,shapiro_bias); //Back to nominal values {double,string}[] result = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,0.0); //First set magnet to maximum to avoid hysteresis double magnetcurrent_max_h = result[0]{0}; double magnetcurrent_max_v = result[1]{0}; Set_Magnet_current_block_fm(magnetcurrent_max_h,magnetcurrent_max_v); // //Nominal values result = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v","norm_bias_h","norm_bias_v"],band,lo_freq); Set_Magnet_current_block_fm(result[0]{0},result[1]{0}); //Also set bias voltages back to nominal values Mixerbias_block_fm(result[2]{0},result[3]{0}); } //////////////////////////////////// // Fast chop DBS raster observing mode - Engineering version with half throw // // The timing is defined as WBS timing, the HRS takes more data during // the WBS read out, but this is ignored in the computations here. // // Return time and noise levels {int,double,double,double,double,double} obs HifiEngHalfThrowFastDBSRaster { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source {double,double} lineDistance = {0.0050,0.0050}; // Distance between subsequent rows int nlines = 1 in [1,100]; // Number of rows in the map double stepsize = 0.0050 in [5.5556E-4,0.13333]; // Distance between subsequent points in the raster line int npoints = 10 in [2,100]; // Number of points per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 10 in [4,80]; // data dump interval int n_int_on = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_switch_on = 1 in [1,1800]; // number of data transfer cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Engineering - DBS Raster Map halfThrow fastChop",{data_time,0,n_int_on,n_switch_on,0,0,n_pointsperscan,0,n_cycles,load_interval}); // Call first part of the timing computer {int,int,int,int,int,int,int,int,int,int,int,int,int} pre_timing = FastDBSRaster_pre_timing(nlines,npoints,band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_switch_on,n_pointsperscan,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; // Check for NoddingInRaster or NoddingOfRaster int scansize = pre_timing{10}; if(scansize > 1) { {int,int,int,string,int,double,double,bool,double,double,double,int,int,double,double,int,int,double,double,int,int,int,int,int} tmpar = DBSMultiRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"half",pre_timing,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = nodding_of_raster_pointing(false,tmpar{0},tmpar{1},tmpar{2},tmpar{3},tmpar{4},tmpar{5},tmpar{6},tmpar{7},tmpar{8},tmpar{9},tmpar{10},tmpar{11},tmpar{12},tmpar{13},tmpar{14},tmpar{15},tmpar{16},tmpar{17},tmpar{18},tmpar{19},tmpar{20},tmpar{21},tmpar{22},tmpar{23}); } else { {int,int,int,string,int,double,double,bool,double,double,double,int,int,double,double,int,int,int,double,double,int,int,int,double,double,int,int,int,int} tpar = DBSRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"half",pre_timing,n_cycles); telescopetimes = nodding_raster_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23},tpar{24},tpar{25},tpar{26},tpar{27},tpar{28}); } ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,int},bool,double,double} post_timing = DBSRaster_post_timing(pre_timing,telescopetimes,nlines,npoints,n_switch_on,n_cycles,load_interval,true); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command if(scansize > 1) { tmpar = DBSMultiRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"half",post_timing{1},n_cycles); // Call telescope command telescopetimes = nodding_of_raster_pointing(true,tmpar{0},tmpar{1},tmpar{2},tmpar{3},tmpar{4},tmpar{5},tmpar{6},tmpar{7},tmpar{8},tmpar{9},tmpar{10},tmpar{11},tmpar{12},tmpar{13},tmpar{14},tmpar{15},tmpar{16},tmpar{17},tmpar{18},tmpar{19},tmpar{20},tmpar{21},tmpar{22},tmpar{23}); } else { tpar = DBSRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"half",post_timing{1},n_cycles); telescopetimes = nodding_raster_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23},tpar{24},tpar{25},tpar{26},tpar{27},tpar{28}); } // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{3}; int n_load = post_timing{1}{6}; int n_loadinterval = post_timing{1}{7}; int n_seq = post_timing{1}{8}; int initlength = post_timing{1}{11}; int dangling = post_timing{1}{12}; bool final_load = post_timing{2}; double tscan = post_timing{3}; double tdead = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { HalfFastDBSRaster_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_seq,n_cycles,scansize,n_loadinterval,n_load,final_load,startobs,telescopetimes,loadlength,false); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double} tact = FastDBSRaster_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_seq,n_load,scansize,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = DBS_noisecomputer(band,lo_freq,effResolution,continuumDetection,oneGHzReference,n_cycles,tscan,tact); // Evaluate performance DBSRaster_performance(band,lo_freq,effResolution,noisevalues,timeTaken,nlines,npoints,n_cycles,n_seq * n_int_on * imax(n_load,1),tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // // Diplexer scan very fast, block. // Mixer current as function of diplexer current. // Uses the new OBS TC allowing much faster scan. block Scan_diplexer_block_fm HIFI 3254 { string band = "3a"; // HIFI band double diplexer_current_min_h = -2.24; //minimum diplexer current H double diplexer_current_min_v = -2.24; //minimum diplexer current V double diplexer_current_step = 0.1; //maximum diplexer current V int n_steps = 100; //number of steps double stepTime = 0.1; //Step time in seconds }{ //Start_block(); //double stepTime = 0.07; //Should be in a config file eventually //Check how many TCs need to be sent int max_step = 61; int nloop = iceil(double(n_steps) / double(max_step)); //Compute number of step for last interation int last_n_steps = n_steps - (nloop - 1) * max_step; int dipscan_delay = 0; // //Preset to first value and wait 1sec (for possible overshoot) Set_Diplexer_current_proc_fm(diplexer_current_min_h,diplexer_current_min_v); //Send command for(int i = 1 .. nloop) { n_steps = max_step; diplexer_current_min_h = diplexer_current_min_h + double((i - 1) * max_step) * diplexer_current_step; diplexer_current_min_v = diplexer_current_min_v + double((i - 1) * max_step) * diplexer_current_step; if(i == nloop) { n_steps = last_n_steps; } Hifi_HIFI_scan_diplexer($BBID,n_steps,stepTime,diplexer_current_min_h,diplexer_current_min_v,diplexer_current_step); //Compute delay dipscan_delay = iceil(1.0 + double(n_steps) * (stepTime + 0.03)); delay(dipscan_delay + 1); } } //Magnet tune fine, procedure procedure Magnet_tune_fine { string band = "1a"; // HIFI band int integ_time = 4; //Integration time double lo_freq = 522.0; //LO frequency string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ Magnet_scan_fine_fm(band,integ_time,lo_freq,backend); } /////////////////////////////////////////////////////////////////// // Procedure to compute detailed post timing for the version of the // load-chop and frequency-switch modes with baseline measurement // {int,{int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int},int,bool,double,double} procedure DoubleChop_post_timing { {int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int} pre_timing = {16,16,16,16,21,11,1800,32,2,2,0,0,false,false,50,0}; // pre_timing parameter list int[] telescopetimes = [300,180,20,1,21,0]; int n_cycles = 1; // Number of half OFF-ON-ON-OFF calibration cycles }{ // Get all values from the pre_timing section int on_inttime = pre_timing{0}; int off_inttime = pre_timing{1}; int on_pointing = pre_timing{2}; int off_pointing = pre_timing{3}; int loadlength = pre_timing{4}; int jitterdead = pre_timing{5}; int load_spacing = pre_timing{6}; int n_loadinterval = pre_timing{7}; int n_per_on = pre_timing{8}; int n_per_off = pre_timing{9}; int n_load_on = pre_timing{10}; int n_load_off = pre_timing{11}; bool end_load_on = pre_timing{12}; bool end_load_off = pre_timing{13}; int initlength = pre_timing{14}; int dangling = pre_timing{15}; // Use all values from the telescope section int telinit = telescopetimes[1]; // Initial slew time int slewtime = telescopetimes[2]; // Slew time to OFF int pointwaittime = telescopetimes[3]; // Idle time between two phases int longslew = telescopetimes[4]; // Actual slew time for load slew int tend = telescopetimes[5]; // Final deceleration time // If load is performed between the cycles use pointwaittime for load int halfloadlength = (loadlength - jitterdead + 1) / 2; int effhalfloadlength = (loadlength - jitterdead - pointwaittime + 1) / 2; if(end_load_on) { on_pointing = on_pointing - (halfloadlength - effhalfloadlength); int shiftlength_on = effhalfloadlength; } else { shiftlength_on = 0; } if(end_load_off) { off_pointing = off_pointing - (halfloadlength - effhalfloadlength); int shiftlength_off = effhalfloadlength; } else { shiftlength_off = 0; } // treat remaining pointwaittime like an additional slew dead time in cycles slewtime = slewtime + pointwaittime; longslew = longslew + pointwaittime; // Now we can compute the true scan time int scan_time = on_pointing + off_pointing + slewtime; // Finally I can compute the load interval n_loadinterval = imax((load_spacing + slewtime) / scan_time,1); // Exception handling for very uneven phases if(end_load_on || end_load_off) { n_loadinterval = 1; } // Variables for the noise computer // Compute duration of measurement and average scan length // Compute total dead time in one pointing cycle including load overhead int scan_time_long = on_pointing + off_pointing + longslew; int n_long = n_cycles / n_loadinterval; // Determine need for final load measurement double rest = double(n_cycles % n_loadinterval) + 0.5; bool final_load = rest > 0.5001 * double(n_loadinterval); int looplength = (n_cycles - n_long) * scan_time + n_long * scan_time_long; double tscan = double(looplength) / double(n_cycles); // Get pointing dead time, instrument dead time is added later double tdead = tscan - double(off_inttime + on_inttime); int initshiftlength = shiftlength_off; // Check the last pointing cycle, repeated on the telescope procedure if(n_cycles % 2 == 0) { int lastshiftlength = shiftlength_off; } else { lastshiftlength = shiftlength_on; } // Add dangling load time if(lastshiftlength > 0) { dangling = loadlength - lastshiftlength; } if(final_load) { dangling = loadlength; } int closelength = duration(HIFICloseObs()); dangling = imax(dangling + closelength - tend,0); // Compute total duration initlength = initlength - initshiftlength; // The initial time is no longer contained in the total time // Compute total duration, remove pointwaittime for last slew int totaltime = looplength + dangling - pointwaittime + tend; // show gyro-propagation messages GCPMessages(off_pointing,2 * scan_time_long,tend); // Return all the times needed in the telescope and instrument modules return {totaltime,{on_inttime,off_inttime,on_pointing,off_pointing,loadlength,jitterdead,load_spacing,n_loadinterval,n_per_on,n_per_off,n_load_on,n_load_off,end_load_on,end_load_off,initlength,dangling},initshiftlength,final_load,tscan,tdead}; } //General LO configuration command // Uses SFT approach with safe call to 3b BUT combined TM page dump block HIFI_Configure_LCU_block_spur HIFI 3978 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency int freq_nx = 0; // HL_freq_nx int lsu_main = 0; // HL_LSU_main int lsu_offset = 0; // HL_LSU_offset int d2_step = 1; // HL_D2_step double plevel_v = 0.0; double m1_v = 9.0; double m2_v = -2.0; double m3_v = 0.0; double gate1_v = -2.5; double gate2_v = -2.5; double drain1_v = 2.8; string curlim1_v = "1.4"; double drain2_v = 2.6; string curlim2_v = "1.4"; int macro_checksum = 0; // HL_macro_checksum int config_lo_delay = 6; }{ //Check that Vd2 is within the blue limits drain2_v = Check_BLUE_LIMIT_D2_proc_fm(band,lo_freq,drain2_v); // //Start_block(); // //Execute configuration //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Conf_safe_LCU_ch1a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "1b") { //Band 1b Hifi_HIFI_Conf_safe_LCU_ch1b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "2a") { //Band 2a Hifi_HIFI_Conf_safe_LCU_ch2a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "2b") { //Band 2b Hifi_HIFI_Conf_safe_LCU_ch2b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "3a") { //Band 3a Hifi_HIFI_Conf_safe_LCU_ch3a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "3b") { //Band 3b Hifi_HIFI_Conf_safe_LCU_ch3b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "4a") { //Band 4a Hifi_HIFI_Conf_safe_LCU_ch4a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "4b") { //Band 4b Hifi_HIFI_Conf_safe_LCU_ch4b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "5a") { //Band 5a Hifi_HIFI_Conf_nom_LCU_ch5a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "5b") { //Band 5b Hifi_HIFI_Conf_nom_LCU_ch5b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "6a") { //Band 6a Hifi_HIFI_Conf_nom_LCU_ch6a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "6b") { //Band 6b Hifi_HIFI_Conf_nom_LCU_ch6b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "7a") { //Band 7a Hifi_HIFI_Conf_nom_LCU_ch7a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "7b") { //Band 7b Hifi_HIFI_Conf_nom_LCU_ch7b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } // delay(config_lo_delay); // //Store settings into available register //HIFI_HL_store_tm_proc_fm(); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } ///////////////////////////////////////////////////////// // WBS configuration with maximum attenuation, block // Lasers set up as in config file block WBS_config_max_att_block_fm HIFI 3638 { string band = "1a"; // HIFI band }{ //Start_block(); //H-Polarization // {double,string}[] result_d = ConfigurationReader("name_configwbs",["hwh_laser1_s","hwh_laser2_s","hwh_heater","hwh_latchup_s"],band,0.0); string hwh_laser1_s = result_d[0]{1}; string hwh_laser2_s = result_d[1]{1}; int hwh_heater = iround(result_d[2]{0}); string hwh_latchup_s = result_d[3]{1}; int hwh_att_band4 = 7; int hwh_att_band3 = 7; int hwh_att_band2 = 7; int hwh_att_band1 = 7; int hwh_att_in = 15; // result_d = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result_d[0]{0}); //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); //delay(wbs_config_delay); //V-Polarization //Get configuration parameters // result_d = ConfigurationReader("name_configwbs",["hwv_laser1_s","hwv_laser2_s","hwv_heater","hwv_latchup_s"],band,0.0); string hwv_laser1_s = result_d[0]{1}; string hwv_laser2_s = result_d[1]{1}; int hwv_heater = iround(result_d[2]{0}); string hwv_latchup_s = result_d[3]{1}; int hwv_att_band4 = 7; int hwv_att_band3 = 7; int hwv_att_band2 = 7; int hwv_att_band1 = 7; int hwv_att_in = 15; //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // //Wait delay to allow all setting to be configured delay(wbs_config_delay); } //Force boot, procedure: NOT LONGER USED, USE BLOCK INSTEAD procedure HIFI_force_boot_proc { int partition_ID = 0; //0 if forceboot_default. Partition ID in case it should be used. }{ if(partition_ID == 0) { Hifi_HIFI_force_bootdefault(); } else { Hifi_HIFI_force_bootpartition(partition_ID); } //Increase delay - SPR-1354 delay(5); } ///////////////////////////////////////////////////////////////// // Procedure to compute total dead times for the mode // {double,double,double} procedure OTFmap_deadtimes { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // chunk size given by the data rates and optimum speed int n_supersample = 1; // Supersamplingfactor int n_linesperscan = 1; // Number of lines between two OFFs int n_intoff = 3; // Number of data dumps for the OFF integration time int n_pp = 10; // Number of data dumps per line double tdead = 10.0; // Dead time from telescope }{ ////////////////////////////////////////////////////////////////////// // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Dead time in OFF {double,double} tinst = GetInstDeadSlowChop(data_time,n_intoff,"tp",band,lo_freq,backendreadoutparms); // dead time within OFF double tdeadint = double(data_time * n_intoff) - tinst{0}; // total dead time from OFF double tdead_tot = tdead + tdeadint; double tintoff = tinst{0}; // Dead time in one line tinst = GetInstDeadSlowChop(data_time,n_pp,"tp",band,lo_freq,backendreadoutparms); // Dead time for each line tdeadint = double(data_time * n_pp) - tinst{0}; tdead_tot = tdead_tot + double(n_linesperscan) * tdeadint; double tintpoint = tinst{0} / double(n_pp) * double(n_supersample); // Return total dead time and actual integration times return {tdead_tot,tintpoint,tintoff}; } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the observing mode procedure LoadChopNoRef_commanding { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // data dump interval limited by the data rates int n_per_on = 2; // number of half load-sky-sky-load cycles on ON int n_load_on = 0; // additional load measurements in ON pointing phase bool end_load_on = false; // Need for load after ON pointing phase int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,0]; // Timing of observation from telescope int loadlength = 21; // Load duration }{ ////////////////////////////////////////////////////////////////////// // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time //////////////////////////////////////////////////////////////////////// // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // // Clustering is currently not implemented in MPS - switched off here int clustered = 0; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] rates = dataparms{1}; int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 1) { // Initialization if(clustered != 1) { HIFIInitObs(); TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal"); } delay(tinitslew - (time() - startobs) - loadlength - hkduration); // First load measurement HIFISetHK("normal",false); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 3) { // ON integration HIFIConfigureLoadChopIntegration(data_time,n_per_on,band,lo_freq,backendreadoutparms); // Loop for load cycles for(int i1 = 1 .. n_load_on) { HIFILoadChopOnIntegration(data_time,n_per_on,band,lo_freq,rates); // Perform load calibration delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); HIFIConfigureLoadChopIntegration(data_time,n_per_on,band,lo_freq,backendreadoutparms); } // Last cycle - no load HIFILoadChopOnIntegration(data_time,n_per_on,band,lo_freq,rates); } if(state[0] == 5) { delay(readoutdead); if(end_load_on) { // Perform final load measurement LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } HIFICloseObs(); } } } // Initialisation of FPU, block with only H-MSA in use // It is only for cold context block Init_MSA_H_fm HIFI 3207 { string band = "1a"; string chop_loop = "CLOSE"; double lo_freq = 522.0; //LO frequency }{ Start_block(); //Get parameters {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,lo_freq); int band_nb = iround(result_d[0]{0}); double diplex_H = 0.0; double diplex_V = 0.0; int diplex_h_ctrl_mode = 0; int diplex_v_ctrl_mode = 0; // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],"0",0.0); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // string chop_sine_s = "ON"; // string chop_loop = "CLOSE" ; result_d = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current_on"],band,lo_freq); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // double calibcurrent = result_d[7]{0}; // //Get biases result_d = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); double bias_H = result_d[0]{0}; double bias_V = result_d[1]{0}; //For bands 6 and 7, first set to 4mV if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { result_d = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,lo_freq); bias_H = result_d[0]{0}; bias_V = result_d[1]{0}; } // //Get magnets: not applicable to bands 6 and 7 double magnetcurrent_H = 0.0; double magnetcurrent_V = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,lo_freq); magnetcurrent_H = result_d[0]{0}; magnetcurrent_V = result_d[1]{0}; } //Diplexer is interpolated from a table for Bands 3, 4, 6L and 6H if(band_nb <= 2 || band_nb == 5) { diplex_H = 0.0; //For bands 1, 2 and 5 diplex_V = 0.0; diplex_h_ctrl_mode = 0; diplex_v_ctrl_mode = 0; } else { //Get diplexer currents result_d = ConfigurationReader("name_confilfpu",["diplex_h_ctrl_mode","diplex_v_ctrl_mode"],band,lo_freq); diplex_h_ctrl_mode = iround(result_d[0]{0}); diplex_v_ctrl_mode = iround(result_d[1]{0}); double[] result_dip = Get_Diplexer_setting(band,lo_freq); diplex_H = result_dip[0]; diplex_V = result_dip[1]; } // result_d = ConfigurationReader("name_chopper",["chop_startup_cold"],band,0.0); if(chop_loop == "OPEN") { result_d = ConfigurationReader("name_chopper",["chop_startup_warm"],band,0.0); } double chopper = result_d[0]{0}; //For this configuration we won't convert prime chopper voltage into redundant voltage //Just checking we are in range. //chopper = Check_Chopper_Prime_Redundant(chopper); chopper = Check_Chopper_Range(chopper); // //Switch on upconverter, assuming chopper and mixers are also ON Hifi_HIFI_Configure_FCU_Power($BBID,"ON","ON","ON","ON","ON"); // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result_d = ConfigurationReader("name_delays",["config_fpu_delay"],band,lo_freq); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // //In case of band 6 or 7, bias have been set to 4mV. Now set to nominal if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { {double,string}[] result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); Mixerbias(result[0]{0},result[1]{0}); } // //Magnet are so far at maximum value. Now set to nominal if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); Hifi_HIFI_CH1_MX_MG_C($BBID,result_d[0]{0}); Hifi_HIFI_CV1_MX_MG_C($BBID,result_d[1]{0}); delay(1); } // Hifi_HIFI_non_periodic_hk_FCU(); } ///////////////////////////////////////////////////////////////// // Get limiting frequencies {double,double} procedure GetBandLimits { string band = "4a"; // HIFI band }{ // read master file string calibfile = slookup("frequencystep_masterfile",band,"tablefile"); double[] allfpoints = dcolumn(calibfile,"stepfrequency"); // get table size int iindex1 = length(allfpoints); double firstlo = allfpoints[1]; double lastlo = allfpoints[iindex1 - 2]; return {firstlo,lastlo}; } //////////////////////////////////// // Fast chop DBS raster observing mode // // The timing is defined as WBS timing, the HRS takes more data during // the WBS read out, but this is ignored in the computations here. // // Combination of four modules implementing the new structure // // Return time and noise levels {int,double,double,double,double,double} obs HifiMappingProcFastDBSRaster { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source {double,double} lineDistance = {0.0050,0.0050}; // Distance between subsequent rows int nlines = 1 in [1,100]; // Number of rows in the map double stepsize = 0.0050 in [5.5556E-4,0.13333]; // Distance between subsequent points in the raster line int npoints = 10 in [2,100]; // Number of points per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 10 in [4,80]; // data dump interval int n_int_on = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_switch_on = 1 in [1,1800]; // number of data transfer cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Mapping - DBS Raster Map fastChop",{data_time,0,n_switch_on,n_int_on,0,0,n_pointsperscan,0,n_cycles,load_interval}); // Call first part of the timing computer {int,int,int,int,int,int,int,int,int,int,int,int,int} pre_timing = FastDBSRaster_pre_timing(nlines,npoints,band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_switch_on,n_pointsperscan,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; // Check for NoddingInRaster or NoddingOfRaster int scansize = pre_timing{10}; if(scansize > 1) { {int,int,int,string,int,double,double,bool,double,double,double,int,int,double,double,int,int,double,double,int,int,int,int,int} tmpar = DBSMultiRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",pre_timing,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = nodding_of_raster_pointing(false,tmpar{0},tmpar{1},tmpar{2},tmpar{3},tmpar{4},tmpar{5},tmpar{6},tmpar{7},tmpar{8},tmpar{9},tmpar{10},tmpar{11},tmpar{12},tmpar{13},tmpar{14},tmpar{15},tmpar{16},tmpar{17},tmpar{18},tmpar{19},tmpar{20},tmpar{21},tmpar{22},tmpar{23}); } else { {int,int,int,string,int,double,double,bool,double,double,double,int,int,double,double,int,int,int,double,double,int,int,int,double,double,int,int,int,int} tpar = DBSRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",pre_timing,n_cycles); telescopetimes = nodding_raster_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23},tpar{24},tpar{25},tpar{26},tpar{27},tpar{28}); } ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,int},bool,double,double} post_timing = DBSRaster_post_timing(pre_timing,telescopetimes,nlines,npoints,n_switch_on,n_cycles,load_interval,true); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command if(scansize > 1) { tmpar = DBSMultiRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",post_timing{1},n_cycles); // Call telescope command telescopetimes = nodding_of_raster_pointing(true,tmpar{0},tmpar{1},tmpar{2},tmpar{3},tmpar{4},tmpar{5},tmpar{6},tmpar{7},tmpar{8},tmpar{9},tmpar{10},tmpar{11},tmpar{12},tmpar{13},tmpar{14},tmpar{15},tmpar{16},tmpar{17},tmpar{18},tmpar{19},tmpar{20},tmpar{21},tmpar{22},tmpar{23}); } else { tpar = DBSRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",post_timing{1},n_cycles); telescopetimes = nodding_raster_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23},tpar{24},tpar{25},tpar{26},tpar{27},tpar{28}); } // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{3}; int n_load = post_timing{1}{6}; int n_loadinterval = post_timing{1}{7}; int n_seq = post_timing{1}{8}; int initlength = post_timing{1}{11}; int dangling = post_timing{1}{12}; bool final_load = post_timing{2}; double tscan = post_timing{3}; double tdead = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { FastDBSRaster_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_seq,n_cycles,scansize,n_loadinterval,n_load,final_load,startobs,telescopetimes,loadlength,false); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double} tact = FastDBSRaster_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_seq,n_load,scansize,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = DBS_noisecomputer(band,lo_freq,effResolution,continuumDetection,oneGHzReference,n_cycles,tscan,tact); // Evaluate performance DBSRaster_performance(band,lo_freq,effResolution,noisevalues,timeTaken,nlines,npoints,n_cycles,n_seq * n_int_on * imax(n_load,1),tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // Configuration for fast-chop integration int[] block HIFIConfigureFastChopIntegration HIFI 6040 { int data_time = 4; // Integration time between two data readouts int n_int = 20; // number chop cycles to integrate in ICU before transfer int n_seq = 1; // Number of continuous data transfer cycles string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // HRS1/2 {used,resolution,subbands used}, WBS1/2 {used, channel windows} }{ // Call procedure doing the work {int,int} fchop = FastConfigureSpectroscopy(data_time,n_int,n_seq,band,lo_freq,backendreadoutparms); // Return data rates for command return [fchop{0},fchop{1}]; } ///////////////////////////////////////////////////////////////// // get reference frequency, resolution, redundancy {double,int,double} procedure GetFReference { string band = "4a"; // HIFI band double lo_freq1 = 978200.0 in [480000.0,1950000.0]; // LO frequency double lo_freq2 = 979600.0 in [480000.0,1950000.0]; // LO frequency }{ // first step: read master file double referencefreq = ComputeReferenceFreq(band,lo_freq1,lo_freq2); int redundancy = ilookup("frequencystep_masterfile",band,"redundancy"); double stdstep = dlookup("frequencystep_masterfile",band,"stdstep"); return {referencefreq,redundancy,stdstep}; } //Contingency for LOU temp FDIR modification mode HifiManCmd_LOU_FDIR_enable { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! }{ mois_comment("Procedure to enable and modify FDIR limits for LOU operational temperatures"); //StartMode_block_ops(); // mois_step("Set new FDIR limits"); Set_LO_FDIR_temperatures_block_mois(); // StopMode_block_ops(); // -> to issue last obsd/bbid } //Chopper rotation block. It takes into account //overshoot risk and performs the rotation in //2 steps if the targetted positions are either of the end stops block Chopper_Rotation_block_fm HIFI 3646 { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string chop_current_position = "chop_hot_ang"; //Current chopper position string chop_target_position = "chop_cold_ang"; //Targetted chopper position }{ Start_block(); //Retrieve angles of corresponding positions {double,string}[] result_d = ConfigurationReader("name_chopper",[chop_current_position,chop_target_position,"chop_endstopright_ang","chop_endstopleft_ang","overshoot"],band,0.0); double chop_current_angle = result_d[0]{0}; double chop_target_angle = result_d[1]{0}; double chop_endstopright_angle = result_d[2]{0}; double chop_endstopleft_angle = result_d[3]{0}; double overshoot = result_d[4]{0}; string chop_target_name = result_d[1]{1}; string chop_current_name = result_d[0]{1}; int step = 1; // //Check whether the rotation may reach either of the end stops, i.e. //go beyond either the HBB or M3_left ///// We suppose here overshoot to be 0, so the 2 steps only occur when targetting ///// the end stops strictly. overshoot = 0.0; double total_angle = abs(chop_target_angle - chop_current_angle) * (1.0 + overshoot); // //The endstop that one may hit depends on the rotating direction //Case were endstop is the left one double angle_to_endstop = abs(chop_endstopleft_angle - chop_current_angle); if(chop_target_angle > chop_current_angle) { //then end stop is the right one angle_to_endstop = abs(chop_endstopright_angle - chop_current_angle); } //debug_print(total_angle); //debug_print(angle_to_endstop); if(total_angle >= angle_to_endstop) { message("Chopper expected to hit the endstop. Rotation done in two steps"); step = 2; } //If we have two steps necessary, the middle position between current and //targetted position is used. result_d = ConfigurationReader("name_confilfpu",[chop_target_name,chop_current_name],band,0.0); double chop = result_d[0]{0}; double chop_intermediate = (result_d[0]{0} + result_d[1]{0}) / 2.0; // chop = Check_Chopper_Prime_Redundant(chop); if(step == 1) { HIFI_CPR_Chopper_Rot_proc_fm(chop); Hifi_HIFI_non_periodic_hk_FCU(); //To get sent voltage delay(1); } if(step == 2) { chop_intermediate = Check_Chopper_Prime_Redundant(chop_intermediate); HIFI_CPR_Chopper_Rot_proc_fm(chop_intermediate); Hifi_HIFI_non_periodic_hk_FCU(); //To get sent voltage delay(1); HIFI_CPR_Chopper_Rot_proc_fm(chop); Hifi_HIFI_non_periodic_hk_FCU(); //To get sent voltage delay(1); } } ///////////////////////////////////////////////////////////////// // Procedure to compute detailed timing for the mode // {int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int} procedure PositionSwitch_pre_timing { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4 in [1,5]; // data dump interval limited by the data rates int n_int = 3 in [2,1800]; // number of data dumps for integration per phase int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // First check validity of frequencies CheckLOFrequencies(band,lo_freq,lo_freq); // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // First perform consistency checks // Check chunk size given by the data rates CheckDataTaking(backendreadoutparms,data_time); // Compute parameters for the instrument timing int jitterdead = GetMaxTimeJitter(band,lo_freq); int inttime = n_int * data_time; // Resulting integer integration time int pointing = inttime + jitterdead; // Pointing time // compute load integration time int loadlength = duration(LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms)); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); loadlength = loadlength + readoutdead; int halfloadlength = (loadlength - jitterdead + 1) / 2; int load_spacing = CheckedLoadSpacing(load_interval - loadlength,2 * inttime); // Duration of initial set up // determine exact duration only in case of full commanding if(docommands) { int initlength = duration(HIFIInitObs()); initlength = initlength + duration(TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal")); // Add time for HK readout int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); initlength = initlength + hkduration; } else { initlength = GetRoughInitLength(band,lo_freq,false); } initlength = initlength + loadlength; // Compute the load period // First estimate of the load interval int n_loadinterval = imax(load_interval / (2 * pointing),1); // Dangling load not known yet at this point bool final_load = false; int dangling = readoutdead; // pseudo parameters which are notneeded here, but used for a // unified treatment of all modes using the same pointing command int n_seq = 1; int n_load = 0; // Return all the times needed for telescope call and post_timing processing return {inttime,inttime,pointing,pointing,loadlength,halfloadlength,load_spacing,n_loadinterval,n_seq,n_seq,n_load,n_load,final_load,final_load,initlength,dangling}; } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Testmodes for Functional test of WBS FM // // DT - 21/09/04: first draft for QM // DT - 04/11/04: added new modes // 19/07/05: Updated for FM // 09/12/05: Updated after WBS FM delivery. // Laser2 is the default laser for ILT. // 22/01/07: Laser1 is the default laser for FM ILT. //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //Modes: see fm_testmodes.cus //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Associated blocks //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Special COMB FT for WBS, procedure // Follows procedure requested after COMB problem discovered on WBS-V procedure FT_COMB_proc_fm { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string laser_H = "Laser1" in ["Laser1","Laser2"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2"]; //WBS-V laser to be set ON }{ //Allow fast HK readout HKrate(1.0); // int integ_time = 2; //Total integration time in sec. int[] res = Configure_Spectrometer_proc_fm(band,integ_time,["wb1","wb1"],"wbs"); //Scan all attenuators with COMB ON FT_WBS_att_overall_COMB_fm(band,integ_time,laser_H,laser_V,"wbs"); FT_WBS_att_individual_COMB_fm(band,integ_time,laser_H,laser_V,"wbs"); // //Att. at 7/7/7/7/7 WBS_config_w_laser_and_att_block_fm(band,laser_H,laser_V,[7,7,7,7,7],[7,7,7,7,7]); //Spectra with COMB ON - various integration times res = Configure_Spectrometer_proc_fm(band,2,["wb1","wb1"],"wbs"); Spectro_total_power_block_fm(band,res,"wbs"); res = Configure_Spectrometer_proc_fm(band,10,["wb1","wb1"],"wbs"); Spectro_total_power_block_fm(band,res,"wbs"); res = Configure_Spectrometer_proc_fm(band,20,["wb1","wb1"],"wbs"); Spectro_total_power_block_fm(band,res,"wbs"); res = Configure_Spectrometer_proc_fm(band,30,["wb1","wb1"],"wbs"); Spectro_total_power_block_fm(band,res,"wbs"); //Switch off zero and comb after the above Switch_zero_comb_block_fm("OFF"); //Back to slow HK readout HKrate(0.25); } ///////////////////////////////////////////////////////////////// // Get all frequency points in interval double[] procedure GetFScanPoints { string band = "4a"; // HIFI band int firstindex = 1; // Index of first frequency point int lastindex = 2; // Index of last frequency point int increment = 1; // Index increment }{ // first step: read master file string calibfile = slookup("frequencystep_masterfile",band,"tablefile"); double[] allfpoints = dcolumn(calibfile,"lo_frequency"); // Initialize field int nstep = (lastindex - firstindex + 2 * increment - 1) / increment; double[] fpoints = []; // Loop for reading for(int i = 0 .. nstep - 1) { int counter = firstindex + i * increment; fpoints[i] = allfpoints[counter]; } return fpoints; } //Tune HIFI at frequency of interest for 2 frequencies (FSW) procedure HIFITuneFsw { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq_1 = 978200.0; //LO frequency for FSW1 phase double lo_freq_2 = 978300.0; //LO frequency for FSW2 phase bool hrs1used = true; // HRS1 parameter =used bool hrs2used = true; // HRS2 parameter bool wbs1used = true; // WBS1 parameter =used bool wbs2used = true; // WBS2 parameter string target_name = "normal"; // Name of target level }{ // //LO power tuning: could use either H or V polar {double,string}[] result = ConfigurationReader("name_confpolar4lotune",[band],band,lo_freq_1); double x = result[0]{0}; string tuningbackend = "H"; if(iround(x) == 2) { tuningbackend = "V"; } else { tuningbackend = "H"; } // All tuning for first frequency, and store in FSW1 register double lo_freq_setting = 0.5 * (lo_freq_1 / 1000.0 + lo_freq_2 / 1000.0); LO_tuning_block_aot(band,lo_freq_1 / 1000.0,lo_freq_setting,tuningbackend,true,true,true); // //Magnet tuning: could use either HRS or WBS. Not done for bands1,2,6,7 (SCR-2380) if(band == "3a" || band == "3b" || band == "4a" || band == "4b" || band == "5a" || band == "5b") { // Currently only the HRS is used string magnettuningbackend = "HRS"; Magnet_tuning_block_aot(band,lo_freq_1 / 1000.0,magnettuningbackend); } // //Spectrometer attenuator tuning on HBB if(wbs1used || wbs2used) { WBS_attenuators_block(band,lo_freq_1 / 1000.0,target_name,false); } if(hrs1used || hrs2used) { HRS_tune_block_aot(band); } // Second frequency setup, and stored in FSW2 register LO_tuning_block_aot(band,lo_freq_2 / 1000.0,lo_freq_setting,tuningbackend,false,true,true); // } //////////////////////////////////// // OTF load-chop observing mode // // Return time and noise levels {int,double,double,double,double,double} obs HifiMappingProcLoadChopOTF { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source double raoff = 0.0; // RA coordinate of the OFF position double decoff = 0.0; // DEC coordinate of the OFF position bool refSelected = true; // Dummy parameter required by HSPOT {double,double} lineDistance = {0.0050,0.0050}; // Distance between subsequent rows int nlines = 1 in [1,240]; // Number of rows in the map double stepsize = 0.0050 in [0.0,0.13333]; // Distance between subsequent points in the OTF line int npoints = 10 in [1,720]; // Number of data dumps per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // chunk size given by the data rates and optimum speed int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 1 in [1,1800]; // Supersamplingfactor int n_switch_off = 3 in [1,3600]; // Number of data dumps for the OFF integration time int n_linesperscan = 1 in [1,32]; // Number of lines between two OFFs int n_cycles = 1 in [1,1200]; // Number of map coverages int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Mapping - OTF Map Load Chop Ref",{data_time,data_time_off,0,n_switch_on,n_switch_off,n_linesperscan,0,0,n_cycles,load_interval}); // Auxiliary routine for API parameter correction {double,double,int} mapused = ValidMapSize(band,lo_freq,lineDistance,nlines,stepsize,npoints,2 * data_time * n_switch_on); double line_used = mapused{0}; double scanvelocity = mapused{1}; int npoints_used = mapused{2}; // Call first part of the timing computer {int,int,int,int,int,int,int,int} pre_timing = OTFLoadChop_pre_timing(nlines,npoints_used,band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,n_switch_on,n_switch_off,n_linesperscan,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {double,double} refPosition = {raoff,decoff}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,double,double,int,int,double,double,int,int,int,int,int} tpar = OTFmap_telescope(naifid,onPosition,lineDistance,nlines,line_used,refPosition,scanvelocity,band,lo_freq,n_linesperscan,n_cycles,pre_timing); // Dummy call to spacecraft command int[] telescopetimes = line_scan_with_off_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23}); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int},double,double} post_timing = OTFmap_post_timing(pre_timing,telescopetimes,data_time,n_linesperscan,n_cycles,load_interval); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = OTFmap_telescope(naifid,onPosition,lineDistance,nlines,line_used,refPosition,scanvelocity,band,lo_freq,n_linesperscan,n_cycles,post_timing{1}); // Call telescope command telescopetimes = line_scan_with_off_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23}); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int n_pp = post_timing{1}{0}; int n_scans = post_timing{1}{1}; int off_inttime = post_timing{1}{2}; int loadlength = post_timing{1}{4}; int n_loadinterval = post_timing{1}{5}; double tscan = post_timing{2}; double tdead = post_timing{3}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { OTFLoadChop_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,npoints_used * n_switch_on,n_switch_off,nlines * n_cycles,n_linesperscan,n_loadinterval,startobs,telescopetimes,loadlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double,double,double} tact = OTFDoubleChop_deadtimes("lchop",band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,n_switch_on,n_switch_off,n_linesperscan,n_pp,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = OTFLoadChop_noisecomputer(band,lo_freq,effResolution,oneGHzReference,nlines,data_time,n_switch_on,n_linesperscan,off_inttime,n_cycles,tscan,tact); // Evaluate performance OTFDoubleChop_performance(band,lo_freq,effResolution,noisevalues,timeTaken,nlines,npoints_used,n_switch_on,n_switch_off,n_scans,n_cycles,false,tscan,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // Compute the length of an angular vector, derived from AngularDistance double procedure AngleVectorLength { {double,double} vector = {0.0,0.0}; // vector }{ double pideg = 3.14159265 / 180.0; double dist = acos(cos(vector{0} * pideg) * cos(vector{1} * pideg)) / pideg; return dist; } // Switch HIFI off, mode // Assumed to be in standby I when starting this mode // mode HifiManCmd_HIFI_global_switch_off_ops { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red string chopper_loop = "OPEN" in ["OPEN","CLOSE"]; //chopper loop status }{ Mode_status_check_standby_I(chopper_loop,"down",prime_or_redundant); mois_comment("HIFI global switch OFF: successively switch OFF subsystems"); StartMode_block_ops(); HIFI_global_switch_off_proc_ops(prime_or_redundant); //from moc_1.2: use proc instead of block //Here, HIFI is idle: the switch back to obsid = 0 is done just before ICU switched off //StopMode_block_ops () ; Mode_status_check_switched_off(); } // Spectrometer configuration for total power in peakup, procedure // Adds the possibility to blank a polarization int[] procedure Configure_Spectrometer_peakup_proc_fm { string band = "1a"; // HIFI band int integ_time = 4; //Total integration time in sec. string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4,wb5,wb6,wb7,wb8 string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string mixer_polarization = "H" in ["H","V"]; //mixer polarization to be used }{ //First derive backend setting codes as expected by VO's routine //Build up backend parameter tupple: {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = BackendSettings(band,0.0,hrs_mode,backend); // Readout parameters for HRS1,HRS2, WBS1,WBS2 //Blank out unused polarization if(backend == "wbs") { if(mixer_polarization == "H") { backendreadoutparms{3}{0} = false; } else { backendreadoutparms{2}{0} = false; } } if(backend == "hrs") { if(mixer_polarization == "H") { backendreadoutparms{1}{0} = false; } else { backendreadoutparms{0}{0} = false; } } // //Compute data_time and n_switch using the wrapper int[] res = ConfigSlowChop(integ_time,"tp",band,0.0,backendreadoutparms); int data_time = res[0]; int n_switch = res[1]; // Now call the spectroscopy setup: it is common to ILT and AOT CUS. // The deadtimes output is not used at ILT level. {double,double} dtimes = ConfigSpectroscopySlowChop_IST(data_time,n_switch,"tp",band,0.0,backendreadoutparms,true); // return res; } //Stopmode, block block StopMode_block_ops HIFI 7923 { }{ {double,string}[] result = ConfigurationReader("name_lastobsid",["last_obsid_Ops_Manual"],"0",0.0); mois_comment("Switch to obsid number applicable between observations"); Hifi_HIFI_Set_OBS_ID(0,iround(result[0]{0})); //mois_tmcheck("Check that parameter OBS_ID_per_hk has become " + iround(result[0]{0})); delay(1); } //HIFI-COP-X-IF-FBk-Dip procedure IF_FBk_Dip_COP_proc_ops { string band = "3a" in ["3a","3b","4a","4b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 807.0; //LO frequency string[] hrs_mode = ["wb1","wb1"]; int integ_time = 600; string backend = "both"; }{ //Switch-off LO LCU_switch_off_block_fm(); // //Take largest excursion string chop1 = "chop_M3left"; string chop2 = "chop_hot"; //Get voltages {double,string}[] result_d = ConfigurationReader("name_confilfpu",[chop1,chop2],band,0.0); int[] res = [0,0]; // Init_MSA_HBB_fm(band,"CLOSE",lo_freq,"ON"); //Set magnets to 0 Set_Magnet_current_block_fm(0.0,0.0); //Use high biases result_d = ConfigurationReader("name_confilfpu",["bias_high_resistive_h","bias_high_resistive_v"],band,lo_freq); Mixerbias_block_fm(result_d[0]{0},result_d[1]{0}); WBS_calib_fm(band); WBS_tune_proc_fm(band); HRS_config_block_fm(band,hrs_mode); HRS_tune_block_fm(band); // //Diplexer settings considered int total = 3; double[] dipl_curr = [-2.24,0.0,2.24]; result_d = ConfigurationReader("name_confilfpu",[chop1,chop2],band,0.0); res = Configure_Spectrometer_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); //Loop on diplexer settings for(int i = 0 .. total - 1) { // Set_Diplexer_current_block_fm(dipl_curr[i],dipl_curr[i]); Spectro_slow_chop_block_fm(band,[result_d[0]{0},result_d[1]{0}],[integ_time * 2,1],backend); } // //Bias to nominal {double,string}[] result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); Mixerbias(result[0]{0},result[1]{0}); //Magnets back to nominal, via max result = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,lo_freq); Set_Magnet_current_proc_fm(result[0]{0},result[1]{0}); result = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); Set_Magnet_current_proc_fm(result[0]{0},result[1]{0}); } //Readback of LCU safety table and memory patches, mode mode HifiManCmd_readback_LCU_table_flight { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! string section = "P" in ["P","R"]; }{ mois_comment("Start LCU table and memory patch readback"); StartMode_block_ops(); mois_step("Read back memory patch content"); LcuMemoryPatchReadback_ops(section); mois_step("Read back LCU safety table content"); LcuSafetyTableReadback_ops(); StopMode_block_ops(); mois_spacon("Communicate the ObsID to the HIFI team, and check with them that the memory upload has been successful"); } // Fourth part of WBS FM functional test, block // Check effect of attenuators for laser 2 // NOT USED ANYMORE IN FM. STAYS AS A PLACEHOLDER FOR BLOCK NUMBER. //block FT_WBS_att_laser2_fm HIFI 3702 { // string band="1a"; // HIFI band // int integ_time = 4; //Total integration time in sec. // }{ //} // WBS overall attenuator FM functional test, block // Done for laser1 block FT_WBS_att_overall_fm HIFI 3706 { string band = "1a"; // HIFI band int integ_time = 4; //Total integration time in sec. string laser_H = "Laser1" in ["Laser1","Laser2"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2"]; //WBS-V laser to be set ON string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); // //Set zero and comb off Hifi_HIFI_Single_cmd($BBID,"HWH_ZERO_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWV_ZERO_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWH_COMB_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWV_COMB_OFF"); delay(2); // //Initial configuration: overall attenuators set to max., individual attenuators to 0 //H-Polarization // {double,string}[] result = ConfigurationReader("name_configwbs",["hwh_heater","hwh_latchup_s"],band,0.0); string hwh_laser1_s = "OFF"; string hwh_laser2_s = "OFF"; if(laser_H == "Laser1") { hwh_laser1_s = "ON"; } if(laser_H == "Laser2") { hwh_laser2_s = "ON"; } int hwh_heater = iround(result[0]{0}); string hwh_latchup_s = result[1]{1}; int hwh_att_band4 = 0; int hwh_att_band3 = 0; int hwh_att_band2 = 0; int hwh_att_band1 = 0; int hwh_att_in = 16; // result = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result[0]{0}); // //V-Polarization // result = ConfigurationReader("name_configwbs",["hwv_heater","hwv_latchup_s"],band,0.0); string hwv_laser1_s = "OFF"; string hwv_laser2_s = "OFF"; if(laser_V == "Laser1") { hwv_laser1_s = "ON"; } if(laser_V == "Laser2") { hwv_laser2_s = "ON"; } int hwv_heater = iround(result[0]{0}); string hwv_latchup_s = result[1]{1}; int hwv_att_band4 = 0; int hwv_att_band3 = 0; int hwv_att_band2 = 0; int hwv_att_band1 = 0; int hwv_att_in = 16; // //Loop on overall attenuators for(int i = 0 .. 15) { // Change the value of the main attenuator //======================================== hwh_att_in = hwh_att_in - 1; hwv_att_in = hwv_att_in - 1; // Set WBS //======== Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); delay(wbs_config_delay); //Wait for configuration to be applied // Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); delay(wbs_config_delay); //Wait for configuration to be applied // HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // } //Set att. to max. WBS_config_proc_max_att_w_laser_fm(band,laser_H,laser_V); // } //HIFI-COP-X-HRS-Fast-Imix: Fast HRS chopped observations, combined with 21Hz oscillation investigation obs HifiEng_stability_chopped_fasthrs_FastImix { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency in GHz string chopper_pair = "load" in ["load","sky"]; //internal load or sky on-off string with_lo_on = "true" in ["true","false"]; //Whether measurement with LO ON or not }{ // //General parameters in use int phaselength = 10; // Chop phase length int nchop = 12; // Number of phases double readout = 0.333; // HRS readout length double hrs_h_1 = 6.0; //Position in IF of HRS-H sub-band 1 double hrs_h_2 = 6.0; //Position in IF of HRS-H sub-band 2 - not used double hrs_v_1 = 6.0; //Position in IF of HRS-V sub-band 1 double hrs_v_2 = 6.0; //Position in IF of HRS-V sub-band 2 - not used //Needs to duplicate hrs_mode word: double[] hrs_subband = [hrs_h_1,hrs_h_2,hrs_v_1,hrs_v_2]; // Check if(readout < 0.333) { error("We cannot readout both polarizations faster than at 3Hz"); } //General parameters in use for Fast_Imix string polarization = "B"; //mixer to be sampled: H, V or B. If B, they are done successively int milliSecSample = 3; // interval between samples int samplesBefore = 50; int samplesAfter = 1000; // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Stability_chopped_fasthrs_proc_ops(band,lo_freq,phaselength,nchop,readout,hrs_subband,chopper_pair,polarization,milliSecSample,samplesBefore,samplesAfter,with_lo_on)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Stability_chopped_fasthrs_proc_ops(band,lo_freq,phaselength,nchop,readout,hrs_subband,chopper_pair,polarization,milliSecSample,samplesBefore,samplesAfter,with_lo_on); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } //////////////////////////////////// // DBS cross observing mode - special version for Jupiter // // Return time and noise levels {int,double,double,double,double,double} obs HifiMappingProcJupiterDBSCross { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source double stepsize = 0.0050 in [5.5556E-4,0.13333]; // Distance between subsequent points in the two raster lines int npoints = 10 in [2,100]; // Number of points per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_switch_on = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Engineering - Jupiter - DBS Cross Map slowChop",{data_time,0,0,n_switch_on,0,0,n_pointsperscan,0,n_cycles,load_interval}); // Call first part of the timing computer // Two changes relative to the normal DBS raster // 1) The longer load duration is enforced by zero resolution {double,double} loadResolution = {0.0,effResolution{1}}; // 2) I assume that the tuning duration does not depend on the tuning level // so that the normal pre_timing can be reused. {int,int,int,int,int,int,int,int,int,int,int,int,int} pre_timing = DBSRaster_pre_timing(2,npoints,band,lo_freq,loadResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_switch_on,n_pointsperscan,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,bool,double,double,double,double[],double[],int[],double,double,int,int,int,int,int,int} tpar = DBSCross_telescope(naifid,onPosition,stepsize,npoints,band,lo_freq,"",pre_timing,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = custom_map_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21}); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,int},bool,double,double} post_timing = DBSCross_post_timing(pre_timing,telescopetimes,npoints,n_switch_on,n_cycles,load_interval,false); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = DBSCross_telescope(naifid,onPosition,stepsize,npoints,band,lo_freq,"",post_timing{1},n_cycles); telescopetimes = custom_map_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21}); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{3}; int n_load = post_timing{1}{6}; int n_loadinterval = post_timing{1}{7}; int n_seq = post_timing{1}{8}; int scansize = post_timing{1}{10}; int initlength = post_timing{1}{11}; int dangling = post_timing{1}{12}; bool final_load = post_timing{2}; double tscan = post_timing{3}; double tdead = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { JupiterDBSRaster_commanding(band,lo_freq,loadResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_seq,n_cycles,scansize,n_loadinterval,n_load,final_load,startobs,telescopetimes,loadlength,true); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double} tact = DBSRaster_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_seq,n_load,scansize,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = DBS_noisecomputer(band,lo_freq,effResolution,continuumDetection,oneGHzReference,n_cycles,tscan,tact); // Evaluate performance DBSRaster_performance(band,lo_freq,effResolution,noisevalues,timeTaken,2,npoints,n_cycles,n_seq * imax(n_load,1),tact); // Correct for double counting of central point // The central point is returned only double multiplier = sqrt(0.5); noisevalues{0} = noisevalues{0} * multiplier; noisevalues{1} = noisevalues{1} * multiplier; noisevalues{2} = noisevalues{2} * multiplier; noisevalues{3} = noisevalues{3} * multiplier; noisevalues{4} = noisevalues{4} / multiplier; // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } //Procedure checking and, if applicable, converting //prime chopper sent voltage into redundant chopper sent voltage double procedure Check_Chopper_Prime_Redundant_COP { double chopper_angle = 0.0; //prime chopper voltage string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ //Check prime or redundant status {double,string}[] result_d = ConfigurationReader("name_chopper",["prime_or_redundant","p_to_r_coeff_0","p_to_r_coeff_1","p_to_r_coeff_2","prime_endstop_min","prime_endstop_max","red_endstop_min","red_endstop_max"],"0",0.0); double chop = chopper_angle; double prime_endstop_min = result_d[4]{0}; double prime_endstop_max = result_d[5]{0}; double red_endstop_min = result_d[6]{0}; double red_endstop_max = result_d[7]{0}; //Change chopper voltage if necessary if(prime_or_redundant == "Red") { chop = result_d[3]{0} * pow(chop,2.0) + result_d[2]{0} * chop + result_d[1]{0}; } //Now check the chopper angle is within the ranges if(prime_or_redundant == "Prime") { if(chop > prime_endstop_max || chop < prime_endstop_min) { error("The chopper voltage (requested is " + chop + " V) in " + result_d[0]{1} + " mode has to be between " + prime_endstop_min + " and " + prime_endstop_max + " V."); } } if(prime_or_redundant == "Red") { if(chop > red_endstop_max || chop < red_endstop_min) { error("The chopper voltage (requested is " + chop + " V) in " + result_d[0]{1} + " mode has to be between " + red_endstop_min + " and " + red_endstop_max + " V."); } } return chop; } // LO SFT, following procedure of MPI, procedure // Uses routine approach with new TM TC call procedure LO_SFT_proc_ops { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ // double lo_freq = 0.0; double drain2_v = 0.0; double[] cresult_d = CalibrationReader("name_keyfreq",["keyfreq","key_d2v_P","key_d2v_R"],band,0.0); lo_freq = cresult_d[0]; //applies to cold LO //Switch on with safe Vd2 LCU_switchon_proc_fm(band); //LO freq and Vd2 to use is embedded in the proc //Wait total of 20 sec. delay(20); //Check what d2_v to use depending on test circumstances drain2_v = cresult_d[1]; //Value for prime case, and fm H/W // if(prime_or_redundant == "Red") { drain2_v = cresult_d[2]; } // LCU_config_nominal_w_D2_proc_fm(band,lo_freq,drain2_v); } {int,double,double,double,double,double} obs HifiSScanModeLoadChopNoRef { string modeName = "load-freq"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_cycles = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles per frequency and pointing int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode OpenMessages("HIFI Spectral Scan - Load Chop noRef",{data_time,0,0,0,0,0,0,n_freq_point,n_cycles,load_interval}); // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,redundancy,wbs1Used,wbs2Used,data_time); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; ////////////////////////////////////////////////////////////////////// // Call first part of the timing computer {{int,int,int,int,int,int,bool,int,int},{int,double,double[],int[][],bool,double[],int,bool}} pre_timing = SScanLoadChopNoRef_pre_timing(band,lo_freq,lo_freq_up,redundancy,effResolution,hr1,hr2,wb1,wb2,data_time,n_cycles,n_freq_point,load_interval,docommands); // frequency parameters int groupnumber = pre_timing{1}{0}; double reffreq = pre_timing{1}{1}; double[] freqgrid = pre_timing{1}{2}; int[][] grouporder = pre_timing{1}{3}; bool retuning = pre_timing{1}{4}; double[] targetlevels = pre_timing{1}{5}; int nfreq_if = pre_timing{1}{6}; bool dsb = pre_timing{1}{7}; ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,double,double,int} tpar = Fine_telescope(naifid,onPosition,band,reffreq,pre_timing{0}); // Dummy call to spacecraft command int[] telescopetimes = basic_fine_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9}); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,bool,int,int},double,double} post_timing = SScanChopNoRef_post_timing(pre_timing{0},telescopetimes); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = Fine_telescope(naifid,onPosition,band,reffreq,post_timing{1}); // Call telescope command telescopetimes = basic_fine_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9}); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following // normal pre_timing values int loadlength = post_timing{1}{2}; int n_per_on = post_timing{1}{4}; int n_load_on = post_timing{1}{5}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { SScanLoadChopNoRef_commanding(band,reffreq,effResolution,hr1,hr2,wb1,wb2,n_freq_point,grouporder,freqgrid,retuning,targetlevels,data_time,n_per_on,n_load_on,groupnumber,startobs,telescopetimes,loadlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double} tact = SingleChop_deadtimes("lchop",band,reffreq,hr1,hr2,wb1,wb2,data_time,n_per_on); double tscan = 2.0 * (tact{1} + tact{2}); double tdead = 2.0 * tact{2}; // // Call noise computer {double,double,double,double,double} noisevalues = SScanChopNoRef_noisecomputer(band,reffreq,nfreq_if,dsb,effResolution,n_per_on * imax(n_load_on,1),false,tscan,tdead); // Evaluate performance SScanChopNoRef_performance(band,reffreq,nfreq_if,dsb,effResolution,noisevalues,timeTaken,n_per_on * imax(n_load_on,1),groupnumber * n_freq_point,false,tscan,tdead); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } //////////////////////////////////// // Top-level procedures //////////////////////////////////// //HIFI-COP-X-FastImix: 21Hz oscillation investigation procedure Fast_Imix_proc_ops { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string polarization = "B" in ["H","V","B"]; //mixer to be sampled: H, V or B. If B, they are done successively int milliSecSample = 3; // interval between samples int samplesBefore = 30 in [0,50]; int samplesAfter = 1000 in [0,1000]; }{ //Need a representative frequency: take keyfreq double[] result_d = CalibrationReader("name_keyfreq",["keyfreq"],band,0.0); double lo_freq = result_d[0]; //First measurement without LO //Force LO swith-off LCU_switch_off_block_fm(); //FPU configuration Init_MSA_HBB_fm(band,"CLOSE",lo_freq,"ON"); //For HEBs, set bias to 3mV if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { {double,string}[] result = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,lo_freq); Mixerbias_block_fm(result[0]{0},result[1]{0}); result = ConfigurationReader("name_confilfpu",["bias_dipscan_h","bias_dipscan_v"],band,lo_freq); Mixerbias_block_fm(result[0]{0},result[1]{0}); } //Fast measurement Fast_Imix_block_fm(band,polarization,milliSecSample,samplesBefore,samplesAfter); //Second measurement with LO LCU_switchon_proc_fm(band); //Wait an extra delay of 1 min for short term stabilization delay(60); //For HEBs, set bias back to nominal if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { result = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,lo_freq); Mixerbias_block_fm(result[0]{0},result[1]{0}); result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); Mixerbias_block_fm(result[0]{0},result[1]{0}); } //LO tuning LO_tuning_block_fm(band,lo_freq); //Fast measurement Fast_Imix_block_fm(band,polarization,milliSecSample,samplesBefore,samplesAfter); } ///////////////////////////////////////////////////////////////// // Procedure to compute total dead times for the mode // {double,double,double} procedure DBSRaster_deadtimes { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // data dump interval int n_chop = 3; // number of chop cycles in one integration int n_load = 0; // number of integrations in one pointing phase int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase double tdead = 10.0; // Dead time from telescope }{ ////////////////////////////////////////////////////////////////////// // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Special meaning of n_load here if(n_load == 0) { int n_seq = 1; } else { n_seq = n_load; } // Compute parameters for the instrument timing {double,double} tinst = GetInstDeadSlowChop(data_time,2 * n_chop,"chop",band,lo_freq,backendreadoutparms); // dead time double tdeadint = double(data_time * 2 * n_chop) - tinst{0}; // subtract dead times in switches // keep dead times between A-A and B-B in total dead time tdeadint = tdeadint - double(n_chop) * tinst{1}; // Total dead time per cycle, only one point still not covered double tdead_tot = tdead + double(2 * n_seq) * tdeadint; // Integration time double tphaseint = tinst{0} / double(2 * n_chop); return {tdead_tot,tphaseint,tinst{1}}; } //HIFI LO tuning for FSW and no cases, block //Settings for both frequencies need to be common //and are passed through lo_freq_setting //Target current is read from look-up table block LO_tuning_block_aot HIFI 6616 { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978.2; //LO frequency at which to set LSU double lo_freq_setting = 978.3; //LO frequency at which to take the settings string mixer_polarization = "H" in ["H","V","B"]; //The polarization to be used for the tuning bool clearflags = true; // whether to reset LCU bool newsetting = true; // whether LSU/LOU parameters are new bool fswstorage = true; // whether FSW register shall be stored }{ //Store rest frequency double rest_lofreq = lo_freq; //LO frequency uncorrected from VelCorr double rest_lofreq_setting = lo_freq_setting; // Perform radial velocity correction lo_freq = VelCorrFreq(rest_lofreq); lo_freq_setting = VelCorrFreq(rest_lofreq_setting); //Get target mixer current {double,string}[] result = ConfigurationReader("name_confilmix",["target_mx_c_h","target_mx_c_v"],band,lo_freq); double target_current = result[0]{0}; if(mixer_polarization == "V") { target_current = result[1]{0}; } if(mixer_polarization == "B") { target_current = 0.5 * (result[1]{0} + result[0]{0}); } // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; name_configlcutune = "name_configlcutune_b"; } // result = ConfigurationReader(name_configlotune,["step_drain2_v","nsteps","step_time"],band,lo_freq); double step_drain2_v = result[0]{0}; int nsteps = iround(result[1]{0}); double step_time = result[2]{0}; // result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq_setting); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v_start = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // //Adjust scan cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,rest_lofreq); double drain2_safe = cresult[0]; // double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); // //For all bands, scan will be done with decreasing drain2 voltages //The best guess is taken from look-up table double tune_range = 0.1; result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lo_freq); double v_d2 = result[0]{0}; drain2_v_start = min(v_d2 * (1.0 + tune_range / 2.0),drain2_bluemax); double drain2_v_end = (1.0 - tune_range / 2.0) / (1.0 + tune_range / 2.0) * drain2_v_start; step_drain2_v = (drain2_v_end - drain2_v_start) / double(nsteps - 1); // //Recovey from potential failure mode if(clearflags) { Set_LO_Nominal_proc_aot(); } // // Commanding of new parameters only if needed if(newsetting) { // Get all parameters needed to compute config_lo_delay in Configure_LCU // //Compute largest delay possible anticipating worst redshift // Maximum redshift given by maximum accepted radial velocity // Needs to be compliant with code in VelCorr // maxredshift=1 + 30.7km/s / 299999.6km/s; double maxredshift = 1.0001023; double drain2_bluemax_lowredshift = Get_BLUE_LIMIT_D2_proc_fm(band,rest_lofreq / maxredshift); result = ConfigurationReader(name_configlcutune,["drain2_v"],band,rest_lofreq / maxredshift); double drain2_lowredshift = min(result[0]{0} * (1.0 + tune_range / 2.0),drain2_bluemax_lowredshift); double drain2_bluemax_highredshift = Get_BLUE_LIMIT_D2_proc_fm(band,rest_lofreq * maxredshift); result = ConfigurationReader(name_configlcutune,["drain2_v"],band,rest_lofreq * maxredshift); double drain2_highredshift = min(result[0]{0} * (1.0 + tune_range / 2.0),drain2_bluemax_highredshift); // // Finally get config_lo_delay result = ConfigurationReader("name_delays",["lock_lo_delay","vd2_rampup_speed"],band,rest_lofreq); int config_lo_delay = iceil(result[0]{0} + (max(drain2_lowredshift,drain2_highredshift) - drain2_safe) / result[1]{0}); // //Send command HIFI_Configure_LCU_proc_aot(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,macro_checksum,config_lo_delay); // //TM page dump and error flag clearance now contained in the above proc } // //Load vector scan //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Load_vector_safe_1a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "1b") { //Band 1b Hifi_HIFI_Load_vector_safe_1b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2a") { //Band 2a Hifi_HIFI_Load_vector_safe_2a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2b") { //Band 2b Hifi_HIFI_Load_vector_safe_2b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3a") { //Band 3a Hifi_HIFI_Load_vector_safe_3a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3b") { //Band 3b Hifi_HIFI_Load_vector_nom_3b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "4a") { //Band 4a Hifi_HIFI_Load_vector_safe_4a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "4b") { //Band 4b Hifi_HIFI_Load_vector_safe_4b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "5a") { //Band 5a Hifi_HIFI_Load_vector_nom_5a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "5b") { //Band 5b Hifi_HIFI_Load_vector_nom_5b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6a") { //Band 6a Hifi_HIFI_Load_vector_nom_6a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6b") { //Band 6b Hifi_HIFI_Load_vector_nom_6b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7a") { //Band 7a Hifi_HIFI_Load_vector_nom_7a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7b") { //Band 7b Hifi_HIFI_Load_vector_nom_7b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } // //Execute tuning: check which mixer is to be used if(mixer_polarization == "V") { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCV($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCV($BBID,target_current); } } else { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCH($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCH($BBID,target_current); } } // double time_needed = double(nsteps) * step_time; delay(iround(time_needed + 2.0 + 0.5)); //0.5s added for completion of load_vector // //Store settings into available register if(fswstorage) { HIFI_HL_store_tm_proc_fm(); } // //Read TM pages and clear error flags after vector scan LCU_Read_TM_pages_proc_aot(); } //HIFI-COP-7-EngInv: Investigation time - placeholder for planning obs HifiEng_EngInv_COP { int test_duration = 3600; //duration in seconds }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(EngInv_COP_proc_ops(test_duration)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution EngInv_COP_proc_ops(test_duration); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } // Wait a given time, procedure // procedure Wait_proc_fm { int wait_time = 100; //Time to wait, in seconds }{ delay(wait_time); } // Stability test, procedure, IF system procedure Proc_stability_IF_system { string band = "1a"; // HIFI band int n = 100; //Number of load pairs to be measured string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code string mixer_polarization = "B" in ["H","V","B"]; //Polarization: H, V, or both (B) int integ_time = 4; //Total integration time in sec. to be set at end of test string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast double mixer_bias = 8.0; //Mixer bias to be set during stability measurement }{ //Do not switch-off LO, rather, use the 3b-dissipative mode //LCU_switch_off_block_fm(); string band_dissipate = "3b"; double lofreq_dissipate = 958.0; double[] cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band_dissipate,lofreq_dissipate); double drain2_v = cresult[0]; LCU_config_nominal_w_D2_proc_fm(band_dissipate,lofreq_dissipate,drain2_v); // Put heaters explicitly to 4 V HL_heater_block_aot(band_dissipate,"nominal"); //Sets FPU with both IF on Init_all_IF_fm(band,mixer_polarization); // //Set mixer bias to 10mV for backend tuning prior to IF noise measurement {double,string}[] result = ConfigurationReader("name_confilfpu",["bias_medium_resistive_h","bias_medium_resistive_v","bias_low_resistive_h","bias_low_resistive_v","bias_high_resistive_h","bias_high_resistive_h"],band,0.0); // double bias_medium_h = result[0]{0}; double bias_medium_v = result[1]{0}; double bias_low_h = result[2]{0}; double bias_low_v = result[3]{0}; double bias_high_h = result[4]{0}; double bias_high_v = result[5]{0}; //Set magnets to 0 Set_Magnet_current_block_fm(0.0,0.0); // Mixerbias(bias_high_h,bias_high_v); // //WBS calibration if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_config_block_fm(band); WBS_calib_fm(band); WBS_tune_proc_fm(band); } if(backend == "hrs" || backend == "both" || backend == "hrsFast") { //Configure backends to max. attenuation HRS_config_block_fm(band,hrs_mode); HRS_tune_block_fm(band); } // //Configure spectrometers integration to default Configure_Spectrometer_proc_fm(band,4,hrs_mode,backend); //Measure IF noise with high and low resistive bias Spectra_resistive_high_fm(band,bias_high_h,bias_high_v,4,"both"); Spectra_resistive_low_fm(band,bias_low_h,bias_low_v,4,"both"); // //Set to 8mV bias and do stability measurement //Mixerbias (bias_medium_h,bias_medium_v) ; //Now sets to user input bias Mixerbias(mixer_bias,mixer_bias); Stability_IF_system_fm(band,n,integ_time,backend,hrs_mode); //Configure spectrometers integration back to default Configure_Spectrometer_proc_fm(band,4,hrs_mode,backend); //Set magnets back to nominal //Need a representative frequency: take keyfreq double[] result_d = CalibrationReader("name_keyfreq",["keyfreq"],band,0.0); double lo_freq = result_d[0]; // //Bias to nominal first - SPR-2579 result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); Mixerbias(result[0]{0},result[1]{0}); result = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); Set_Magnet_current_proc_fm(result[0]{0},result[1]{0}); // } //Notify PDU status ON, procedure //I assume all S/S are present procedure HIFI_notify_PDU_status_on_proc_ops { string status_FCU = "ON" in ["ON","OFF"]; //Status of FCU string status_LCU = "ON" in ["ON","OFF"]; //Status of LCU string status_WBSV = "ON" in ["ON","OFF"]; //Status of WBSV string status_WBSH = "ON" in ["ON","OFF"]; //Status of WBSH string status_HRSV = "ON" in ["ON","OFF"]; //Status of HRSV string status_HRSH = "ON" in ["ON","OFF"]; //Status of HRSH string apply_to_subsystem = "FCU" in ["FCU","LCU","WBSH","WBSV","HRSH","HRSV","ALL"]; }{ Hifi_HIFI_notify_PDU_status(status_FCU,status_LCU,status_WBSV,status_WBSH,status_HRSV,status_HRSH); delay(1); //Prepare message for operator: we will check whether one particular HK is ON if(status_FCU == "ON") { string subsyst_on = "HI_FCU_S"; } if(status_WBSH == "ON") { subsyst_on = "HI_WBSH_S"; } if(status_WBSV == "ON") { subsyst_on = "HI_WBSV_S"; } if(status_HRSH == "ON") { subsyst_on = "HI_HRSH_S"; } if(status_HRSV == "ON") { subsyst_on = "HI_HRSV_S"; } if(status_LCU == "ON") { subsyst_on = "HI_LCU_S"; } mois_tmcheck("Check that the HK parameter " + subsyst_on + " is ON."); // //Specific S/S check after switch on if(apply_to_subsystem == "FCU" || apply_to_subsystem == "ALL") { //check OBS version {double,string}[] result = ConfigurationReader("name_delays",["hi_sw_version","hi_sw_revision","hi_sw_patch"],"0",0.0); int hi_sw_version = iround(result[0]{0}); int hi_sw_revision = iround(result[1]{0}); int hi_sw_patch = iround(result[2]{0}); mois_tmcheck("Check that HI_SW_Version is " + hi_sw_version); mois_tmcheck("Check that HI_SW_Revision is " + hi_sw_revision); mois_tmcheck("Check that HI_SW_Patch is " + hi_sw_patch); } if(apply_to_subsystem == "WBSH" || apply_to_subsystem == "ALL") { //This is now done at end of procedure as instrument mode status check //mois_tmcheck("Check that both parameters HWH_Laser1_S and HWH_Laser2_S are OFF"); //mois_tmcheck("Check that parameter HWH_Zero_S is ON"); //mois_tmcheck("Check that parameter HWH_IN_ATT is set to 15, and parameters HWH_Band_1_ATT, HWH_Band_2_ATT, HWH_Band_3_ATT, HWH_Band_4_ATT are set to 7"); } if(apply_to_subsystem == "WBSV" || apply_to_subsystem == "ALL") { //This is now done at end of procedure as instrument mode status check //mois_tmcheck("Check that both parameters HWV_Laser1_S and HWV_Laser2_S are OFF"); //mois_tmcheck("Check that parameter HWV_Zero_S is ON"); //mois_tmcheck("Check that parameter HWV_IN_ATT is set to 15, and parameters HWV_Band_1_ATT, HWV_Band_2_ATT, HWV_Band_3_ATT, HWV_Band_4_ATT are set to 7"); } if(apply_to_subsystem == "HRSH" || apply_to_subsystem == "ALL") { //This is now done at end of procedure as instrument mode status check //mois_tmcheck("Check that parameters HRH_1U_ATT, HRH_1L_ATT, HRH_2U_ATT, HRH_2L_ATT, HRH_3U_ATT, HRH_3L_ATT, HRH_4U_ATT and HRH_4L_ATT are set to 15.5"); } if(apply_to_subsystem == "HRSV" || apply_to_subsystem == "ALL") { //This is now done at end of procedure as instrument mode status check //mois_tmcheck("Check that parameters HRV_1U_ATT, HRV_1L_ATT, HRV_2U_ATT, HRV_2L_ATT, HRV_3U_ATT, HRV_3L_ATT, HRV_4U_ATT and HRV_4L_ATT are set to 15.5"); } if(apply_to_subsystem == "LCU" || apply_to_subsystem == "ALL") { //This is now done at end of procedure as instrument mode status check //mois_tmcheck("Check that parameter HL_MODE_S is standby"); //mois_tmcheck("Check that parameter HL_Channel_S is OFF"); } } // HRS linearity check, loop on individual attenuators, mode // The WBS attenuators are also changed at the same time // ======================================================= block HRS_linearity_indiv_block_fm HIFI 3660 { string band = "1a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int integ_time = 4; //Total integration time in sec. string laser_H = "Laser1" in ["Laser1","Laser2"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2"]; //WBS-V laser to be set ON string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); //Fetch resistive bias {double,string}[] result = ConfigurationReader("name_confilfpu",["bias_high_resistive_h","bias_high_resistive_v","bias_medium_resistive_h","bias_medium_resistive_v"],band,0.0); // double bias_high_h = result[0]{0}; double bias_high_v = result[1]{0}; double bias_medium_h = result[2]{0}; double bias_medium_v = result[3]{0}; int repeats = 32; double hrsH_attenuators_value = 15.5; double hrsV_attenuators_value = 15.5; //Test will be done in WB mode for both polar string hrsh_blocks_configuration = "corr_wide"; string hrsv_blocks_configuration = "corr_wide"; // Configure spectroscopy Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); // // Configure blocks //================= //H-polar Hifi_HIFI_Config_HRS_H_blocks($BBID,hrsh_blocks_configuration,hrsh_blocks_configuration,hrsh_blocks_configuration,hrsh_blocks_configuration,hrsh_blocks_configuration,hrsh_blocks_configuration,hrsh_blocks_configuration,hrsh_blocks_configuration); // //delay(1); //V-polar Hifi_HIFI_Config_HRS_V_blocks($BBID,hrsv_blocks_configuration,hrsv_blocks_configuration,hrsv_blocks_configuration,hrsv_blocks_configuration,hrsv_blocks_configuration,hrsv_blocks_configuration,hrsv_blocks_configuration,hrsv_blocks_configuration); // delay(1); // Fetch internal LO settings //=========================== //H-polar string hrs_filename_h = "name_confighrs_" + hrs_mode[0]; result = ConfigurationReader(hrs_filename_h,["hrh_switch","hrh_up_ol1","hrh_up_ol2","hrh_up_ol3","hrh_up_ol4","hrh_down_ol5","hrh_down_ol6","hrh_down_ol7"],band,0.0); double[] hrsH_LO = [result[1]{0},result[2]{0},result[3]{0},result[4]{0},result[5]{0},result[6]{0},result[7]{0}]; string hrs_polarization_h = result[0]{1}; //V-polar string hrs_filename_v = "name_confighrs_" + hrs_mode[1]; result = ConfigurationReader(hrs_filename_v,["hrv_switch","hrv_up_ol1","hrv_up_ol2","hrv_up_ol3","hrv_up_ol4","hrv_down_ol5","hrv_down_ol6","hrv_down_ol7"],band,0.0); double[] hrsV_LO = [result[1]{0},result[2]{0},result[3]{0},result[4]{0},result[5]{0},result[6]{0},result[7]{0}]; string hrs_polarization_v = result[0]{1}; // //Convert IF frequencies into A and M parameters //Truncate wb or hr keyword: string[] output_hrs_mode = GetHrsMode_proc_fm(hrs_mode); string hrs_mode_h = output_hrs_mode[0]; string hrs_mode_v = output_hrs_mode[1]; // int[] a_m_parameter = ComputeA_M_parameters([hrs_mode_h,hrs_mode_v],hrsH_LO[0],hrsH_LO[1],hrsH_LO[2],hrsH_LO[3],hrsH_LO[4],hrsH_LO[5],hrsH_LO[6],hrsV_LO[0],hrsV_LO[1],hrsV_LO[2],hrsV_LO[3],hrsV_LO[4],hrsV_LO[5],hrsV_LO[6]); // //H-polar int hrsH_LO1_M = a_m_parameter[1]; int hrsH_LO1_A = a_m_parameter[0]; int hrsH_LO2_M = a_m_parameter[3]; int hrsH_LO2_A = a_m_parameter[2]; int hrsH_LO3_M = a_m_parameter[5]; int hrsH_LO3_A = a_m_parameter[4]; int hrsH_LO4_M = a_m_parameter[7]; int hrsH_LO4_A = a_m_parameter[6]; int hrsH_LO5_M = a_m_parameter[9]; int hrsH_LO5_A = a_m_parameter[8]; int hrsH_LO6_M = a_m_parameter[11]; int hrsH_LO6_A = a_m_parameter[10]; int hrsH_LO7_M = a_m_parameter[12]; //V-polar int hrsV_LO1_M = a_m_parameter[14]; int hrsV_LO1_A = a_m_parameter[13]; int hrsV_LO2_M = a_m_parameter[16]; int hrsV_LO2_A = a_m_parameter[15]; int hrsV_LO3_M = a_m_parameter[18]; int hrsV_LO3_A = a_m_parameter[17]; int hrsV_LO4_M = a_m_parameter[20]; int hrsV_LO4_A = a_m_parameter[19]; int hrsV_LO5_M = a_m_parameter[22]; int hrsV_LO5_A = a_m_parameter[21]; int hrsV_LO6_M = a_m_parameter[24]; int hrsV_LO6_A = a_m_parameter[23]; int hrsV_LO7_M = a_m_parameter[25]; // /////////////////////////////////////// //Now prepare WBS //Set zero and comb off Hifi_HIFI_Single_cmd($BBID,"HWH_ZERO_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWV_ZERO_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWH_COMB_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWV_COMB_OFF"); delay(2); // //Initial configuration: overall attenuators set to max., individual attenuators to 0 //H-Polarization // result = ConfigurationReader("name_configwbs",["hwh_heater","hwh_latchup_s"],band,0.0); string hwh_laser1_s = "OFF"; string hwh_laser2_s = "OFF"; if(laser_H == "Laser1") { hwh_laser1_s = "ON"; } if(laser_H == "Laser2") { hwh_laser2_s = "ON"; } int hwh_heater = iround(result[0]{0}); string hwh_latchup_s = result[1]{1}; int hwh_att_band4 = 0; int hwh_att_band3 = 0; int hwh_att_band2 = 0; int hwh_att_band1 = 0; int hwh_att_in = 15; // result = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result[0]{0}); // //V-Polarization // result = ConfigurationReader("name_configwbs",["hwh_heater","hwh_latchup_s"],band,0.0); string hwv_laser1_s = "OFF"; string hwv_laser2_s = "OFF"; if(laser_V == "Laser1") { hwv_laser1_s = "ON"; } if(laser_V == "Laser2") { hwv_laser2_s = "ON"; } int hwv_heater = iround(result[0]{0}); string hwv_latchup_s = result[1]{1}; int hwv_att_band4 = 0; int hwv_att_band3 = 0; int hwv_att_band2 = 0; int hwv_att_band1 = 0; int hwv_att_in = 15; // // Loops on the different configurations of the HRS attenuators //=============================================== //Magnets shall be set to 0 since high biases will be used Set_Magnet_current_proc_fm(0.0,0.0); // for(int i = 0 .. repeats - 1) { // Configure attenuators and LO //============================= Hifi_HIFI_Config_HRS_H_att_lo($BBID,hrs_polarization_h,hrsH_attenuators_value,hrsH_attenuators_value,hrsH_attenuators_value,hrsH_attenuators_value,hrsH_attenuators_value,hrsH_attenuators_value,hrsH_attenuators_value,hrsH_attenuators_value,hrsH_LO1_M,hrsH_LO1_A,hrsH_LO2_M,hrsH_LO2_A,hrsH_LO3_M,hrsH_LO3_A,hrsH_LO4_M,hrsH_LO4_A,hrsH_LO5_M,hrsH_LO5_A,hrsH_LO6_M,hrsH_LO6_A,hrsH_LO7_M); // //delay(2); Hifi_HIFI_Config_HRS_V_att_lo($BBID,hrs_polarization_v,hrsH_attenuators_value,hrsV_attenuators_value,hrsV_attenuators_value,hrsV_attenuators_value,hrsV_attenuators_value,hrsV_attenuators_value,hrsV_attenuators_value,hrsV_attenuators_value,hrsV_LO1_M,hrsV_LO1_A,hrsV_LO2_M,hrsV_LO2_A,hrsV_LO3_M,hrsV_LO3_A,hrsV_LO4_M,hrsV_LO4_A,hrsV_LO5_M,hrsV_LO5_A,hrsV_LO6_M,hrsV_LO6_A,hrsV_LO7_M); // delay(1); /////////////////////// //Configure WBS Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); //delay(wbs_config_delay); // Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); delay(wbs_config_delay); // //Set the shot noise to high resistive bias Mixerbias(bias_high_h,bias_high_v); // Take spectrum //============== HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // // //Set the shot noise to medium resistive bias Mixerbias(bias_medium_h,bias_medium_v); // Take spectrum //============== HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // // Change the value of the 8 attenuators //====================================== hrsH_attenuators_value = hrsH_attenuators_value - 0.5; hrsV_attenuators_value = hrsV_attenuators_value - 0.5; // Change the value of the main WBS attenuator: //============================================ if(hwh_att_in > 0) { hwh_att_in = hwh_att_in - 1; hwv_att_in = hwv_att_in - 1; } else { hwh_att_in = 0; hwv_att_in = 0; } } //Set magnets back to normal settings //Need a representative frequency: take keyfreq double[] result_d = CalibrationReader("name_keyfreq",["keyfreq"],band,0.0); double lo_freq = result_d[0]; // result = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); Set_Magnet_current_proc_fm(result[0]{0},result[1]{0}); // } //Peak up simulation in ILT, procedure //Shutter is used to partially blind external BB load procedure Peakup_test_proc_fm { int band = 1 in [1,7]; // HIFI band string backend = "hrs" in ["hrs","wbs"]; //Backend in use: hrs or wbs int integ_time = 2; //Total integration time in sec. string mixer_polarization = "H" in ["H","V"]; //mixer polarization to be used string peakup_matrix = "centred" in ["centred","offseted","flat"]; //Which brightness distribution to simulate with shutter: centred, offseted, flat }{ string band_nb = "" + band + "a"; //Configure backend in total power int[] res = Configure_Spectrometer_peakup_proc_fm(band_nb,integ_time,["wb1","wb1"],backend,mixer_polarization); int total_time = res[0] * res[1]; if(backend == "wbs") { WBS_config_block_fm(band_nb); WBS_tune_proc_fm(band_nb); } //If HRS need to provide IF input power if(backend == "hrs") { double[] deflofreq = [522.0,652.0,807.0,979.0,1152.0,1520.0,1746.0]; Init_MSA_fm(band_nb,"CLOSE",deflofreq[band - 1],"ON"); //Set mixer bias to 5mV {double,string}[] result = ConfigurationReader("name_confilfpu",["bias_low_resistive_h","bias_low_resistive_v"],band_nb,0.0); // double bias_low_h = result[0]{0}; double bias_low_v = result[1]{0}; //Set magnets to 0 Set_Magnet_current_block_fm(0.0,0.0); // Mixerbias(bias_low_h,bias_low_v); } //configure peak-up aquisition mode Peakup_test_configure_block_fm("" + band + "",mixer_polarization); //trigger measurement at all 9 positions Peakup_test_acquire_data_block_fm("" + band + "",backend,total_time,peakup_matrix,mixer_polarization); // } //Set LCU3b back to standby status, procedure procedure LCU3b_standby_proc_fm { string band = "3b"; // HIFI band double lo_freq = 900.0 in [852.0,953.0]; //LO frequency }{ error("This module is obsolete: use LCU_standby_proc_fm instead"); } // Procedure for zero and comb measurement // Collects all common parts for LoadMeasurement and DoubleLoadMeasurement // procedure ZeroCombMeasurement { string band = "4a"; // HIFI band (needed to estimate stabilization) double lo_freq = 978200.0; // LO frequency int used_datatime = 4; // time between subsequent data readouts in load {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // Readout parameters for HRS1,HRS2, WBS1,WBS2 }{ // Usage of WBS bool wbs1used = backendreadoutparms{2}{0}; bool wbs2used = backendreadoutparms{3}{0}; // Zero and Comb measurement is only used in WBS observations if(wbs1used || wbs2used) { // Now start the zero-comb measurement int danglingreadout = WBS_Zero_Comb(band,lo_freq); // Add possible delay needed before next zero measurement if(used_datatime < danglingreadout) { delay(danglingreadout - used_datatime); } // Perform the first zero measurement with the settings of the // regular observations // // I use the optimistic approach to completely omit this step now // danglingreadout=WBS_Full_Zero(band,lo_freq,used_datatime, // backendreadoutparms); // // Add possible delay needed before hot-cold measurement // if (used_datatime < danglingreadout) { // delay(danglingreadout-used_datatime); // } } } {string,double,double}[] procedure HifiMappingModeFastDBSRasterSequencerInit { string modeName = "raster"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 10 in [4,80]; // data dump interval int n_int_on = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_switch_on = 1 in [1,1800]; // number of data transfer cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Get the drift parameters to compute the drift noise {double,double} phaselengths = DBSPhaseLengths(band,lo_freq,effResolution,continuumDetection,oneGHzReference); // Compute derived quantities // Top down approach here int main_phase = iceil(phaselengths{0}); // Arbitrary selection of data_time int data_time_guess = 20; // Combine points for n_switch=1 int n_pointsperscan_guess = imin(imax(main_phase / data_time_guess,1),npoints * nlines); int n_pointsperscan_range = 1 - n_pointsperscan_guess; if(n_pointsperscan_range == 0) { n_pointsperscan_range = 1; } // remaining part for n_switch int n_switch_on_guess = main_phase / (n_pointsperscan_guess * data_time_guess) + 1; data_time_guess = main_phase / (n_pointsperscan_guess * n_switch_on_guess); // Check with data rate {int,double[]} dataparms = DataTaking(backendreadoutparms,8); int datalimit = 2 * dataparms{0}; if(data_time_guess < datalimit) { data_time_guess = datalimit; n_switch_on_guess = 1; } int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } // Chop phase length double phase_min = min(max(phaselengths{1},0.15),1.5); int n_int_on_guess = ifloor(double(data_time_guess) / (2.0 * phase_min)); int n_int_on_range = -n_int_on_guess / 2; if(n_int_on_range == 0) { n_int_on_range = 1; } // Add pointing requirements condition: >=10s {int,int} new_data_time = MatchMinPointing(data_time_guess,data_time_range,n_switch_on_guess); data_time_guess = new_data_time{0}; data_time_range = new_data_time{1}; // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"n_int_on",double(n_int_on_guess),double(n_int_on_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)},{"n_pointsperscan",double(n_pointsperscan_guess),double(n_pointsperscan_range)}]; return retvalues; } // Load OBSW in intermediate mode, mode mode HifiManCmd_load_OBSW { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! }{ Mode_status_check_intermediate(); StartMode_block_ops(); mois_comment("Start loading of a new OBSW in standby-1 mode"); Load_OBSW_block_ops(); StopMode_block_ops(); } /////////////////////////////////////////////////////// // Generic procedures to configure various S/S in HIFI //Configure FPU at frequency of interest: // - set nominal bias, magnet currents and diplexer currents // - set IF amp. to nominal // - look at internal HBB // - set chopper parameter, use of CLOSED loop // - checks whether one of the polarization is not used // - DT 250707: added code to allow LO band switch on // //Configure FPU procedure ConfigureFPU { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz bool power_fcu = true; //whether needs full FPU configuration (true) or just freq-dependent adjustement (false) }{ //We always setup both polarizations although one of them may not be used //This has only effect on data readouts, not on hardware settings Init_MSA_aot(band,"CLOSE",lo_freq / 1000.0,power_fcu,"ON"); } // Check of Bragg cell heating using internal attenuators, block block FT_WBS_BraggCell_att_fm HIFI 3711 { string band = "1a"; // HIFI band string laser_H = "Laser1" in ["Laser1","Laser2"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2"]; //WBS-V laser to be set ON int[] att_h = [7,7,7,7,12]; //User input att. for optimum level H-polar: DO A TUNING FIRST ! int[] att_v = [7,7,7,7,12]; //User input att. for optimum level V-polar: DO A TUNING FIRST ! int integ_time = 4; //Total integration time in sec. string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); // //Test continuum signal response //1. Set WBS attenuators to work at nominal level //for the current input (minimum attenuation without saturation) //It practice the CUS cannot read back the optimum settings from //a tuning...instead we consider they are input //We assume the test is done after a tuning. //Must be done manually... // {double,string}[] result = ConfigurationReader("name_configwbs",["hwh_laser1_s","hwh_laser2_s","hwh_heater","hwh_latchup_s","hwh_att_band4","hwh_att_band3","hwh_att_band2","hwh_att_band1","hwh_att_in"],band,0.0); string hwh_laser1_s = "OFF"; string hwh_laser2_s = "OFF"; if(laser_H == "Laser1") { hwh_laser1_s = "ON"; } if(laser_H == "Laser2") { hwh_laser2_s = "ON"; } int hwh_heater = iround(result[2]{0}); string hwh_latchup_s = result[3]{1}; int hwh_att_band4 = att_h[3]; //iround(result[4]{0}); int hwh_att_band3 = att_h[2]; //iround(result[5]{0}); int hwh_att_band2 = att_h[1]; //iround(result[6]{0}); int hwh_att_band1 = att_h[0]; //iround(result[7]{0}); int hwh_att_in = att_h[4]; //iround(result[8]{0}); // result = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result[0]{0}); // result = ConfigurationReader("name_configwbs",["hwv_laser1_s","hwv_laser2_s","hwv_heater","hwv_latchup_s","hwv_att_band4","hwv_att_band3","hwv_att_band2","hwv_att_band1","hwv_att_in"],band,0.0); string hwv_laser1_s = "OFF"; string hwv_laser2_s = "OFF"; if(laser_V == "Laser1") { hwv_laser1_s = "ON"; } if(laser_V == "Laser2") { hwv_laser2_s = "ON"; } int hwv_heater = iround(result[2]{0}); string hwv_latchup_s = result[3]{1}; int hwv_att_band4 = att_v[3]; //iround(result[4]{0}); int hwv_att_band3 = att_v[2]; //iround(result[5]{0}); int hwv_att_band2 = att_v[1]; //iround(result[6]{0}); int hwv_att_band1 = att_v[0]; //iround(result[7]{0}); int hwv_att_in = att_v[4]; //iround(result[8]{0}); // //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // delay(wbs_config_delay); //Wait for configuration to be applied // //2. Configure spectroscopy and do integration: total of 100s with 4s integration Total_power_spectro_for_Stability_proc_fm(band,25,4,backend,["wb1","wb1"]); // //Increase main attenuator by 3 dB hwh_att_in = hwh_att_in + 3; hwv_att_in = hwv_att_in + 3; //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // delay(wbs_config_delay); //Wait for configuration to be applied // //Integrate with the WBS Total_power_spectro_for_Stability_proc_fm(band,25,4,backend,["wb1","wb1"]); // //Decrease main attenuator again by 3 dB hwh_att_in = hwh_att_in - 3; hwv_att_in = hwv_att_in - 3; //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // delay(wbs_config_delay); //Wait for configuration to be applied // //Integrate with the WBS Total_power_spectro_for_Stability_proc_fm(band,25,4,backend,["wb1","wb1"]); // //Increase main attenuator again by 3 dB hwh_att_in = hwh_att_in + 3; hwv_att_in = hwv_att_in + 3; //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // delay(wbs_config_delay); //Wait for configuration to be applied // //Integrate with the WBS Total_power_spectro_for_Stability_proc_fm(band,25,4,backend,["wb1","wb1"]); // //Settling time of COMB //We have to set attenuators to values different from max. //12,3,3,3,3: info from Oliver Sibertz. This may change for FM //Initial configuration //H-Polarization result = ConfigurationReader("name_configwbs",["hwh_laser1_s","hwh_laser2_s","hwh_heater","hwh_latchup_s","hwh_att_band4_comb","hwh_att_band3_comb","hwh_att_band2_comb","hwh_att_band1_comb","hwh_att_in_comb"],band,0.0); hwh_laser1_s = "OFF"; hwh_laser2_s = "OFF"; if(laser_H == "Laser1") { hwh_laser1_s = "ON"; } if(laser_H == "Laser2") { hwh_laser2_s = "ON"; } hwh_heater = iround(result[2]{0}); hwh_latchup_s = result[3]{1}; hwh_att_band4 = iround(result[4]{0}); hwh_att_band3 = iround(result[5]{0}); hwh_att_band2 = iround(result[6]{0}); hwh_att_band1 = iround(result[7]{0}); hwh_att_in = iround(result[8]{0}); // //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); // delay(wbs_config_delay); //Wait for configuration to be applied // //V-Polarization // result = ConfigurationReader("name_configwbs",["hwv_laser1_s","hwv_laser2_s","hwv_heater","hwv_latchup_s","hwv_att_band4_comb","hwv_att_band3_comb","hwv_att_band2_comb","hwv_att_band1_comb","hwv_att_in_comb"],band,0.0); hwv_laser1_s = "OFF"; hwv_laser2_s = "OFF"; if(laser_V == "Laser1") { hwv_laser1_s = "ON"; } if(laser_V == "Laser2") { hwv_laser2_s = "ON"; } hwv_heater = iround(result[2]{0}); hwv_latchup_s = result[3]{1}; hwv_att_band4 = iround(result[4]{0}); hwv_att_band3 = iround(result[5]{0}); hwv_att_band2 = iround(result[6]{0}); hwv_att_band1 = iround(result[7]{0}); hwv_att_in = iround(result[8]{0}); // //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // delay(wbs_config_delay); //Wait for configuration to be applied // //Set Zero and COMB ON Hifi_HIFI_Single_cmd($BBID,"HWH_ZERO_ON"); Hifi_HIFI_Single_cmd($BBID,"HWV_ZERO_ON"); Hifi_HIFI_Single_cmd($BBID,"HWH_COMB_ON"); Hifi_HIFI_Single_cmd($BBID,"HWV_COMB_ON"); delay(2); // //Integrate with the WBS Total_power_spectro_for_Stability_proc_fm(band,25,4,backend,["wb1","wb1"]); // //Still TBD here: [Perform comb measurements for different Bragg cell heat levels] Hifi_HIFI_Single_cmd($BBID,"HWH_COMB_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWV_COMB_OFF"); delay(1); Hifi_HIFI_Single_cmd($BBID,"HWH_ZERO_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWV_ZERO_OFF"); delay(1); //Configure Spectroscopy //Configure_Spectrometer_proc_fm(band,4,["wb1","wb1"]); } // Step 2 of QLA_Testcontrol fine magnet-tuning loop block Magnet_set_fine_with_IVcurve_fm HIFI 3204 { string band = "1a"; }{ Start_block(); {double,string}[] result_d = ConfigurationReader("name_confilfpu",["bias_min_h","bias_max_h","bias_steps_h","bias_min_v","bias_max_v","bias_steps_v"],band,0.0); //H polar double bias_min_h = result_d[0]{0}; double bias_max_h = result_d[1]{0}; int steps_h = iround(result_d[2]{0}); //V polar double bias_min_v = result_d[3]{0}; double bias_max_v = result_d[4]{0}; int steps_v = iround(result_d[5]{0}); //Bias to set at end of IVC //Need a representative frequency: take keyfreq double[] result = CalibrationReader("name_keyfreq",["keyfreq"],band,0.0); double lo_freq = result[0]; // result_d = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v","norm_magn_h","norm_magn_v"],band,lo_freq); double bias_h = result_d[0]{0}; double bias_v = result_d[1]{0}; //Fetch magnets only if band is not band6 double magnetcurrent_h = 0.0; double magnetcurrent_v = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { magnetcurrent_h = result_d[2]{0}; magnetcurrent_v = result_d[3]{0}; } // //The IVCurve is done on the smallest range and the finest step double bias_min = max(bias_min_h,bias_min_v); double bias_max = min(bias_max_h,bias_max_v); int steps = iround(max(double(steps_h),double(steps_v))); // //First set magnets to max. double magnet_current_max_h = 0.0; double magnet_current_max_v = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,0.0); magnet_current_max_h = result_d[0]{0}; magnet_current_max_v = result_d[1]{0}; } Hifi_HIFI_CH1_MX_MG_C($BBID,magnet_current_max_h); Hifi_HIFI_CV1_MX_MG_C($BBID,magnet_current_max_v); delay(1); //Do IV curve IVcurve(band,bias_min,bias_max,steps,magnetcurrent_h,magnetcurrent_v,bias_h,bias_v); } // LCU configuration with no retune, block // Uses best guess D2 voltage from latest LO tuning block LCU_config_nominal_noretune_block_aot HIFI 6614 { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978.2; //LO frequency bool fswstorage = true; // whether FSW register shall be stored }{ //Store rest frequency double rest_lofreq = lo_freq; //LO frequency uncorrected from VelCorr // Perform radial velocity correction lo_freq = VelCorrFreq(rest_lofreq); //Fetch LO parameters string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; } // {double,string}[] result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); // //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; // result = ConfigurationReader("name_delays",["config_lo_delay"],band,rest_lofreq); int config_lo_delay = iround(result[0]{0}); //Send command Hifi_HIFI_Conf_f_LCU_noretune($BBID,freq_nx,lsu_main,lsu_offset); // delay(config_lo_delay); //Store settings into available register if(fswstorage) { HIFI_HL_store_tm_proc_fm(); } } //////////////////////////////////////// // Standing wave analysis combined with stability measurement, procedure // It uses only the WBS in a specific setup. // Otherwise, re-use of Stability_intcold_fm code procedure Standing_wave_w_stability_fm { string band = "1a"; // HIFI band int integ_time = 4; //Total integration time in sec. string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast double[] lo_freq_input = [500.0,500.15,0.02]; //Start, end and step lo_freq for the LO scan int n = 100; //The number of integrations }{ //WBS calibration and backend tuning if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band); WBS_tune_stndwave_proc_fm(band); } if(backend == "hrs" || backend == "both") { HRS_tune_block_fm(band); } // //Configure spectrometers integration after tuning int[] res = Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); // //Loop on LO frequencies. It is assumed that the LO is tuned at the initial frequency double lo_freq = lo_freq_input[0]; while(lo_freq <= lo_freq_input[1]) { //Set synthesizer to new LO freq. LCU_config_nominal_proc_fm(band,lo_freq); // //Noise temperature measurement to check sensitivity change with LO frequency Hot_cold(band,hrs_mode,backend,res[0] * res[1],"tp",0,0); //integration on internal loads // //Stability measurement on cold internal source //Radiometry_stability_fm(band,n,hrs_mode,"wbsFast"); //Complementary ~100-200 sec. stability measurement // //Configure spectrometers integration back to default res = Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); //Increase lo_freq lo_freq = lo_freq + lo_freq_input[2]; } // } ///////////////////////////////////////////////////////////////// // Slow chop dual beam switch observing mode // // Combination of four modules implementing the new structure // // Implemented as procedure returning time and noise levels for HSPOT {int,double,double,double,double,double} obs HifiPointProcDBS { /* Setup parameters */ int naifid = 0; // Tracing object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_switch_on = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per pointing int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Single Point - DBS slowChop",{data_time,0,0,n_switch_on,0,0,0,0,n_cycles,load_interval}); // Call first part of the timing computer {int,int,int,int,int,int,int,int,int,bool,int,int,int} pre_timing = DBS_pre_timing(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_switch_on,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,int,int,int,int,int,int} tpar = DBS_telescope(naifid,onPosition,band,lo_freq,"",pre_timing,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = nodding_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},false); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,bool,int,int,int},bool,double,double} post_timing = DBS_post_timing(pre_timing,telescopetimes,n_cycles); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = DBS_telescope(naifid,onPosition,band,lo_freq,"",post_timing{1},n_cycles); // Call telescope command telescopetimes = nodding_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},false); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{3}; int n_load = post_timing{1}{6}; int n_seq = post_timing{1}{8}; int n_loadinterval = post_timing{1}{7}; bool end_load = post_timing{1}{9}; int shiftlength = post_timing{1}{10}; bool final_load = post_timing{2}; double tscan = post_timing{3}; double tdead = post_timing{4}; // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { DBS_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_seq,n_load,n_loadinterval,end_load,final_load,startobs,telescopetimes,loadlength,shiftlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double} tact = DBS_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_seq,n_load,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = DBS_noisecomputer(band,lo_freq,effResolution,continuumDetection,oneGHzReference,n_cycles,tscan,tact); // Evaluate performance DBS_performance(band,lo_freq,effResolution,noisevalues,timeTaken,n_cycles,n_seq * (n_load + 1),tscan,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // General HIFI performance test to be run at key frequencies // Assumes that a SFT has been previously performed procedure HIFI_Performance_proc_fm { string band = "1a"; // HIFI band double lo_freq = 500.0; //LO frequency string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int integ_time = 4; //Total integration time in sec. string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ // //FPU configuration Init_MSA_fm(band,"CLOSE",lo_freq,"ON"); //backend config if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_config_block_fm(band); } if(backend == "hrs" || backend == "both") { HRS_config_block_fm(band,hrs_mode); } //Set-up LO at new frequency and performs tuning at that frequency. //Assumes the band was already switched on prior to the performance test //Also assumes we are in nominal mode. LO_tuning_block_fm(band,lo_freq); //The mixer to use is checked in a table // //Now start measurements corresponding to FT pumped IVcurve_pumped_fm(band,lo_freq); // //Magnet tuning: only up to band 5 since band6-7 have no magnets string backend_code = "HRS"; //our experience is that HRS is doing fine for mag tuning if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { {double,string}[] result_d = ConfigurationReader("name_configwbs",["tune_target_magnet"],band,lo_freq); int tune_target_magnet = iround(result_d[0]{0}); Magnet_tuning_block_fm(band,lo_freq,backend_code,tune_target_magnet); } // //Spectrometer attenuator tuning: should be done on Hot source Chopper_Rotation_block_fm(band,"chop_M3_ang","chop_hot_ang"); // //WBS calibration and backend tuning if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band); WBS_tune_proc_fm(band); } if(backend == "hrs" || backend == "both") { HRS_tune_block_fm(band); } // //Configure spectrometers after tuning int[] res = Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); //HotCold measurement Hot_cold(band,hrs_mode,backend,res[0] * res[1],"tp",0,0); // //Finally, perform chopper scan from M3_right to end stop //it is done in slowchop mode to avoid short term instabilities // //DT - from FM_CUS_9.15.2 onwards, chopper scan is done out of this testmode // res = Configure_Spectrometer_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); int total_time = res[0] * res[1]; int n_steps = 100; int n_wbs1 = 0; //we use the slowchop mode int n_hrs_trans = 0; //we use the slowchop mode double chop_phase = 1.0; //we use the slowchop mode //Get voltages for start and end positions result_d = ConfigurationReader("name_confilfpu",["chop_M3right","chop_endstopright"],band,0.0); double chopper_pos_min = result_d[0]{0}; double chopper_pos_max = result_d[1]{0}; //Chopper_scan_fm (band, chopper_pos_min, chopper_pos_max, n_steps,total_time,backend,"slowchop",n_wbs1,n_hrs_trans,false,shutter_used,hrs_mode,chop_phase) ; // } //HIFI investigation of spurs in 1a and 4b procedure Spur_Investigation_proc_fm_COP { string band = "1a" in ["1a","4b"]; // HIFI band int freq_index = 1 in [1,3]; //Frequency index: 1 for 1a, 1 to 3 for 4b string parm = "G1" in ["G1","G2","D1","D2","M1","M2"]; //Parameter to scan: G1,G2,D1,D2,M1,M2 }{ //Sanity checks: no blocks 0 and 3 for 7b if(band == "1a" && (freq_index == 2 || freq_index == 3)) { error("There's no such testblock allowed in 1a"); } //Read input table string tab1 = "config_spur_cop_" + band + ".config"; //Get parameters double lo_freq = dlookup(tab1,"" + freq_index,"frequency"); double step_g1 = dlookup(tab1,"" + freq_index,"delta_g1"); double step_g2 = dlookup(tab1,"" + freq_index,"delta_g2"); double step_d1 = dlookup(tab1,"" + freq_index,"delta_d1"); double step_d2 = dlookup(tab1,"" + freq_index,"delta_d2"); double step_m1 = dlookup(tab1,"" + freq_index,"delta_m1"); double step_m2 = dlookup(tab1,"" + freq_index,"delta_m2"); //Configure instrument and backends. LO should be warmed up already Init_MSA_fm(band,"CLOSE",lo_freq,"ON"); //General parameters in use string backend = "both"; string[] hrs_mode = ["wb1","wb1"]; //For bands 6 and 7, use wb8 if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { hrs_mode = ["wb8","wb8"]; } // int integ_time = 4; string chopmode = "slowchop"; int[] res = Configure_Spectrometer_hc_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); int total_time = res[0] * res[1]; HRS_config_block_fm(band,hrs_mode); WBS_calib_fm(band); //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; name_configlcutune = "name_configlcutune_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["m1_v","m2_v","m3_v"],band,lo_freq); double m1_nom = result[0]{0}; double m2_nom = result[1]{0}; double m3_nom = result[2]{0}; double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v"],band,lo_freq); double gate1_nom = cresult[0]; double gate2_nom = cresult[1]; double drain1_nom = cresult[2]; result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lo_freq); double drain2_bestguess = result[0]{0}; //Get safe Vd2 cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); double vd2_safe = cresult[0]; if(parm == "G1") { double param_nom = gate1_nom; double step_nom = step_g1; } if(parm == "G2") { param_nom = gate2_nom; step_nom = step_g2; } if(parm == "D1") { param_nom = drain1_nom; step_nom = step_d1; } if(parm == "D2") { param_nom = drain2_bestguess; step_nom = step_d2; } if(parm == "M1") { param_nom = m1_nom; step_nom = step_m1; } if(parm == "M2") { param_nom = m2_nom; step_nom = step_m2; } //Loop on parameter to scan //First at nominal double param_value = param_nom; LCU_config_w_paramscan_block_fm(band,lo_freq,parm,param_value); WBS_tune_proc_fm(band); HRS_tune_block_fm(band); Hot_cold(band,hrs_mode,backend,total_time,chopmode,0,0); //Then at nominal - delta param_value = param_nom - step_nom; LCU_config_w_paramscan_block_fm(band,lo_freq,parm,param_value); WBS_tune_proc_fm(band); HRS_tune_block_fm(band); Hot_cold(band,hrs_mode,backend,total_time,chopmode,0,0); //Finally at nominal + delta param_value = param_nom + step_nom; LCU_config_w_paramscan_block_fm(band,lo_freq,parm,param_value); WBS_tune_proc_fm(band); HRS_tune_block_fm(band); Hot_cold(band,hrs_mode,backend,total_time,chopmode,0,0); //Configure back to nominal at this frequency LCU_config_nominal_w_D2_proc_fm(band,lo_freq,drain2_bestguess); } //HIFI LO tuning, block for experts: allow all vector scan parameters as user input //Target current is read from look-up table block LO_tuning_EXPERT_block_fm HIFI 3613 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency string mixer_polarization = "H" in ["H","V","B"]; //The polarization to be used for the tuning double target_current = 1.0; //Target mixer current double step_drain2_v = 2.0; //D2_V steps during vector scan int nsteps = 10; //Number of steps. Should not be larger than 10 double step_time = 1.0; //In seconds. double drain2_v_start = 1.5; //Starting D2_V in vector scan }{ //Clear potential failure mode Set_LO_Nominal_proc_fm(); // //Start_block(); // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; //double drain2_v_start = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); double drain2_safe = cresult[0]; // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // //For bands 1 to 5, scan will be done with increasing drain2 voltages // //For bands 6 to 7, scan will be done with decreasing drain2 voltages if(band == "6a" || band == "7a" || band == "6b" || band == "7b") { step_drain2_v = -1.0 * step_drain2_v; } // //Load vector scan //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Load_vector_safe_1a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "1b") { //Band 1b Hifi_HIFI_Load_vector_safe_1b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2a") { //Band 2a Hifi_HIFI_Load_vector_safe_2a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2b") { //Band 2b Hifi_HIFI_Load_vector_safe_2b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3a") { //Band 3a Hifi_HIFI_Load_vector_safe_3a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3b") { //Band 3b Hifi_HIFI_Load_vector_nom_3b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "4a") { //Band 4a Hifi_HIFI_Load_vector_safe_4a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "4b") { //Band 4b Hifi_HIFI_Load_vector_safe_4b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "5a") { //Band 5a Hifi_HIFI_Load_vector_nom_5a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "5b") { //Band 5b Hifi_HIFI_Load_vector_nom_5b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6a") { //Band 6a Hifi_HIFI_Load_vector_nom_6a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6b") { //Band 6b Hifi_HIFI_Load_vector_nom_6b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7a") { //Band 7a Hifi_HIFI_Load_vector_nom_7a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7b") { //Band 7b Hifi_HIFI_Load_vector_nom_7b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } // //delay(1); // //Execute tuning: check which mixer is to be used //Execute tuning: check which mixer is to be used if(mixer_polarization == "V") { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCV($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCV($BBID,target_current); } } else { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCH($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCH($BBID,target_current); } } // double time_needed = double(nsteps) * step_time; delay(iround(time_needed + 2.0 + 0.5)); //0.5s added for completion of load_vector // //Store settings into available register HIFI_HL_store_tm_only_proc_fm(); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } // Detector heater control: AOT version does not switch magnet back to normal at end block Heater_block_aot HIFI 6940 { string band = "4a"; }{ //Get name of FPU configuration file {double,string}[] result_d = ConfigurationReader("name_confilfpu",["normal_heater_time_h","normal_heater_time_v","heater_delay_h","heater_delay_v","magnet_current_max_h","magnet_current_max_v"],band,0.0); double normal_heater_time_h = result_d[0]{0}; double normal_heater_time_v = result_d[1]{0}; int heater_delay_h = iround(result_d[2]{0}); int heater_delay_v = iround(result_d[3]{0}); //Magnets need to be switched to 0 prior to the deflux Hifi_HIFI_CH1_MX_MG_C($BBID,0.0); Hifi_HIFI_CV1_MX_MG_C($BBID,0.0); delay(1); // Hifi_HIFI_HF_CH1_DHTR_C($BBID,normal_heater_time_h); delay(iceil(normal_heater_time_h / 1000.0) + 1); // int startobs = time(); //Extra delay for cooling down temperature: will be included in the V-mixer delay //delay(heater_delay_h); Hifi_HIFI_HF_CV1_DHTR_C($BBID,normal_heater_time_v); delay(iceil(normal_heater_time_v / 1000.0) + 1); //Extra delay for cooling down temperature: both mixers cool down together delay(heater_delay_v); // } //HIFI LO tuning, procedure procedure LO_tuning_block_fm_1a { double target_current = 1.0; //Target mixer current string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 570.0; //LO frequency string mixer_polarization = "H" in ["H","V"]; //The polarization to be used for the tuning }{ error("This module is obsolete: use LO_tuning_block_fm instead"); } ////////////////////////////////////////////////////////////////////////// // Procedure to generate the parameters for the telescope command // and to check all input parameters {int,int,int,string,int,double,double,bool,double,double,double,int,double,int,int,int,int,int,int} procedure DBS_telescope { int naifid = 0; // Tracing object ID {double,double} onposition = {0.0,0.0}; // Coordinates of the source string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz string throw = ""; // Identifier for chop throw, empty is standard {int,int,int,int,int,int,int,int,int,bool,int,int,int} timing = {4,10,4,21,11,1800,0,10,1,false,0,50,0}; // full timing parameter list int n_cycles = 2; // Number of half OFF-ON-ON-OFF cycles }{ // Assign values int pointing = timing{1}; // Pointing during in one phase int loadlength = timing{3}; // Load duration int n_loadinterval = timing{7}; //No. of nods between load measurements int initlength = timing{11}; // Initial setup time int dangling = timing{12}; // Final load measurement // Create variables for telescope command string ib = GetBoresight(band,lo_freq,true); // A change of ra-dec depending on naifid may be needed double ra = onposition{0}; double dec = onposition{1}; // pattern angle and throw of the chopper direction double[] chopper = GetSkyChopThrow(band,lo_freq,throw); double nodlength = chopper[0]; double patt = chopper[1]; nodlength = max(nodlength * 3600.0,2.0); // Check parameter compatibility with pointing command for parameters // which are no direct input parameters if(n_cycles > 1200) { IError("Too many noddings. Break up the observation into smaller pieces."); } if(pointing < 10) { SError("Pointing phase length too short. Increase the number of integrations."); } if(pointing > 50000) { SError("Pointing phase length too long. Reduce the number of integrations."); } if(nodlength > 7200.0) { IError("Nodding length too long. Choose a smaller chop throw."); } // repetition at multiple frequencies not yet implemented: int thold = 0; int nhold = 0; int n_repeat = n_cycles; // return parameters in required order return {initlength,0,dangling,ib,naifid,ra,dec,false,patt,0.0,0.0,n_repeat,nodlength,pointing,pointing,loadlength,n_loadinterval,thold,nhold}; } /////////////////////////////////////////////// // Functions useful for almost all observing modes // Perform consistency check for long observations // where readout time <= data time procedure CheckDataTaking { {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // Readout parameters for HRS1,HRS2, WBS1,WBS2 int data_time = 4; // Integration time between two data readouts }{ // Compute chunk size given by the data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); if(dataparms{0} > data_time) { SError("Maximum data rate does not allow to dump backends every " + data_time + "s."); } } // WBS configuration, block // Both polarizations are treated block WBS_config_block_aot HIFI 6625 { string band = "4a"; // HIFI band }{ //H-Polarization // {double,string}[] result_d = ConfigurationReader("name_configwbs",["hwh_laser1_s","hwh_laser2_s","hwh_heater","hwh_latchup_s","hwh_att_band4","hwh_att_band3","hwh_att_band2","hwh_att_band1","hwh_att_in"],band,0.0); string hwh_laser1_s = result_d[0]{1}; string hwh_laser2_s = result_d[1]{1}; int hwh_heater = iround(result_d[2]{0}); string hwh_latchup_s = result_d[3]{1}; int hwh_att_band4 = iround(result_d[4]{0}); int hwh_att_band3 = iround(result_d[5]{0}); int hwh_att_band2 = iround(result_d[6]{0}); int hwh_att_band1 = iround(result_d[7]{0}); int hwh_att_in = iround(result_d[8]{0}); // result_d = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result_d[0]{0}); // //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); // //delay(wbs_config_delay); //Wait for configuration to be applied // //V-Polarization // result_d = ConfigurationReader("name_configwbs",["hwv_laser1_s","hwv_laser2_s","hwv_heater","hwv_latchup_s","hwv_att_band4","hwv_att_band3","hwv_att_band2","hwv_att_band1","hwv_att_in"],band,0.0); string hwv_laser1_s = result_d[0]{1}; string hwv_laser2_s = result_d[1]{1}; int hwv_heater = iround(result_d[2]{0}); string hwv_latchup_s = result_d[3]{1}; int hwv_att_band4 = iround(result_d[4]{0}); int hwv_att_band3 = iround(result_d[5]{0}); int hwv_att_band2 = iround(result_d[6]{0}); int hwv_att_band1 = iround(result_d[7]{0}); int hwv_att_in = iround(result_d[8]{0}); // //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // delay(wbs_config_delay); //Wait for configuration to be applied // } ///////////////////////////////////////////////////////////////// // Procedure to call ConfigSpectroscopy for fast chop with a single command // int[] procedure ConfigFastChop { int observing_time = 12; // Integration time double chop_phase = 0.5 in [0.125,2.0]; // Chop phase length string band_number = "1a"; // HIFI band double lo_freq = 522000.0; // LO frequency /* Backend settings */ {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // HRS1 {used,resolution,subbands used}, HRS2 , WBS1 {used, channel windows}, WBS2 }{ // Use only 24 bit mode here int dpmax = observing_time / 2; {int,double[]} dataparms = DataTaking(backendreadoutparms,dpmax); int dpmin = 2 * dataparms{0}; if(observing_time < dpmin) { error("The total integration time of " + observing_time + "s is too short " + "for a fast chop measurement."); } // split integration time int data_time = 0; int n_data = 0; // Construct possible read out times dpmax = 160; // WBS ICD for(int idiv = dpmin .. dpmax) { if(observing_time % idiv == 0) { data_time = idiv; n_data = observing_time / idiv; } } if(data_time == 0) { error("The integration time of " + observing_time + "s cannot be split " + "into equal integrations <= 10s."); } // Split into chop cycles int wbs_overhead = 2; int n_chop = ifloor(double(data_time - wbs_overhead) / (2.0 * chop_phase)); return [data_time,n_data,n_chop]; } // Return standard readout setting used in frequency calibration {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} procedure FrequencyCalibrationParms { bool usewbs1 = true; // whether the WBS1 is used bool usewbs2 = true; // whether the WBS2 is used bool usehrs1 = false; // whether the HRS1 is used bool usehrs2 = false; // whether the HRS2 is used }{ {bool,int,bool[]} hrs1 = {usehrs1,3,[true,true,true,true]}; {bool,int,bool[]} hrs2 = {usehrs2,3,[true,true,true,true]}; {bool,int[][]} wbs1 = {usewbs1,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {usewbs2,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {hrs1,hrs2,wbs1,wbs2}; return backendreadoutparms; } //Reduced version: IVC only //HIFI-COP-7.2-LO_FT obs HifiEng_LO_FT_IVC_COP { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(LO_FT_IVC_COP_proc_ops(band,prime_or_redundant)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution LO_FT_IVC_COP_proc_ops(band,prime_or_redundant); } if(state[0] == 5) { HIFISetHK("normal",true); StopMode_block_ops(); } } } //HIFI-COP-2.1-DPL-RespTime procedure Diplexer_Response_time_COP_proc_ops { string band = "3a" in ["3a","4a","6a","7a"]; string mixer_polarization = "H"; //mixer polarization: H or V }{ //Get keyfreq double[] result_d = CalibrationReader("name_keyfreq",["keyfreq"],band,0.0); double lo_freq = result_d[0]; //Series of diplexer settings to move to double[] dipl_curr = [1.5,-1.5,1.5,0.1,-0.1,0.1,1.3,1.5,1.3,-1.3,-1.5,-1.3]; //Define engineering scan parameters int milliSecSample = 3; // interval between samples int samplesBefore = 30; // HIF_N_samples_1 int samplesAfter = 1000; // HIF_N_samples_2 double bandnb = GetBandCode(band); string tabfilter = "config_dipfilter.config"; //Loop on filter parameters //For trend monitoring repeat, we limit this to index 4, which is filter=1 for(int j = 4 .. 4) { // for (int j = 1 .. 4) { //Retrieve filters from LUT int dipfilter = ilookup(tabfilter,"" + iceil(bandnb),"filter_" + j); //Initialise MSA with this filter Init_MSA_DipFilter_fm(band,"CLOSE",lo_freq,"ON",dipfilter); //Loop on pairs for(int i = 0 .. 3) { //Set diplexer to starting point Set_Diplexer_current_block_fm(dipl_curr[i * 3],dipl_curr[i * 3]); //Start series of diplexer motion and measure response time Diplexer_engineering_scan_block_fm(mixer_polarization,dipl_curr[i * 3 + 1],milliSecSample,samplesBefore,samplesAfter); Diplexer_engineering_scan_block_fm(mixer_polarization,dipl_curr[i * 3 + 2],milliSecSample,samplesBefore,samplesAfter); //Engineering_scan_for_diplexer_resp_block_ops(milliSecSample,samplesBefore,samplesAfter); } } } ///////////////////////////////////////////////////////////////// // Procedure to derive often used backend settings // Derived from spectral-scan-mode and genericCode // {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} procedure BackendSettings { string band = "1a"; // HIFI band double lo_freq = 522000.0; // LO frequency string[] hrs_mode = ["wb2","wb2"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4,wb5 string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Fetch parameters applicable to the backend case string spec_filename = "name_confilspec"; //For tp and chop if(backend == "wbsFast") { spec_filename = "name_confilspec_wbsFast"; } if(backend == "wbsFast2") { spec_filename = "name_confilspec_wbsFast2"; } {double,string}[] result = ConfigurationReader(spec_filename,["wbsh_offset1","wbsh_width1","wbsh_offset2","wbsh_width2","wbsh_offset3","wbsh_width3","wbsh_offset4","wbsh_width4","wbsv_offset1","wbsv_width1","wbsv_offset2","wbsv_width2","wbsv_offset3","wbsv_width3","wbsv_offset4","wbsv_width4","hrsh_sel","hrsv_sel"],band,0.0); int wbsh_offset1 = iround(result[0]{0}); int wbsh_width1 = iround(result[1]{0}); int wbsh_offset2 = iround(result[2]{0}); int wbsh_width2 = iround(result[3]{0}); int wbsh_offset3 = iround(result[4]{0}); int wbsh_width3 = iround(result[5]{0}); int wbsh_offset4 = iround(result[6]{0}); int wbsh_width4 = iround(result[7]{0}); int wbsv_offset1 = iround(result[8]{0}); int wbsv_width1 = iround(result[9]{0}); int wbsv_offset2 = iround(result[10]{0}); int wbsv_width2 = iround(result[11]{0}); int wbsv_offset3 = iround(result[12]{0}); int wbsv_width3 = iround(result[13]{0}); int wbsv_offset4 = iround(result[14]{0}); int wbsv_width4 = iround(result[15]{0}); int hrsh_sel = iround(result[16]{0}); int hrsv_sel = iround(result[17]{0}); //HRS settings: //1. Translate HRS selection code into array of sub-band state //Check against conversion table //H-polar result = ConfigurationReader("name_hrs_select",["band1","band2","band3","band4"],"0",double(hrsh_sel)); bool[] band_hrsh = [true,true,true,true]; for(int i = 0 .. 3) { if(result[i]{0} == 0.0) { band_hrsh[i] = false; } } //V-polar result = ConfigurationReader("name_hrs_select",["band1","band2","band3","band4"],"0",double(hrsv_sel)); bool[] band_hrsv = [true,true,true,true]; for(int k = 0 .. 3) { if(result[k]{0} == 0.0) { band_hrsv[k] = false; } } //2. Convert resolution code int hrsh_res = 3; //wb int hrsv_res = 3; //wb //H-polar if(hrs_mode[0] == "hr") { // high resolution hrsh_res = 0; } if(hrs_mode[0] == "mr") { // low resolution hrsh_res = 1; } if(hrs_mode[0] == "lr") { // low resolution hrsh_res = 2; } //V-polar if(hrs_mode[1] == "hr") { // high resolution hrsv_res = 0; } if(hrs_mode[1] == "mr") { // low resolution hrsv_res = 1; } if(hrs_mode[1] == "lr") { // low resolution hrsv_res = 2; } //Check whether a given HRS polar is in use: it is so unless sel. code is 0 bool hrsh_used = true; bool hrsv_used = true; if(hrsh_sel == 0) { hrsh_used = false; } if(hrsv_sel == 0) { hrsv_used = false; } // //Other check is whether HRS is used at all if(backend == "wbs") { hrsh_used = false; hrsv_used = false; band_hrsh = [false,false,false,false]; band_hrsv = [false,false,false,false]; } // //Case of hrsFast: use only half of the so-far selected sub-band // if(backend == "hrsFast") { if(hrs_mode[0] == "hr" || hrs_mode[1] == "hr") { error("hrsFast cannot be used with high resolution mode."); } //Selection code will depend on resolution mode: //We use the same mapping of the band for all cases. //1. If wide-band mode: we had 8 sub-bands, keep 4 in 2 pairs: 1L/U and 2L/U // widebits=[192,12,3,48] -> sel=195 //2. If lr mode: We had 4 sub-bands: 1U,3U,4L and 2L. We keep 1U and 3U // lowbits=[192,12,48,3] -> sel=240 //3. If mr mode: We had 2 sub-bands 1U and 4L. We keep 1U // normalbits=[240,15] -> sel=240 band_hrsh = [true,true,false,false]; band_hrsv = [true,true,false,false]; //For mr, we need to keep only the first half if(hrs_mode[0] == "mr") { band_hrsh = [true,false,true,false]; } if(hrs_mode[1] == "mr") { band_hrsv = [true,false,true,false]; } } //WBS //1. WBS channels in use int[] wbsh_ch1 = [wbsh_offset1,wbsh_offset1 + wbsh_width1]; int[] wbsh_ch2 = [wbsh_offset2 - 2048,wbsh_offset2 + wbsh_width2 - 2048]; int[] wbsh_ch3 = [wbsh_offset3 - 4096,wbsh_offset3 + wbsh_width3 - 4096]; int[] wbsh_ch4 = [wbsh_offset4 - 6144,wbsh_offset4 + wbsh_width4 - 6144]; int[] wbsv_ch1 = [wbsv_offset1,wbsv_offset1 + wbsv_width1]; int[] wbsv_ch2 = [wbsv_offset2 - 2048,wbsv_offset2 + wbsv_width2 - 2048]; int[] wbsv_ch3 = [wbsv_offset3 - 4096,wbsv_offset3 + wbsv_width3 - 4096]; int[] wbsv_ch4 = [wbsv_offset4 - 6144,wbsv_offset4 + wbsv_width4 - 6144]; // //2. Other check is whether WBS is used at all bool wbsh_used = true; bool wbsv_used = true; if(backend == "hrs" || backend == "hrsFast") { wbsh_used = false; wbsv_used = false; } //Build up backend parameter tupple {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrsh_used,hrsh_res,band_hrsh},{hrsv_used,hrsv_res,band_hrsv},{wbsh_used,[wbsh_ch1,wbsh_ch2,wbsh_ch3,wbsh_ch4]},{wbsv_used,[wbsv_ch1,wbsv_ch2,wbsv_ch3,wbsv_ch4]}}; // Readout parameters for HRS1,HRS2, WBS1,WBS2 return backendreadoutparms; } // Load boot in rescue mode, mode mode HifiManCmd_load_boot { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! }{ Mode_status_check_rescue("normal"); //StartMode_block_ops(); mois_comment("Start loading and booting of a new OBSW in rescue mode"); Load_boot_block_ops(); // //Get applicable HK rate {double,string}[] result = ConfigurationReader("name_delays",["hk_rate"],"0",0.0); double hk_rate = result[0]{0}; // mois_step("Adjust HK data rate."); HKrate_block_ops(hk_rate); Mode_status_check_intermediate(); StopMode_block_ops(); } //////////////////////////////////// // Routine to provide initial guesses for sequence parameters // Position switch observing mode // {string,double,double}[] procedure HifiPointProcPositionSwitchSequencerInit { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source double raoff = 0.0; // RA coordinate of the OFF position double decoff = 0.0; // DEC coordinate of the OFF position string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,5]; // data dump interval limited by the data rates int n_int_on = 3 in [2,1800]; // number of data dumps for integration per phase int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF cycles int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode // limit on data rate {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // limits from noise section // Get the drift parameters to compute the drift noise // System Allan variance double[] allanparms = InterpolateSpecAllan(band,lo_freq,oneGHzReference); // rescale to frequency resolution double alpha = allanparms[1]; double binningexp = 1.0 / allanparms[2]; double allan_time_lores = allanparms[0] * pow(1.0 / effResolution{1},binningexp); // Compute derived quantities int int_time_guess = imax(iceil(0.3 * allan_time_lores),datalimit); int data_time_guess = imin(5,int_time_guess); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } int n_int_on_guess = imax(int_time_guess / data_time_guess,2); int n_int_on_range = 2 - n_int_on_guess; if(n_int_on_range == 0) { n_int_on_range = 1; } // Add pointing requirements condition: >=10s {int,int} new_data_time = MatchMinPointing(data_time_guess,data_time_range,n_int_on_guess); data_time_guess = new_data_time{0}; data_time_range = new_data_time{1}; // Contruct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"n_int_on",double(n_int_on_guess),double(n_int_on_range)}]; return retvalues; } // Set diplexer currents for both polarizations, procedure procedure Set_Diplexer_current_proc_fm { double dipl_curr_h = 1.0; //Diplexer current H polarization double dipl_curr_v = 1.0; //Diplexer current V polarization }{ Hifi_HIFI_CH1_DPACT_C($BBID,dipl_curr_h); Hifi_HIFI_CV1_DPACT_C($BBID,dipl_curr_v); delay(1); } ///////////////////////////////////////////////////////////////// // Procedure to compute detailed timing for a // Spectral Scan Frequency-Switch observing mode // // We assume that each telescope motion is related to an // instrument calibration. // {{int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int},{int,double,double[],int[][],bool,double[],int,bool}} procedure SScanFSwitch_pre_timing { string band = "4a"; // HIFI band double lo_freq_low = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz int redundancy = 4; // Frequency scan redundancy double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} eff_resolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_chop_on = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles per frequency and pointing int n_chop_off = 1 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles on OFF int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int n_cycles = 1 in [1,600]; // Number of half OFF-ON-ON-OFF cycles at one frequency int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Create composite readout structure for backends {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Get frequency grid characteristic parameters {int,double,double[],int[][],int,bool} fqparms = MakeFreqGrid(band,lo_freq_low,lo_freq_up,redundancy,freq_throw,n_freq_point); double reffreq = fqparms{1}; double[] freqgrid = fqparms{2}; int[][] grouporder = fqparms{3}; // Process tuning level grid double[][] levelgrid = GetSScanLevelGrid(band,wbs1,wbs2,freqgrid,fqparms{0},grouporder); {bool,double[]} targets = TargetLevels(band,reffreq,levelgrid); bool retuning = targets{0}; double[] targetgrid = targets{1}; string reftarget = ""; if(retuning) { reftarget = "sscan_normal"; } {int,double,double[],int[][],bool,double[],int,bool} spectralparms = {fqparms{0},reffreq,freqgrid,grouporder,retuning,targetgrid,fqparms{4},fqparms{5}}; ////////////////////////////////////////////////////////////////////// // Get timing within the normal frequency-switch observations int readoutdead = SlowChopReadoutDelay(band,reffreq,backendreadoutparms); int jitterdead = GetMaxTimeJitter(band,reffreq); // Integration time per frequency and pointing int on_inttime = 2 * n_chop_on * data_time; int off_inttime = 2 * n_chop_off * data_time_off; // Duration of initial set up // Staying at the same frequency makes no sense here. // First frequency point double runningfreq = freqgrid[grouporder[1][0]]; // Compute load integration time int loadlength = duration(SScanDoubleLoadMeasurement(band,runningfreq,reffreq,freq_throw,true,eff_resolution{0},data_time,backendreadoutparms)); loadlength = loadlength + readoutdead; // determine exact duration only in case of full commanding if(docommands) { int initlength = duration(HIFIInitObs()); initlength = initlength + duration(TuneHIFIFsw(band,runningfreq,freq_throw,hrs1,hrs2,wbs1{0},wbs2{0},"sscan_normal")); // Add time for HK readout int hkduration = HkReadoutTime(band,reffreq,backendreadoutparms,false); initlength = initlength + hkduration; } else { initlength = GetRoughInitLength(band,runningfreq,true); } initlength = initlength + loadlength; // recompute load length during slews - no retuning loadlength = duration(SScanDoubleLoadMeasurement(band,reffreq,reffreq,freq_throw,false,eff_resolution{0},data_time,backendreadoutparms)); loadlength = loadlength + readoutdead; // Check load spacing int load_spacing = CheckedLoadSpacing(load_interval - loadlength,8); // Tuning delays int bigtunestep = duration(HIFIRetuneFsw(band,reffreq,freq_throw,reftarget)); // Correct for variation within the band int tunediff = ComputeLOTimeDifference(band,lo_freq_low,lo_freq_up,reffreq); bigtunestep = bigtunestep + 2 * tunediff; // As step within a group could be faster than a large step if(n_freq_point > 1) { int smallstep = duration(HIFIChangeFreqFsw(band,reffreq,freq_throw)); } else { smallstep = bigtunestep; } // For double phases I can use the added jitterdead in both phases for tune int auxtunestep = bigtunestep - jitterdead; int halftunestep = (auxtunestep + 1) / 2; // Telescope pointing int on_pointing = n_freq_point * on_inttime + (n_freq_point - 1) * smallstep + halftunestep + jitterdead; int off_pointing = off_inttime + halftunestep + jitterdead; // Check load_interval allowance int scan_time = 2 * imax(on_pointing,off_pointing); if(scan_time > load_spacing) { SError("Load interval of " + load_interval + "s is exceeded by " + n_chop_on * n_freq_point + " chop cycles."); } // Estimate of the load-cycles to issue a representative // telescope command if(n_cycles > 1) { // How often do I have to perform a load slew int n_loadinterval = imax(load_interval / scan_time,1); // fit with n_cycles n_loadinterval = imin(n_loadinterval,n_cycles); n_loadinterval = IMultiple(n_loadinterval,n_cycles); } else { n_loadinterval = 1; } // No dangling needed in this mode - we stop halftunelength before telescope int dangling = 0; bool end_load_on = false; bool end_load_off = false; // Return all the times needed for telescope call and post_timing processing return {{on_inttime,off_inttime,on_pointing,off_pointing,loadlength,auxtunestep,load_spacing,n_loadinterval,n_chop_on,n_chop_off,data_time,data_time_off,end_load_on,end_load_off,initlength,dangling},spectralparms}; } // Set diplexer currents for both polarizations, block block Set_Diplexer_current_FSW_block_fm HIFI 3743 { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 522.0; //The LO frequency in GHz }{ //Start_block(); if(band == "3a" || band == "3b" || band == "4a" || band == "4b" || band == "6a" || band == "6b" || band == "7a" || band == "7b") { double[] result_dip = Get_Diplexer_setting(band,lo_freq); Hifi_HIFI_CH1_DPACT_C($BBID,result_dip[0]); Hifi_HIFI_CV1_DPACT_C($BBID,result_dip[1]); } delay(1); } ////////////////////////////////////////////////////////////////////////// // Procedure to generate the telescope command for the OTF observing mode {int,int,int,string,int,double,double,bool,double,double,double,int,double,double,double,int,int,int} procedure OTFDoubleChopNoRef_telescope { int naifid = 0; // Tracking object ID {double,double} mapcenter = {0.0,0.0}; // Coordinates of the center of the map {double,double} linedistance = {0.0050,0.0050}; // Distance between subsequent rows int nlines = 1; // Number of rows in the map double linesize = 0.0050 in [0.0,2.0]; // Length of OTF lines double scanvelocity = 4.0E-4 in [2.75E-5,0.017]; // Scan velocity in � per s string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz int n_cover = 1; // Number of map coverages {int,int,int,int,bool,int,int} timing = {21,1780,1,21,false,50,0}; // timing parameter list }{ // Assign values int holdlength = timing{3}; // Load duration - turn around time int n_loadinterval = timing{2}; // N of OTF scans between load measurements int initlength = timing{5}; // Initial setup time int dangling = timing{6}; // Final load measurement // no load means n_loadinterval=0 here int nlines_tot = nlines * n_cover; if(n_loadinterval > nlines_tot) { int n_linesperscan = 0; } else { n_linesperscan = n_loadinterval; } // Create variables for telescope command string ib = GetBoresight(band,lo_freq,false); double ra = mapcenter{0}; double dec = mapcenter{1}; double patt = AngleFromVector(linedistance); patt = RotateRight(patt); // I assume that ValidMapSize was called, so that the API granularity // is meet for d1 and rate double d1 = linesize * 3600.0; double rate = scanvelocity * 3600.0; // Granularity for d2 double linestep = 0.5; double d2_req = AngleVectorLength(linedistance); d2_req = d2_req * 3600.0; // Define maximum reduction double eps = 0.98; double d2 = double(iceil(d2_req * eps / linestep)) * linestep; // Exception for the "impossible" case of spacings below 2arcsec d2 = max(d2,2.0); // Check parameter compatibility with pointing command for parameters // which are no direct input parameters if(rate > 60.0) { IError("Maximum scan velocity exceeded. Reduce the step size."); } else { if(rate < 0.1) { SError("Minimum scan velocity not reached. Reduce switch cycle number."); } } if(d1 > 7200.0) { IError("OTF line length too long. Reduce the map size."); } if(d2 > 480.0) { IError("OTF line spacing too coarse. Increase the sampling."); } // repetition at multiple frequencies not yet implemented: int n_repeat = n_cover; // return parameters in required order return {initlength,0,dangling,ib,naifid,ra,dec,true,patt,0.0,0.0,nlines,d1,d2,rate,holdlength,n_linesperscan,n_repeat}; } //Procedure checking the consistency of total power spectroscopy //parameters to be sent to configuration command. bool procedure Check_total_power_parameters_proc { int n_wbs_start = 1; //Nb of frames int r_hrs = 1; //Nb of HRS readout per WBS readout int n_wbs_integr = 1; //Number of wbs readout packetized per WBS frame int n_hrs_integr = 1; //Number of hrs readout packetized per HRS frame int del_hrs = 5; //Delay before starting HRS integration int del_wbs = 5; //Delay before starting WBS integration int t_acc_wbs = 4005; //Duration of WBS frame int t_acc_hrs = 1950; //Duration of HRS frame int wbsh_offset1 = 0; int wbsh_width1 = 2048; int wbsh_offset2 = 2048; int wbsh_width2 = 2048; int wbsh_offset3 = 4096; int wbsh_width3 = 2048; int wbsh_offset4 = 6144; int wbsh_width4 = 2048; int wbsv_offset1 = 0; int wbsv_width1 = 2048; int wbsv_offset2 = 2048; int wbsv_width2 = 2048; int wbsv_offset3 = 4096; int wbsv_width3 = 2048; int wbsv_offset4 = 6144; int wbsv_width4 = 2048; int hrs_rshift = 0; //HRS bit shift int wbs_rshift = 0; //WBS bit shift int hrsh_sel = 255; //HRS-H band selection int hrsv_sel = 255; //HRS-V band selection string wbs_packing = "24_bits_format"; string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4,wb5 string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ error("Procedure Check_total_power_parameters_proc is not used anymore."); return false; } ///////////////////////////////////////////////////////////////// // Procedures to compute the WBS IF levels for spectral scans // // Read attenuators settings across a spectral scan double[][] procedure GetSScanLevels { string band = "4a"; // HIFI band double[] freqgrid = [978053.7,978301.8,978381.1]; // frequency grid int[] subbandindices = [0,1,2,3,4,5,6,7]; // WBS subbands actually used }{ // Go select subband attenuators to read string[] subbandnames = ["pow_hw1","pow_hw2","pow_hw3","pow_hw4","pow_vw1","pow_vw2","pow_vw3","pow_vw4"]; int nsub = length(subbandindices); string[] bandnames = []; for(int j = 0 .. nsub - 1) { bandnames[j] = subbandnames[subbandindices[j]]; } // Initialize output grid double[][] attgrid = [[]]; double[] hlpgrid = []; int nel = length(freqgrid); // Go through frequency grid and read attenuators for(int i = 0 .. nel - 1) { double lo_freq = freqgrid[i]; double[] atts = CalibrationReader("power_levels",bandnames,band,lo_freq); attgrid[i] = clone(atts); } return attgrid; } // Patch OBSW in intermediate mode, mode mode HifiManCmd_patch_OBSW { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! }{ Mode_status_check_intermediate(); StartMode_block_ops(); mois_comment("Start patching of the OBSW in intermediate mode"); Patch_OBSW_block_ops(); StopMode_block_ops(); } //HIFI LO tuning, procedure //Target current is read from look-up table procedure LO_tuning_w_mixerchoice_proc { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency string mixer_polarization = "H" in ["H","V","B"]; //The polarization to be used for the tuning }{ //Clear potential failure mode Set_LO_Nominal_proc_fm(); // //Get target mixer current {double,string}[] result = ConfigurationReader("name_confilmix",["target_mx_c_h","target_mx_c_v"],band,lo_freq); double target_current = result[0]{0}; if(mixer_polarization == "V") { target_current = result[1]{0}; } if(mixer_polarization == "B") { target_current = 0.5 * (result[1]{0} + result[0]{0}); } // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; name_configlcutune = "name_configlcutune_b"; } // result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // result = ConfigurationReader(name_configlotune,["step_drain2_v","nsteps","step_time"],band,lo_freq); double step_drain2_v = result[0]{0}; int nsteps = iround(result[1]{0}); double step_time = result[2]{0}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // //Adjust scan cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); double drain2_safe = cresult[0]; // double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); // //For all bands, scan will be done with decreasing drain2 voltages //The best guess is taken from look-up table double tune_range = 0.1; result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lo_freq); double middle_d2 = result[0]{0}; double drain2_v_start = min(middle_d2 * (1.0 + tune_range / 2.0),drain2_bluemax); double drain2_v_end = (1.0 - tune_range / 2.0) / (1.0 + tune_range / 2.0) * drain2_v_start; step_drain2_v = (drain2_v_end - drain2_v_start) / double(nsteps - 1); // result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); // //Send command HIFI_Configure_LCU_proc_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,macro_checksum,config_lo_delay); // //delay(5); //to settle at this value // //Load vector scan //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Load_vector_safe_1a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "1b") { //Band 1b Hifi_HIFI_Load_vector_safe_1b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2a") { //Band 2a Hifi_HIFI_Load_vector_safe_2a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2b") { //Band 2b Hifi_HIFI_Load_vector_safe_2b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3a") { //Band 3a Hifi_HIFI_Load_vector_safe_3a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3b") { //Band 3b Hifi_HIFI_Load_vector_nom_3b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "4a") { //Band 4a Hifi_HIFI_Load_vector_safe_4a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "4b") { //Band 4b Hifi_HIFI_Load_vector_safe_4b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "5a") { //Band 5a Hifi_HIFI_Load_vector_nom_5a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "5b") { //Band 5b Hifi_HIFI_Load_vector_nom_5b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6a") { //Band 6a Hifi_HIFI_Load_vector_nom_6a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6b") { //Band 6b Hifi_HIFI_Load_vector_nom_6b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7a") { //Band 7a Hifi_HIFI_Load_vector_nom_7a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7b") { //Band 7b Hifi_HIFI_Load_vector_nom_7b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } // delay(1); // //Execute tuning: check which mixer is to be used if(mixer_polarization == "V") { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCV($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCV($BBID,target_current); } } else { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCH($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCH($BBID,target_current); } } // double time_needed = double(nsteps) * step_time; delay(iround(time_needed + 2.0 + 0.5)); //0.5s added for completion of load_vector // //Store settings into available register HIFI_HL_store_tm_only_proc_fm(); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } ////////////////////////////////////////////////////////////////////////// // Procedure to generate the telescope command for the OTF observing mode {int,int,int,string,int,double,double,bool,double,double,double,int,double,double,double,int,int,double,double,int,int,int,int,int} procedure OTFmap_telescope { int naifid = 0; // Tracking object ID {double,double} mapcenter = {0.0,0.0}; // Coordinates of the center of the map {double,double} linedistance = {0.0050,0.0050}; // Distance between subsequent rows int nlines_tot = 1; // Number of rows in the map double linesize = 0.0050 in [0.0,2.0]; // Length of OTF lines {double,double} offposition = {0.2,0.2}; // Coordinates of the OFF position double scanvelocity = 4.0E-4 in [2.75E-5,0.017]; // Scan velocity in � per s string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz int n_linesperscan = 1; // Number of lines between two OFFs int n_cover = 1; // Number of map coverages {int,int,int,int,int,int,int,int} timing = {10,1,12,13,21,10,50,0}; // timing parameter list }{ // Assign values int off_inttime = timing{3}; // Length of OFF integration int loadlength = timing{4}; // Load duration int n_loadinterval = timing{5}; // N of OTF scans between load measurements int initlength = timing{6}; // Initial setup time int dangling = timing{7}; // Final hold // Create variables for telescope command string ib = GetBoresight(band,lo_freq,false); // A change of ra-dec depending on naifid may be needed double ra = mapcenter{0}; double dec = mapcenter{1}; double raoff = offposition{0}; double decoff = offposition{1}; double patt = AngleFromVector(linedistance); patt = RotateRight(patt); // I assume that ValidMapSize was called, so that the API granularity // is meet for d1 and rate (should rather be done in HSPOT) double d1 = linesize * 3600.0; double rate = scanvelocity * 3600.0; // Separate treatment of repeated scans of the same line if(nlines_tot == 1) { int n_lines_eff = n_linesperscan; double d2 = 0.0; } else { n_lines_eff = nlines_tot; // Granularity for d2 double linestep = 0.5; double d2_req = AngleVectorLength(linedistance); d2_req = d2_req * 3600.0; // Define maximum reduction double eps = 0.98; d2 = double(iceil(d2_req * eps / linestep)) * linestep; // Exception for the "impossible" case of spacings below 2arcsec d2 = max(d2,2.0); } // Check parameter compatibility with pointing command for parameters // which are no direct input parameters if(rate > 60.0) { IError("Maximum scan velocity exceeded. Reduce the step size."); } else { if(rate < 0.1) { SError("Minimum scan velocity not reached. Reduce the supersampling."); } } if(d1 > 7200.0) { IError("OTF line length too long. Reduce the map size."); } if(d2 > 480.0) { IError("OTF line spacing too coarse. Increase the sampling."); } // We already put harder constrains on some parameters than required // by the pointing commands: // n_lines_eff <= 240 (HIFI), <= 1500(MPS) // n_linesperscan*j = n_lines_eff (HIFI), n_linesperscan <= n_lines_eff (MPS) // // repetition at multiple frequencies not yet implemented: int thold = 0; int nhold = 0; int n_repeat = n_cover; // return parameters in required order return {initlength,0,dangling,ib,naifid,ra,dec,true,patt,0.0,0.0,n_lines_eff,d1,d2,rate,n_linesperscan,off_inttime,raoff,decoff,n_repeat,thold,nhold,loadlength,n_loadinterval}; } // Slow chop procedure HIFI_Spectr_slow_chop_proc_aot { int data_time = 4; // Integration time between two data readouts int n_cycle = 1; // chop cycle number string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz string[] phases = ["chop_M3left","chop_M3right"]; // identifiers for chopper positions double[] rates = [120.0,1.0,2.0]; // Data rates between and during integrations }{ //Get appropriate chopper voltages {bool,double,double} chopparms = GetChopVoltages(band,lo_freq,phases[0],phases[1]); bool isPrime = chopparms{0}; // set data rates non_ess_hk_data_rate(rates[2] / 1024.0); data_rate(rates[0] / 1024.0); // Call command if(isPrime) { Hifi_HIFI_P_Spectr_slow_chop($BBID,chopparms{1},chopparms{2}); } else { Hifi_HIFI_R_Spectr_slow_chop($BBID,chopparms{1},chopparms{2}); } delay(2 * n_cycle * data_time); // reset data rates non_ess_hk_data_rate(rates[1] / 1024.0); data_rate(0.0); } // IV curve, block block IVcurve_raw_fm HIFI 3211 { string band = "1a"; }{ //Start_block() ; {double,string}[] result_d = ConfigurationReader("name_confilfpu",["bias_min_h","bias_max_h","bias_steps_h","bias_min_v","bias_max_v","bias_steps_v"],band,0.0); //H polar double bias_min_h = result_d[0]{0}; double bias_max_h = result_d[1]{0}; int steps_h = iround(result_d[2]{0}); //V polar double bias_min_v = result_d[3]{0}; double bias_max_v = result_d[4]{0}; int steps_v = iround(result_d[5]{0}); //Bias to set at end of IVC //Need a representative frequency: take keyfreq double[] result = CalibrationReader("name_keyfreq",["keyfreq"],band,0.0); double lo_freq = result[0]; // result_d = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v","norm_magn_h","norm_magn_v"],band,lo_freq); double bias_h = result_d[0]{0}; double bias_v = result_d[1]{0}; //Fetch magnets only if band is not band6 double magnetcurrent_h = 0.0; double magnetcurrent_v = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { magnetcurrent_h = result_d[2]{0}; magnetcurrent_v = result_d[3]{0}; } //The IVCurve is done on the smallest range and the finest step double bias_min = max(bias_min_h,bias_min_v); double bias_max = min(bias_max_h,bias_max_v); int steps = iround(max(double(steps_h),double(steps_v))); // //First set magnets to max. double magnet_current_max_h = 0.0; double magnet_current_max_v = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,0.0); magnet_current_max_h = result_d[0]{0}; magnet_current_max_v = result_d[1]{0}; } Hifi_HIFI_CH1_MX_MG_C($BBID,magnet_current_max_h); Hifi_HIFI_CV1_MX_MG_C($BBID,magnet_current_max_v); delay(1); //Perform IV curve IVcurve(band,bias_min,bias_max,steps,magnetcurrent_h,magnetcurrent_v,bias_h,bias_v); } // Chop between the two internal loads, block // We take 1 spectrum per phase. block Stability_intcold_inthot_fm HIFI 3423 { string band = "1a"; // HIFI band int n = 100; //The number of integration pairs int integ_time = 4; //Total (co-added) integration time of ONE SINGLE phase in sec. string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string chopmode = "slowchop" in ["slowchop","fastchop"]; //Whether to use slowchop or fastchop double chop_phase = 1.0 in [0.2,2.0]; // Chop phase length }{ Start_block(); double chop = 0.0; //Get chopper settings {double,string}[] result = ConfigurationReader("name_confilfpu",["chop_hot","chop_cold"],band,0.0); double chop_hot = result[0]{0}; double chop_cold = result[1]{0}; // //We implement a special slow-chop spectroscopy between //internal cold and external cold if(chopmode == "slowchop") { Slow_chop_spectro_for_Stability_proc_fm(band,n,integ_time * 2,backend,hrs_mode,chop_hot,chop_cold); } else { Fast_chop_spectro_for_Stability_proc_fm(band,n,integ_time * 2,backend,hrs_mode,chop_hot,chop_cold,chop_phase); } } //Chopper rotation procedure. It takes into account //overshoot risk and performs the rotation in //2 steps if the targetted positions are either of the end stops procedure Chopper_Rotation_proc_fm { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string chop_current_position = "chop_hot_ang"; //Current chopper position string chop_target_position = "chop_cold_ang"; //Targetted chopper position }{ //Retrieve angles of corresponding positions {double,string}[] result_d = ConfigurationReader("name_chopper",[chop_current_position,chop_target_position,"chop_endstopright_ang","chop_endstopleft_ang","overshoot"],band,0.0); double chop_current_angle = result_d[0]{0}; double chop_target_angle = result_d[1]{0}; double chop_endstopright_angle = result_d[2]{0}; double chop_endstopleft_angle = result_d[3]{0}; double overshoot = result_d[4]{0}; string chop_target_name = result_d[1]{1}; string chop_current_name = result_d[0]{1}; int step = 1; // //Check whether the rotation may reach either of the end stops, i.e. //go beyond either the HBB or M3_left ///// We suppose here overshoot to be 0, so the 2 steps only occur when targetting ///// the end stops strictly. double total_angle = abs(chop_target_angle - chop_current_angle) * (1.0 + overshoot); // //The endstop that one may hit depends on the rotating direction //Case were endstop is the left one double angle_to_endstop = abs(chop_endstopleft_angle - chop_current_angle); if(chop_target_angle > chop_current_angle) { //then end stop is the right one angle_to_endstop = abs(chop_endstopright_angle - chop_current_angle); } //debug_print(total_angle); //debug_print(angle_to_endstop); if(total_angle >= angle_to_endstop) { message("Chopper expected to hit the endstop. Rotation done in two steps"); step = 2; } //If we have two steps necessary, the middle position between current and //targetted position is used. result_d = ConfigurationReader("name_confilfpu",[chop_target_name,chop_current_name],band,0.0); double chop = result_d[0]{0}; double chop_intermediate = (result_d[0]{0} + result_d[1]{0}) / 2.0; // //Check whether sent values need to be converted in case of redundant mode chop = Check_Chopper_Prime_Redundant(chop); // if(step == 1) { HIFI_CPR_Chopper_Rot_proc_fm(chop); Hifi_HIFI_non_periodic_hk_FCU(); //To get sent voltage delay(1); } if(step == 2) { chop_intermediate = Check_Chopper_Prime_Redundant(chop_intermediate); HIFI_CPR_Chopper_Rot_proc_fm(chop_intermediate); Hifi_HIFI_non_periodic_hk_FCU(); //To get sent voltage delay(1); HIFI_CPR_Chopper_Rot_proc_fm(chop); Hifi_HIFI_non_periodic_hk_FCU(); //To get sent voltage delay(1); } } ////////////////////////////////////////////////////////////////////////// // Procedure to compute detailed timing of peakup observing mode {int,{int,int,int,int,int,double,int,int}} procedure Peakup_post_timing { {int,int,int,int,int,double,int,int} pre_timing = {8,10,2,21,4,1.6,50,0}; // pre timing parameter list int[] telescopetimes = [300,180,10,10,29,0]; int nlines_tot = 3; // Number of rows in the map int npoints = 3; // Number of points per row }{ // Get all values from the pre_timing section int inttime = pre_timing{0}; int pointing = pre_timing{1}; int data_time = pre_timing{2}; int loadlength = pre_timing{3}; int n_chop = pre_timing{4}; double eff_resolution = pre_timing{5}; int initlength = pre_timing{6}; int dangling = pre_timing{7}; // Get all values from the telescope section int telinit = telescopetimes[1]; // Initial slew time int slewtime = telescopetimes[2]; // Slew time to next point int slewline = telescopetimes[3]; int tend = telescopetimes[5]; // Total number of scans int n_tot = npoints * nlines_tot; /////////////////////// // obtain all slew durations int tinlinesdead = (npoints - 1) * slewtime * nlines_tot; int toutlinesdead = (nlines_tot - 1) * slewline; // Compute total duration int totaltime = n_tot * pointing + tinlinesdead + toutlinesdead; // Add dangling time if not included in pointing // Add time needed to perform AOCS correction int closelength = duration(HIFICloseObs()) + duration(HifiPeakupCorrection()); dangling = imax(dangling + closelength - tend,0); totaltime = totaltime + dangling + tend; // show gyro-propagation messages GCPMessages(pointing,totaltime,tend); // Return all the times needed in the observing mode modules return {totaltime,{inttime,pointing,data_time,loadlength,n_chop,eff_resolution,initlength,dangling}}; } ///////////////////////////////////////////////////////////////////////////// // Procedure to perform the noise level evaluation for the OTF observing mode {double,double,double,double,double} procedure OTFFSwitch_noisecomputer { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF int nlines_tot = 1; // Number of rows in the map int data_time = 4; // chunk size given by the data rates and optimum speed int n_switch_on = 1; // Supersamplingfactor int n_linesperscan = 2; // Number of lines between two OFFs int off_inttime = 16; // Integration time per OFF phase int n_cycles = 1; // Number of map coverages double tscan = 60.0; // Total average duration of one scan {double,double,double,double,double} tact = {10.0,4.9,4.9,0.05,0.05}; // Field of actual dead and integration times }{ // The sum of drift noise and radiometric noise is computed. // double tdead = tact{0}; // Average total dead time in one scan double inttimeperonphase = tact{1}; // Actual integration time in ON phase double inttimeperoffphase = tact{2}; // Actual integration time in OFF phase double deadtimeperonphase = tact{3}; // Dead time per switch phase on ON // Get parameters which are needed double tsys = InterpolateTsys(band,lo_freq); double eta_mb = InterpolateCoupling(band,lo_freq); double[] gssb = InterpolateGssb(band,lo_freq); // Get the drift parameters to compute the drift noise double[] allanparms = InterpolateSpecAllan(band,lo_freq,oneGHzReference); // rescale to frequency resolution double alpha = allanparms[1]; double binningexp = 1.0 / allanparms[2]; double allan_time_lores = allanparms[0] * pow(1.0 / eff_resolution{1},binningexp); double allan_time_hires = allanparms[0] * pow(1.0 / eff_resolution{0},binningexp); // Differential Allan variance allanparms = InterpolateSpecFSwitchAllan(band,lo_freq,oneGHzReference); // rescale to frequency resolution double dalpha = allanparms[1]; binningexp = 1.0 / allanparms[2]; double dallan_time_lores = allanparms[0] * pow(1.0 / eff_resolution{1},binningexp); double dallan_time_hires = allanparms[0] * pow(1.0 / eff_resolution{0},binningexp); // resolution of OFF phase double sw_resolution = GetFSwitchSWResolution(band,lo_freq); double sw_resolution_lores = max(eff_resolution{1},sw_resolution); double sw_resolution_hires = max(eff_resolution{0},sw_resolution); // !!!! The computation of the noise is formally NOT CORRECT for this // !!!! case. For simplicity we use as a rough approximations the equations // !!!! for a double-difference setup instead of a difference with // !!!! OTF scheme !!! // Compute the relative noise for the detailed timing double on_int = double(2 * data_time * n_switch_on); // correct for double scan - treat like integrated in one go if(nlines_tot == 1 && n_linesperscan > 1) { on_int = on_int * double(n_linesperscan); } // fudge factor to taking OFF interpolation into account double off_int = double(off_inttime) * 1.5; // The dead time per switch might deviate between ON and OFF - ignored double deadtimeperswitch = deadtimeperonphase; // Dead time includes other points, but excludes off_int fudging // This is slightly too small (excludes inner point dead time) - ignored double tdiff = max(tscan - on_int - off_int,0.0); // Get actual noise // This is returned twice: for both limiting resolutions double systemnoise_lores = DoubleDifferenceNoise(inttimeperonphase / allan_time_lores,[inttimeperoffphase / inttimeperonphase,sw_resolution_lores / eff_resolution{1},on_int / allan_time_lores,off_int / allan_time_lores,deadtimeperswitch / allan_time_lores,tdiff / allan_time_lores,alpha,dallan_time_lores / allan_time_lores,dalpha]); double systemnoise_hires = DoubleDifferenceNoise(inttimeperonphase / allan_time_hires,[inttimeperoffphase / inttimeperonphase,sw_resolution_hires / eff_resolution{0},on_int / allan_time_hires,off_int / allan_time_hires,deadtimeperswitch / allan_time_hires,tdiff / allan_time_hires,alpha,dallan_time_hires / allan_time_hires,dalpha]); double noiseratio = DoubleDifferenceNoiseRatio(inttimeperonphase / allan_time_lores,[inttimeperoffphase / inttimeperonphase,sw_resolution_lores / eff_resolution{1},on_int / allan_time_lores,off_int / allan_time_lores,deadtimeperswitch / allan_time_lores,tdiff / allan_time_lores,alpha,dallan_time_lores / allan_time_lores,dalpha]); // Compute total double sideband noise // Correct for signal in both pases double dsbnoise_lores = tsys * sqrt(systemnoise_lores / (eff_resolution{1} * 2000000.0 * double(n_cycles) * tscan)); double dsbnoise_hires = tsys * sqrt(systemnoise_hires / (eff_resolution{0} * 2000000.0 * double(n_cycles) * tscan)); // Translate to the main beam scale, correct for eta_mb // (This is typically not done at ground based telescopes, // but leads often to problems there - to be discussed.) dsbnoise_lores = dsbnoise_lores / eta_mb; dsbnoise_hires = dsbnoise_hires / eta_mb; // Get single sideband noise equivalent double usbnoise_lores = dsbnoise_lores / gssb[0]; double usbnoise_hires = dsbnoise_hires / gssb[0]; double lsbnoise_lores = dsbnoise_lores / gssb[1]; double lsbnoise_hires = dsbnoise_hires / gssb[1]; // Return noise values and the maximum ratio of drift to radiometric noise return {usbnoise_lores,usbnoise_hires,lsbnoise_lores,lsbnoise_hires,noiseratio}; } //!!!!!!!!!!!!!!!!!!!! // Associated blocks //!!!!!!!!!!!!!!!!!!!! // LO settling time for a LO sub-band change, 1st block // Block for first tuning block LO_Settling_time_first_tuning_fm HIFI 3680 { string band_a = "1a" in ["1a","2a","3a","4a","5a","6a","7a"]; // HIFI band a int int_time1 = 3600; //Integration time after first tuning double lo_freq_a = 500.0; //LO frequency in sub-band a string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); // //Init and tune of LO: configuration from safe to tuned. LCU_config_nominal_proc_fm(band_a,lo_freq_a); LO_tuning_w_mixerchoice_proc(band_a,lo_freq_a,"H"); // //Configure spectroscopy integration Configure_Spectrometer_proc_fm(band_a,int_time1,["wb1","wb1"],backend); //4 sec. integration //Take series of spectra during int_time1 seconds HIFI_Spectr_total_power_proc_fm(band_a,backend,int_time1); // //Now switch off LO sub-band LCU_switch_off_proc_fm(); } //HIFI vector scan, block for experts: allow all vector scan parameters as user input //Check vector scan with some default parameters block Vector_scan_EXPERT_block_fm HIFI 3671 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency double step_drain2_v = 0.05; //D2_V steps during vector scan int nsteps = 10; //Number of steps. Should not be larger than 10 double step_time = 1.0; //In seconds. double drain2_v_start = 1.5; //Starting D2_V in vector scan }{ //Clear potential failure mode Set_LO_Nominal_proc_fm(); // //Start_block(); //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; //double drain2_v_start = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlcu,["drain2_v"],band,lo_freq); double drain2_safe = result[0]{0}; // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // result = ConfigurationReader(name_configlotune,["step_drain2_v","nsteps","step_time"],band,lo_freq); //double step_drain2_v = result[0]{0}; //int nsteps = iround(result[1]{0}); //double step_time = result[2]{0}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // //Load vector scan //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Load_vector_safe_1a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "1b") { //Band 1b Hifi_HIFI_Load_vector_safe_1b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2a") { //Band 2a Hifi_HIFI_Load_vector_safe_2a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2b") { //Band 2b Hifi_HIFI_Load_vector_safe_2b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3a") { //Band 3a Hifi_HIFI_Load_vector_safe_3a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3b") { //Band 3b Hifi_HIFI_Load_vector_nom_3b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "4a") { //Band 4a Hifi_HIFI_Load_vector_safe_4a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "4b") { //Band 4b Hifi_HIFI_Load_vector_safe_4b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "5a") { //Band 5a Hifi_HIFI_Load_vector_nom_5a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "5b") { //Band 5b Hifi_HIFI_Load_vector_nom_5b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6a") { //Band 6a Hifi_HIFI_Load_vector_nom_6a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6b") { //Band 6b Hifi_HIFI_Load_vector_nom_6b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7a") { //Band 7a Hifi_HIFI_Load_vector_nom_7a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7b") { //Band 7b Hifi_HIFI_Load_vector_nom_7b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } // //delay(1); //Execute vector scan Hifi_HIFI_vector_scan($BBID); double time_needed = double(nsteps) * step_time; delay(iround(time_needed + 2.0 + 0.5)); //0.5s added for completion of load_vector //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } //////////////////////////////////// // OTF load-chop observing mode // {string,double,double}[] procedure HifiMappingProcLoadChopOTFSequencerInit { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source double raoff = 0.0; // RA coordinate of the OFF position double decoff = 0.0; // DEC coordinate of the OFF position {double,double} lineDistance = {0.0050,0.0050}; // Distance between subsequent rows int nlines = 1 in [1,240]; // Number of rows in the map double stepsize = 0.0050 in [0.0,0.13333]; // Distance between subsequent points in the OTF line int npoints = 10 in [1,720]; // Number of data dumps per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // chunk size given by the data rates and optimum speed int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 1 in [1,1800]; // Supersamplingfactor int n_switch_off = 3 in [1,3600]; // Number of data dumps for the OFF integration time int n_linesperscan = 1 in [1,32]; // Number of lines between two OFFs int n_cycles = 1 in [1,1200]; // Number of map coverages int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode // limit on data rate {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // limits from noise section {double,double,double,double} phaselengths = LoadChopPhaseLengths(band,lo_freq,effResolution,oneGHzReference); // Compute derived quantities // Main loop int main_phase = iceil(phaselengths{0}); // How many lines could we do at most? int n_linesperscan_guess = main_phase / (2 * datalimit) + 1; n_linesperscan_guess = imax(n_linesperscan_guess * n_linesperscan_guess / npoints,1); // restrict the scan size if(nlines == 1 && n_linesperscan_guess > 1) { n_linesperscan_guess = 2; } else { n_linesperscan_guess = IMultiple(n_linesperscan_guess,nlines); n_linesperscan_guess = imin(n_linesperscan_guess,nlines); } int n_linesperscan_range = 1 - n_linesperscan_guess; if(n_linesperscan_range == 0) { n_linesperscan_range = 1; } double n_pointsperscan = double(n_linesperscan * npoints); // Compute back int int_time_guess = main_phase / iceil(sqrt(n_pointsperscan)); int data_time_guess = imin(imax(iceil(phaselengths{1}),datalimit),20); int n_switch_on_guess = imax(int_time_guess / (2 * data_time_guess),1); int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } data_time_guess = imax(imin(5,int_time_guess / (2 * n_switch_on_guess)),datalimit); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } // OFF phase int data_time_off_guess = imin(imax(iceil(phaselengths{2}),datalimit),20); int data_time_off_range = datalimit - data_time_off_guess; if(data_time_off_range == 0) { data_time_off_range = 1; } int n_switch_off_guess = imax(iceil(double(data_time_guess * n_switch_on_guess) * 0.67 * sqrt(n_pointsperscan) / (double(data_time_off_guess) * sqrt(phaselengths{3} / effResolution{1}))),1); int n_switch_off_range = 1 - n_switch_off_guess; if(n_switch_off_range == 0) { n_switch_off_range = 1; } // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"data_time_off",double(data_time_off_guess),double(data_time_off_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)},{"n_switch_off",double(n_switch_off_guess),double(n_switch_off_range)},{"n_linesperscan",double(n_linesperscan_guess),double(n_linesperscan_range)}]; return retvalues; } ////////////////////////////////////////////// // Testmodes for TV specific activities // They are usually concatenation of // existing modules, here gathered for // a simpler execution // // // DT - 08-02-08: first version ////////////////////////////////////////////// //modes: see fm_testmodes.cus //////////////////////////////////// //Special blocks taken from MOC_CUS //////////////////////////////////// // Diplexer calibration for a given mixer band // uses a list of pre-defined frequencies where to measure // the diplexer scan. procedure Diplexer_survey_proc_TV { string band = "3a" in ["3a","3b","4a","4b","6a","6b","7a","7b"]; // HIFI band }{ // //Get the list of frequencies to be used for the scan string tab = "config_dipscan_TV.config"; double bandnb = GetBandCode(band); double lofreqlow = dlookup(tab,"" + iceil(bandnb),"lofreqlow"); double lofreqhigh = dlookup(tab,"" + iceil(bandnb),"lofreqhigh"); double lofreqstep = dlookup(tab,"" + iceil(bandnb),"lofreqstep"); // LCU_switchon_proc_fm(band); //Wait an extra delay of 1 min for short term stabilization delay(60); // //Start loop on diplexer scans double current_LO = lofreqlow; bool endreached = false; //Loop on key frequencies per LO band while(current_LO <= lofreqhigh && endreached == false) { Check_Band_vs_Freq_proc_fm(band,current_LO); //Configure FPU at that frequency Init_MSA_HBB_fm(band,"CLOSE",current_LO,"ON"); //Perform LO tuning at that frequency //This needs to be done at 0.6mV bias due to Imix target LO_tuning_block_fm(band,current_LO); // //Prepare for diplexer scan //In case of band 6 or 7, use special biases if(band == "6" || band == "7") { {double,string}[] result = ConfigurationReader("name_confilfpu",["bias_dipscan_h","bias_dipscan_v","bias_max_h","bias_max_v"],band,current_LO); //First go to 4mV Mixerbias_block_fm(result[2]{0},result[3]{0}); //Then to 3mV Mixerbias_block_fm(result[0]{0},result[1]{0}); } // //Perform diplexer scan at that frequency and M1 setting double diplexer_current_min_h = -2.24; double diplexer_current_max_h = 2.24; double diplexer_current_step = -0.073; //i.e. approx 4.48/61 int n_steps = 61; double stepTime = 0.1; // Scan_diplexer_block_fm(band,diplexer_current_max_h,diplexer_current_max_h,diplexer_current_step,n_steps,stepTime); // //Check last LO freq done if(current_LO == lofreqhigh && endreached == false) { endreached = true; } //Increase LO freq: truncate if step too high current_LO = current_LO + lofreqstep; if(current_LO > lofreqhigh && endreached == false) { current_LO = lofreqhigh; } // } //Close-off loop //In case of band 6 or 7,go back to nominal values if(band == "6" || band == "7") { result = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,current_LO); //First go to 4mV Mixerbias_block_fm(result[0]{0},result[1]{0}); //Then to nominal result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,current_LO); Mixerbias_block_fm(result[0]{0},result[1]{0}); } } //Set DC bias without switching on the chain, block //All input parameters shall be given by the user block Conf_diag_LCU_EXPERT_block_fm HIFI 3678 { }{ error("Obsolete block. Use Conf_diag_LCU_block_fm HIFI instead"); } //Generic procedure to send chopper angle using the adequate instrument side procedure HIFI_CPR_Chopper_Rot_proc_fm { double targetAngle = -4.0 in [-8.88,8.5]; // HF_CPR_Chopper_Rot }{ //check prime or redundant keyword {double,string}[] result_d = ConfigurationReader("name_chopper",["prime_or_redundant"],"0",0.0); if(result_d[0]{1} == "prime") { Hifi_HIFI_P_Chopper_Rot($BBID,targetAngle); } else { Hifi_HIFI_R_Chopper_Rot($BBID,targetAngle); } } // BLOCK : Functional Test No 2 (HRS Square M Internal Test) block HRS_functional_test_No_2_Square_m_block_fm HIFI 3622 { string band = "1a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int integ_time = 4; //Total integration time in sec. string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); int repeats = 5; //string[] hrsh_blocks_configuration = ["Square_m_ultra","Square_m_wide","Square_m_low","Square_m_nominal","Square_m_high"]; //Fill in block parameter names for each mode - consequence of SPR-0198 string[] hrs_blocks_square_m_ultra = ["square_m_ultra","square_m_ultra","square_m_ultra","square_m_ultra","square_m_ultra","square_m_ultra","square_m_ultra","square_m_ultra"]; string[] hrs_blocks_square_m_wide = ["square_m_wide","square_m_wide","square_m_wide","square_m_wide","square_m_wide","square_m_wide","square_m_wide","square_m_wide"]; string[] hrs_blocks_square_m_low = ["square_m_hilonom","low","square_m_low","low_nominal","square_m_low_nom","low","square_m_low","high_nominal_low"]; string[] hrs_blocks_square_m_nom = ["square_m_hilonom","high_nominal","high_nominal","low_nominal","square_m_low_nom","high_nominal","high_nominal","high_nominal_low"]; string[] hrs_blocks_square_m_high = ["square_m_hilonom","high_nominal","high_nominal","high","high","high_nominal","high_nominal","high_nominal_low"]; // Configure spectroscopy Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); // // Configure LO and attenuators //============================= HRS_config_att_lo_fm(band,hrs_mode); // // Loops on the different configurations of the HRS //====================================== //Calls the 5 modes to be checked //Square_M_ultra Hifi_HIFI_Config_HRS_H_blocks($BBID,hrs_blocks_square_m_ultra[0],hrs_blocks_square_m_ultra[1],hrs_blocks_square_m_ultra[2],hrs_blocks_square_m_ultra[3],hrs_blocks_square_m_ultra[4],hrs_blocks_square_m_ultra[5],hrs_blocks_square_m_ultra[6],hrs_blocks_square_m_ultra[7]); //delay(1); Hifi_HIFI_Config_HRS_V_blocks($BBID,hrs_blocks_square_m_ultra[0],hrs_blocks_square_m_ultra[1],hrs_blocks_square_m_ultra[2],hrs_blocks_square_m_ultra[3],hrs_blocks_square_m_ultra[4],hrs_blocks_square_m_ultra[5],hrs_blocks_square_m_ultra[6],hrs_blocks_square_m_ultra[7]); delay(1); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // //Square_M_wide Hifi_HIFI_Config_HRS_H_blocks($BBID,hrs_blocks_square_m_wide[0],hrs_blocks_square_m_wide[1],hrs_blocks_square_m_wide[2],hrs_blocks_square_m_wide[3],hrs_blocks_square_m_wide[4],hrs_blocks_square_m_wide[5],hrs_blocks_square_m_wide[6],hrs_blocks_square_m_wide[7]); //delay(1); Hifi_HIFI_Config_HRS_V_blocks($BBID,hrs_blocks_square_m_wide[0],hrs_blocks_square_m_wide[1],hrs_blocks_square_m_wide[2],hrs_blocks_square_m_wide[3],hrs_blocks_square_m_wide[4],hrs_blocks_square_m_wide[5],hrs_blocks_square_m_wide[6],hrs_blocks_square_m_wide[7]); delay(1); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // //Square_M_low Hifi_HIFI_Config_HRS_H_blocks($BBID,hrs_blocks_square_m_low[0],hrs_blocks_square_m_low[1],hrs_blocks_square_m_low[2],hrs_blocks_square_m_low[3],hrs_blocks_square_m_low[4],hrs_blocks_square_m_low[5],hrs_blocks_square_m_low[6],hrs_blocks_square_m_low[7]); //delay(1); Hifi_HIFI_Config_HRS_V_blocks($BBID,hrs_blocks_square_m_low[0],hrs_blocks_square_m_low[1],hrs_blocks_square_m_low[2],hrs_blocks_square_m_low[3],hrs_blocks_square_m_low[4],hrs_blocks_square_m_low[5],hrs_blocks_square_m_low[6],hrs_blocks_square_m_low[7]); delay(1); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // //Square_M_nominal Hifi_HIFI_Config_HRS_H_blocks($BBID,hrs_blocks_square_m_nom[0],hrs_blocks_square_m_nom[1],hrs_blocks_square_m_nom[2],hrs_blocks_square_m_nom[3],hrs_blocks_square_m_nom[4],hrs_blocks_square_m_nom[5],hrs_blocks_square_m_nom[6],hrs_blocks_square_m_nom[7]); //delay(1); Hifi_HIFI_Config_HRS_V_blocks($BBID,hrs_blocks_square_m_nom[0],hrs_blocks_square_m_nom[1],hrs_blocks_square_m_nom[2],hrs_blocks_square_m_nom[3],hrs_blocks_square_m_nom[4],hrs_blocks_square_m_nom[5],hrs_blocks_square_m_nom[6],hrs_blocks_square_m_nom[7]); delay(1); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // //Square_M_high Hifi_HIFI_Config_HRS_H_blocks($BBID,hrs_blocks_square_m_high[0],hrs_blocks_square_m_high[1],hrs_blocks_square_m_high[2],hrs_blocks_square_m_high[3],hrs_blocks_square_m_high[4],hrs_blocks_square_m_high[5],hrs_blocks_square_m_high[6],hrs_blocks_square_m_high[7]); //delay(1); Hifi_HIFI_Config_HRS_V_blocks($BBID,hrs_blocks_square_m_high[0],hrs_blocks_square_m_high[1],hrs_blocks_square_m_high[2],hrs_blocks_square_m_high[3],hrs_blocks_square_m_high[4],hrs_blocks_square_m_high[5],hrs_blocks_square_m_high[6],hrs_blocks_square_m_high[7]); delay(1); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // //} } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // The procedures //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //Force boot, procedure: NOT LONGER USED, USE BLOCK INSTEAD procedure HIFI_force_boot_proc_ops { int partition_ID = 0; //0 if forceboot_default. Partition ID in case it should be used. }{ if(partition_ID == 0) { mois_comment("ICU booted using default partition."); Hifi_HIFI_force_bootdefault(); } else { mois_comment("ICU booted using partition # " + partition_ID); Hifi_HIFI_force_bootpartition(partition_ID); } mois_tmcheck("Verify HIFI HK telemetry packets (3,25,1025) - HIFI_PERIODIC_HK - are arriving every 4 seconds."); //mois_tmcheck("Verify that no (5,4) telemetry packet has been received from HIFI."); delay(5); } ////////////////////////////////////////////////////////////////////////// // Procedure to compute detailed timing of OTF observing mode {int,{int,int,int,int,bool,int,int},double,double} procedure OTFDoubleChopNoRef_post_timing { {int,int,int,int,bool,int,int} timing = {21,1780,1,21,false,50,0}; // pre_timing parameter list int[] telescopetimes = [300,180,2,2,40,10,20,0]; int nlines = 1; // Number of rows in the map int data_time = 4; // chunk size given by the data rates and optimum speed int n_cycles = 1; // Number of map coverages }{ // Get all values from the pre_timing section int loadlength = timing{0}; int load_spacing = timing{1}; int n_loadinterval = timing{2}; int lineint = timing{3}; bool end_load_on = timing{4}; int initlength = timing{5}; int dangling = timing{6}; // Get all values from the telescope section int telinit = telescopetimes[1]; // Initial slew time int tacc = telescopetimes[2]; // Acceleration towards line int tdec = telescopetimes[3]; // Deceleration from line int tturn = telescopetimes[5]; // Turn around between lines int tline = telescopetimes[4]; // Time in line int trep = telescopetimes[6]; // Time between two repetitions int tend = telescopetimes[7]; // Final deceleration time // Check the length of the telescope slew relative to the integration time if(tline < lineint) { CError("OTF scan length returned by telescope too short for instrument."); } // Now we can actually determine n_loadinterval including the overheads int lineduration = tline + tturn + imax(trep - tturn,0) / nlines; n_loadinterval = load_spacing / lineduration; if(n_loadinterval < 1) { SError("Scan duration too long for load period. " + "Reduce the number of chop cycles."); } // Make sure that load slews occur at the same position in each coverage int nlines_tot = nlines * n_cycles; n_loadinterval = IMultiple(n_loadinterval,nlines); // If no load required parameter has to be 0 if(n_loadinterval > nlines_tot) { // Determine need for final load measurement double rest = double(nlines_tot % n_loadinterval) + 0.5; end_load_on = rest > 0.5001 * double(n_loadinterval); } else { if(n_loadinterval > nlines) { n_loadinterval = nlines; } // In all these cases a final load will be made anyway in regular pattern end_load_on = false; } // Hold time needed for load // To use the state machine we waste the deceleration time // which could be used in principle for the load measurement as well int tover = imin(tturn - tdec,trep + tacc); int holdlength = imax(loadlength - tover,0); // Dangling load measurement if(end_load_on) { dangling = loadlength; } else { // whenever a load occurs we also have one at the end if(n_loadinterval <= nlines_tot) { dangling = loadlength - holdlength; } } int closelength = duration(HIFICloseObs()); dangling = imax(dangling + closelength - tend,0); // Compute duration of measurement int n_load = nlines_tot / n_loadinterval; int maptime = nlines_tot * (tline + tturn) + n_cycles * (trep + tacc + tdec - tturn) + n_load * holdlength; // Telescope dead time irelevant for mode without baseline reference double tdead = 0.0; // Cycle given by switch cycle double tscan = 2.0 * double(data_time); // The initial time is no longer contained in the total time // int totaltime=imax(initlength,telinit); int totaltime = maptime + dangling - trep + tend; // show gyro-propagation messages // no gyro-propagation for line_scan_pointing GCPMessages(0,maptime,tend); // Return all the times needed in the observing mode modules return {totaltime,{loadlength,load_spacing,n_loadinterval,holdlength,end_load_on,initlength,dangling},tscan,tdead}; } // Set the whole instrument to standby II mode from primary // This will set the FPU to band 0, backend in standby, and LO in standby // Will keep HBB, upconverters, chopper on mode HifiManCmd_HIFI_primary_to_standbyII { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! string laser_H = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-V laser to be set ON string chopper_loop = "OPEN" in ["OPEN","CLOSE"]; //chopper loop status string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ Mode_status_check_primary(laser_H,laser_V,chopper_loop); //Standby should always correspond to band0, lofreq=0 string band = "0"; double lo_freq = 0.0; mois_comment("Set HIFI to standby mode II with " + laser_H + " kept on and chopper loop " + chopper_loop); StartMode_block_ops(); //Needs to duplicate hrs_mode word: string[] hrs_mode = ["wb","wb"]; //LO stand-by. mois_step("Set LOU to standby mode"); mois_comment("Switch off LSU RF"); LCU_switch_off_block_ops(); mois_comment("Switch to standby"); LCU_standby_block_ops(); //FPU stand-by mois_step("Set HIFI FPU to standby mode with internal load heater kept ON"); string chop_startup_prime_red = "chop_startup_cold_prime"; if(prime_or_redundant == "Red") { chop_startup_prime_red = "chop_startup_cold_red"; } {double,string}[] result = ConfigurationReader("name_chopper",[chop_startup_prime_red],"0",0.0); if(chopper_loop == "OPEN") { result = ConfigurationReader("name_chopper",["chop_startup_warm"],"0",0.0); } Init_MSA_ops("0",chopper_loop,0.0,result[0]{0},"ON",prime_or_redundant); //HRS stand-by mois_step("Set HIFI HRS-H and HRS-V spectrometers to standby"); HRS_standby_block_ops(band,hrs_mode); //WBS stand-by mois_step("Set HIFI WBS-H and WBS-V spectrometers to standby"); WBS_standby_block_ops(band,laser_H,laser_V); // StopMode_block_ops(); Mode_status_check_standby_II(laser_H,laser_V,chopper_loop,"down",prime_or_redundant); } {int,double,double,double,double,double} obs HifiSScanModeFSwitchNoRef { string modeName = "fs-freq"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_cycles = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles per frequency and pointing int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode OpenMessages("HIFI Spectral Scan - Frequency Switch noRef",{data_time,0,0,0,0,0,0,n_freq_point,n_cycles,load_interval}); // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,redundancy,wbs1Used,wbs2Used,data_time); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; ////////////////////////////////////////////////////////////////////// // Call first part of the timing computer {{int,int,int,int,int,int,bool,int,int},{int,double,double[],int[][],bool,double[],int,bool}} pre_timing = SScanFSwitchNoRef_pre_timing(band,lo_freq,lo_freq_up,redundancy,freq_throw,effResolution,hr1,hr2,wb1,wb2,data_time,n_cycles,n_freq_point,load_interval,docommands); // frequency parameters int groupnumber = pre_timing{1}{0}; double reffreq = pre_timing{1}{1}; double[] freqgrid = pre_timing{1}{2}; int[][] grouporder = pre_timing{1}{3}; bool retuning = pre_timing{1}{4}; double[] targetlevels = pre_timing{1}{5}; int nfreq_if = pre_timing{1}{6}; bool dsb = pre_timing{1}{7}; ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,double,double,int} tpar = Fine_telescope(naifid,onPosition,band,reffreq,pre_timing{0}); // Dummy call to spacecraft command int[] telescopetimes = basic_fine_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9}); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,bool,int,int},double,double} post_timing = SScanChopNoRef_post_timing(pre_timing{0},telescopetimes); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = Fine_telescope(naifid,onPosition,band,reffreq,post_timing{1}); // Call telescope command telescopetimes = basic_fine_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9}); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following // normal pre_timing values int loadlength = post_timing{1}{2}; int n_per_on = post_timing{1}{4}; int n_load_on = post_timing{1}{5}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { SScanFSwitchNoRef_commanding(band,reffreq,freq_throw,effResolution,hr1,hr2,wb1,wb2,n_freq_point,grouporder,freqgrid,retuning,targetlevels,data_time,n_per_on,n_load_on,groupnumber,startobs,telescopetimes,loadlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double} tact = SingleChop_deadtimes("fs",band,reffreq,hr1,hr2,wb1,wb2,data_time,n_per_on); double tscan = 2.0 * (tact{1} + tact{2}); double tdead = 2.0 * tact{2}; // // Call noise computer {double,double,double,double,double} noisevalues = SScanChopNoRef_noisecomputer(band,reffreq,nfreq_if,dsb,effResolution,n_per_on * imax(n_load_on,1),true,tscan,tdead); // Evaluate performance SScanChopNoRef_performance(band,reffreq,nfreq_if,dsb,effResolution,noisevalues,timeTaken,n_per_on * imax(n_load_on,1),groupnumber * n_freq_point,true,tscan,tdead); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } //////////////////////////////////// // DBS raster observing mode // // Combination of four modules implementing the new structure // // Return time and noise levels {int,double,double,double,double,double} obs HifiMappingProcDBSRaster { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source {double,double} lineDistance = {0.0050,0.0050}; // Distance between subsequent rows int nlines = 1 in [1,100]; // Number of rows in the map double stepsize = 0.0050 in [5.5556E-4,0.13333]; // Distance between subsequent points in the raster line int npoints = 10 in [2,100]; // Number of points per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_switch_on = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Mapping - DBS Raster Map slowChop",{data_time,0,0,n_switch_on,0,0,n_pointsperscan,0,n_cycles,load_interval}); // Call first part of the timing computer {int,int,int,int,int,int,int,int,int,int,int,int,int} pre_timing = DBSRaster_pre_timing(nlines,npoints,band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_switch_on,n_pointsperscan,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; // Check for NoddingInRaster or NoddingOfRaster int scansize = pre_timing{10}; if(scansize > 1) { {int,int,int,string,int,double,double,bool,double,double,double,int,int,double,double,int,int,double,double,int,int,int,int,int} tmpar = DBSMultiRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",pre_timing,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = nodding_of_raster_pointing(false,tmpar{0},tmpar{1},tmpar{2},tmpar{3},tmpar{4},tmpar{5},tmpar{6},tmpar{7},tmpar{8},tmpar{9},tmpar{10},tmpar{11},tmpar{12},tmpar{13},tmpar{14},tmpar{15},tmpar{16},tmpar{17},tmpar{18},tmpar{19},tmpar{20},tmpar{21},tmpar{22},tmpar{23}); } else { {int,int,int,string,int,double,double,bool,double,double,double,int,int,double,double,int,int,int,double,double,int,int,int,double,double,int,int,int,int} tpar = DBSRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",pre_timing,n_cycles); telescopetimes = nodding_raster_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23},tpar{24},tpar{25},tpar{26},tpar{27},tpar{28}); } ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,int},bool,double,double} post_timing = DBSRaster_post_timing(pre_timing,telescopetimes,nlines,npoints,n_switch_on,n_cycles,load_interval,false); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command if(scansize > 1) { tmpar = DBSMultiRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",post_timing{1},n_cycles); // Call telescope command telescopetimes = nodding_of_raster_pointing(true,tmpar{0},tmpar{1},tmpar{2},tmpar{3},tmpar{4},tmpar{5},tmpar{6},tmpar{7},tmpar{8},tmpar{9},tmpar{10},tmpar{11},tmpar{12},tmpar{13},tmpar{14},tmpar{15},tmpar{16},tmpar{17},tmpar{18},tmpar{19},tmpar{20},tmpar{21},tmpar{22},tmpar{23}); } else { tpar = DBSRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",post_timing{1},n_cycles); telescopetimes = nodding_raster_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23},tpar{24},tpar{25},tpar{26},tpar{27},tpar{28}); } // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{3}; int n_load = post_timing{1}{6}; int n_loadinterval = post_timing{1}{7}; int n_seq = post_timing{1}{8}; int initlength = post_timing{1}{11}; int dangling = post_timing{1}{12}; bool final_load = post_timing{2}; double tscan = post_timing{3}; double tdead = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { DBSRaster_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_seq,n_cycles,scansize,n_loadinterval,n_load,final_load,startobs,telescopetimes,loadlength,false); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double} tact = DBSRaster_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_seq,n_load,scansize,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = DBS_noisecomputer(band,lo_freq,effResolution,continuumDetection,oneGHzReference,n_cycles,tscan,tact); // Evaluate performance DBSRaster_performance(band,lo_freq,effResolution,noisevalues,timeTaken,nlines,npoints,n_cycles,n_seq * imax(n_load,1),tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } //////////////////////////////////////// // Procedure to calculate the pre timing // {int,int,int,int,int,int,int,int,int,bool,int,int,int} procedure DBS_pre_timing { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_chop = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per pointing int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // First check validity of frequencies CheckLOFrequencies(band,lo_freq,lo_freq); // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // First perform consistency checks // Check chunk size given by the data rates CheckDataTaking(backendreadoutparms,data_time); int jitterdead = GetMaxTimeJitter(band,lo_freq); // Compute parameters for the instrument timing int inttime = 2 * n_chop * data_time; int readouttime = data_time; // compute load integration time int loadlength = duration(LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms)); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); loadlength = loadlength + readoutdead; // For double phases I can use the added jitterdead in both phases for load int halfloadlength = (loadlength - jitterdead + 1) / 2; // Compare load interval and nodding interval // This determines the order of the loops int load_spacing = CheckedLoadSpacing(load_interval - loadlength,8); int n_load = inttime / load_spacing; if(load_spacing > 2 * inttime) { int n_seq = n_chop; bool end_load = false; int pointing = inttime + jitterdead; int shiftlength = 0; } else { n_seq = n_chop / (n_load + 1); if(n_seq < 1) { SError("Chop phase length too long relative to load period."); } end_load = true; inttime = 2 * n_seq * (n_load + 1) * data_time; pointing = inttime + halfloadlength + n_load * loadlength + jitterdead; shiftlength = halfloadlength; } // Duration of initial set up // determine exact duration only in case of full commanding if(docommands) { int initlength = duration(HIFIInitObs()); initlength = initlength + duration(TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal")); // Add time for HK readout int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); initlength = initlength + hkduration; } else { initlength = GetRoughInitLength(band,lo_freq,false); } initlength = initlength + loadlength; // Compute the overall cycle length // First estimate of the load interval int n_loadinterval = imax(load_interval / (2 * pointing),1); // dangling time given by readout dead time int dangling = readoutdead; // Return all the times needed for telescope call and post_timing processing return {inttime,pointing,readouttime,loadlength,jitterdead,load_spacing,n_load,n_loadinterval,n_seq,end_load,shiftlength,initlength,dangling}; } ///////////////////////////////////////////////////////////////// // Procedure to compute detailed timing for the mode // int procedure Overhead_timing { {double,double} onposition = {0.0,0.0}; // Coordinates of the source {double,double} offposition = {0.2,0.2}; // Coordinates of the OFF position string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int clustered = 0; // whether observation is part of spatial/frequency cluster int data_time = 4 in [0,5]; // data dump interval limited by the data rates }{ ////////////////////////////////////////////////////////////////////// // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Interpret data_time=0 as fast-chop if(data_time == 0) { int load_datatime = GetStdLoadReadout(band,lo_freq); CheckDataTaking(backendreadoutparms,load_datatime); } else { load_datatime = data_time; CheckDataTaking(backendreadoutparms,data_time); } // Compute parameters for the instrument timing int pointing = load_datatime; // Resulting integer integration time // compute load integration time int loadlength = duration(LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms)); // Duration of initial set up if(clustered == 1) { int initlength = 0; } else { initlength = duration(TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal")); } initlength = initlength + loadlength; return initlength; } // Spectra obtained with the mixer bias high in the resistive region block Spectra_resistive_high_fm HIFI 3230 { string band = "1a"; double bias_h = 0.0; double bias_v = 0.0; int integ_time = 4; //Total integration time in sec.: at least 2sec ! string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); Mixerbias(bias_h,bias_v); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // } //Load new OBSW , block block Patch_OBSW_block_ops HIFI 7928 { }{ mois_comment("Assign obsid number to procedure execution"); mois_spacon("In the following command, the second parameter (OBS_ID) shall be replaced by a Formal Parameter value according to the list provided by the instrument ICC."); Hifi_HIFI_Set_OBS_ID($BBID,$OBSID); // mois_step("Copying OBSW to PM-high"); int hifi_OBS_destination = 0x3ffff; // OBS_destination: start of PM high int hifi_OBS_copy_length = 0x20000; // OBS_copy_length Hifi_HIFI_copy_mem_to_high(hifi_OBS_destination,hifi_OBS_copy_length); delay(1); // mois_step("Construct the OBSW patch"); mois_spacon("Use the OBSM to prepare the HIFI_load_PRAM TC list to build the patched OBSW that is to be loaded"); // mois_step("Upload the OBSW patch to PM-high"); mois_spacon("Use the OBSM to run the TC list previously prepared to load the patch of the OBSW. Please be aware at the copy should start from address 0x3ffff."); // mois_step("Verify integrity of copied OBSW"); //Check PM memory for OBS 5.4: need to put offsets of starting address for PM high mois_spacon("In the following command, the three parameters will be replaced by Formal Parameters provided by the instrument ICC."); int check_start = 0x5500 + 0x3ffff; int check_end = 0x17d0b + 0x3ffff; int check_crc = 0x31a0; Hifi_HIFI_check_PM_memory(check_start,check_end,check_crc); delay(3); mois_spacon("Checks TBD"); // mois_step("Copying uploaded OBSW to DM-low"); hifi_OBS_destination = 0x3ffff; // OBS_destination: start of PM high hifi_OBS_copy_length = 0x20000; // OBS_copy_length Hifi_HIFI_copy_mem_to_low(hifi_OBS_destination,hifi_OBS_copy_length); delay(1); //The new OBSW should be booted mois_tmcheck("Check that the new OBSW patch number HI_SW_Patch has been updated"); } ///////////////////////////////////////////////////////////////// // Auxiliary routine to restrict data_time to match the pointing // requirements condition: tpos >=10s {int,int} procedure MatchMinPointing { int data_time_guess = 4; // initial guess for data_time int data_time_range = 1; // initial guess for range int n_switch = 1; // Number of switches with data_time }{ // pointing requirements condition: >=10s // one second is always added for command jitter if(n_switch * data_time_guess < 9) { data_time_guess = 8 / n_switch + 1; data_time_range = 1; } return {data_time_guess,data_time_range}; } //Stopmode procedure StopMode_TEI { }{ {double,string}[] result = ConfigurationReader("name_lastobsid",["last_obsid_current"],"0",0.0); //These are ILT-EGSE commands, not ruled by the 2TC/sec. //HifiIltEgse_FPU_set_BB_ID(0); //HifiIltEgse_PDU_set_OBS_ID(iround(result[0]{0})); //delay(1); //HifiIltEgse_PDU_set_BB_ID(0); //HifiIltEgse_FPU_set_OBS_ID(iround(result[0]{0})); //delay(1); //SpireIltEgse_QCC_SETBBID(0); //SpireIltEgse_QCC_SETOBSID(iround(result[0]{0})); //delay(1); //HifiIltEgse_GAS_set_OBS_ID(iround(result[0]{0})); //HifiIltEgse_GAS_set_BB_ID(0); //delay(1); } ////////////////////////////////////////////////////////// // Band switch off: this is a switch to band0 //////////////////////////// // LCU switch-off, block block LCU_switch_off_block_fm HIFI 3631 { }{ // //Automatic failure mode clearance. //Should take <0.5s so time included in the switch-off delay Hifi_HIFI_HL_Normal($BBID); // //Start_block(); {double,string}[] result = ConfigurationReader("name_delays",["switch_off_delay"],"0",0.0); int switch_off_delay = iround(result[0]{0}); // //Send command: this is the effective switch-off Hifi_HIFI_Conf_nom_LCU_ch0($BBID); // delay(switch_off_delay); // //Set heater to their stby value: should not depend on band HL_heater_proc_fm("1a","stby"); } //Set LCU5b back to standby status, procedure procedure LCU5b_standby_proc_fm { string band = "5b"; // HIFI band double lo_freq = 1200.0 in [1192.0,1242.0]; //LO frequency }{ error("This module is obsolete: use LCU_standby_proc_fm instead"); } // Procedure to get the general parameters for the telescope command // for all engineering observations {int,int} procedure Eng_pre_timing { }{ // Init length int initlength = duration(HIFIInitObs()); int hklength = duration(HIFISetHK("fast",true)); initlength = initlength + hklength; // Final length int closelength = duration(HIFICloseObs()); closelength = closelength + hklength; // telescope parameters - none needed any more // return everything return {initlength,closelength}; } //Generic procedure for total power //It takes care of the data-rate computation procedure HIFI_Spectr_total_power_proc_fm { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast int integ_time = 4; //TOTAL integration time }{ //Compute data-rate double[] rates = ILT_datarate_proc_fm(band,backend,"tp",integ_time); // set data rates non_ess_hk_data_rate(rates[2] / 1024.0); data_rate(rates[0] / 1024.0); // Hifi_HIFI_Spectr_total_power($BBID); Apply_Total_Power_delay(integ_time,band,backend); // reset data rates non_ess_hk_data_rate(rates[1] / 1024.0); data_rate(0.0); } // Integrate with IF1 off, block // We take 1 spectrum per phase. block Stability_noIF1_fm HIFI 3429 { string band = "1a"; // HIFI band int n = 100; //The number of integrations int integ_time = 4; //Total integration time in sec. to be set at end of test string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code }{ Start_block(); //The system as is should be ready //No use of FPU capabilities. // //Do a long integration: 4 sec is OK //We implement a special spectroscopy configuration with fixed values Total_power_spectro_for_Stability_proc_fm(band,n,integ_time,backend,hrs_mode); } //////////////////////////////////////// // Standing wave analysis, procedure NDW // This is like a radiometry: 4 spectra // noretune version procedure Standing_wave_noretune_fm_COP { string band = "1a"; // HIFI band int integ_time = 4; //Total integration time in sec. string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast double[] lo_freq_input = [500.0,500.15,0.02]; //Start, end and step lo_freq for the LO scan string los_code = "sc" in ["sc","sh","ss"]; //The line-of-sight code: sc (sky-CBB), sh (sky-HBB), ss (sky-sky) }{ // Initial LO tuning at centre frequency of scan // double lo_freq_ref = (lo_freq_input[0] + lo_freq_input[1]) / 2.0; message("LO freq: " + lo_freq_ref); if(los_code == "sh") { Init_MSA_HBB_fm(band,"CLOSE",lo_freq_ref,"ON"); } else { Init_MSA_CBB_fm(band,"CLOSE",lo_freq_ref,"ON"); } LO_tuning_block_fm(band,lo_freq_ref); double lo_freq = lo_freq_input[0]; // //WBS calibration and backend tuning if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band); WBS_tune_stndwave_proc_fm(band); } if(backend == "hrs" || backend == "both") { HRS_tune_block_fm(band); } // //Loop on LO frequencies. It is assumed that the LO is tuned at the middle frequency of the scan // int nbstep = 0; //For freq above 1THz rounding makes miss the last step. double margin = 0.1 / 1.0E9; //0.1Hz while(lo_freq <= lo_freq_input[1] + margin) { //Set synthesizer to new LO freq. LCU_config_nominal_noretune_block_fm(band,lo_freq,lo_freq_ref); // if(los_code == "sc") { //Pair towards sky-CBB Sky_Cold_fm_COP(band,integ_time,hrs_mode,backend); } if(los_code == "sh") { //Pair towards sky-HBB Sky_Hot_fm_COP(band,integ_time,hrs_mode,backend); } if(los_code == "ss") { //Pair towards sky-sky Sky_Sky_fm_COP(band,integ_time,hrs_mode,backend); } //Increase lo_freq lo_freq = lo_freq + lo_freq_input[2]; nbstep = nbstep + 1; //debug_print(lo_freq); } message("Nb of steps: " + nbstep); } ////////////////////////////////////////////////////////////////////////// // Procedure to compute detailed timing of OTF observing mode {int,int,int,int,int,int,int,int} procedure OTFFSwitch_pre_timing { int nlines_tot = 1; // Number of rows in the map int npoints = 10; // Number of data dumps per row string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // chunk size given by the data rates and optimum speed int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 1 in [1,1800]; // Supersamplingfactor int n_switch_off = 3 in [1,3600]; // Number of data dumps for the OFF integration time int n_linesperscan = 1 in [1,32]; // Number of lines between two OFFs int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // First check validity of frequencies CheckLOFrequencies(band,lo_freq + min(freq_throw,0.0),lo_freq + max(freq_throw,0.0)); // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // First perform consistency checks // Check chunk size given by the data rates CheckDataTaking(backendreadoutparms,data_time); CheckFswOutOfBand(band,lo_freq,freq_throw,backendreadoutparms); // Is the map size an integer multiple of the scan size? CheckReasonableLineNumber(nlines_tot,true); if(nlines_tot == 1) { int n_scans = 1; } else { if(nlines_tot % n_linesperscan != 0) { SError("Map size is no integer multiple of the scan size."); } n_scans = nlines_tot / n_linesperscan; } // Compute parameters for the instrument timing int n_pp = 2 * npoints * n_switch_on; // compute load integration time int loadlength = duration(DoubleLoadMeasurement(band,lo_freq,freq_throw,eff_resolution{0},data_time,backendreadoutparms)); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); loadlength = loadlength + readoutdead; // Compute parameters for the pointing command int jitterdead = GetMaxTimeJitter(band,lo_freq); int off_inttime = 2 * data_time_off * n_switch_off; // OFF integration time int off_pointing = off_inttime + jitterdead; // increase by commanding jitter // Duration of initial set up // determine exact duration only in case of full commanding if(docommands) { int initlength = duration(HIFIInitObs()); initlength = initlength + duration(TuneHIFIFsw(band,lo_freq,freq_throw,hrs1,hrs2,wbs1{0},wbs2{0},"normal")); // Add time for HK readout int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); initlength = initlength + hkduration; } else { initlength = GetRoughInitLength(band,lo_freq,true); } initlength = initlength + loadlength; // First estimate of the load interval int scan_time = n_linesperscan * n_pp * data_time + off_pointing; if(scan_time > load_interval) { IError("Scan duration too long for required load period. " + "Reduce the map size or increase the step size."); } int n_loadinterval = imax(load_interval / scan_time,1); n_loadinterval = imin(n_loadinterval,32); // Make sure that load slews occur at the same position in each coverage n_loadinterval = IMultiple(n_loadinterval,n_scans); // dangling time given by readout dead time int dangling = readoutdead; // Return all the times needed in the observing mode modules return {n_pp,n_scans,off_inttime,off_pointing,loadlength,n_loadinterval,initlength,dangling}; } // SCR-1243: 14.4 and 14.42 are prohibited LO - shift it to 14.38 and 14.44 GHz double procedure Check_HRS_prohibited_LO_proc_fm { double flo = 15.0; // Input HRS internal LO freq. in GHz }{ double checked_flo = flo; if(checked_flo == 14400.0) { checked_flo = flo - 20.0; } if(checked_flo == 14420.0) { checked_flo = flo + 20.0; } if(checked_flo >= 17180.0) { IError("Impossible HRS configuration. " + "Reduce the IF frequency of at least one HRS subband."); } if(checked_flo < 13000.0) { IError("Impossible HRS configuration. " + "Increase the IF frequency of at least one HRS subband."); } return checked_flo; } // Automatic magnet tuning, block // Also assumes backends are ready // This mode allows some investigation on the input parameters block Magnet_tuning_expert_block_fm HIFI 3619 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b"]; // HIFI band double lo_freq = 522.0; //LO frequency string backend_code = "HRS" in ["WBS","HRS"]; //The backend to be used for tuning int tune_target_magnet = 40 in [10,85]; //Target WBS illumination percentage during magnet tuning double[] input_params = [1.8,7.0,8.0,20.0,10.0,1.0]; //input parameters for expert mode }{ Start_block(); //Set mixer bias to special bias for tuning {double,string}[] result = ConfigurationReader("name_confilmix",["bias4magn_h","bias4magn_v","norm_bias_h","norm_bias_v"],band,lo_freq); //For bands 1,2 and 5, we must substract 0.09mV to this value double bias4magnh = result[0]{0}; double bias4magnv = result[1]{0}; if(band == "1a" || band == "1b" || band == "2a" || band == "2b" || band == "5a" || band == "5b") { bias4magnh = bias4magnh - 0.09; bias4magnv = bias4magnv - 0.09; } Mixerbias(bias4magnh,bias4magnv); double normal_bias_h = result[2]{0}; double normal_bias_v = result[3]{0}; // //First set magnets to maximum because of hysteresis result = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,lo_freq); double magnetcurrentmax_H = result[0]{0}; double magnetcurrentmax_V = result[1]{0}; Set_Magnet_current_proc_fm(magnetcurrentmax_H,magnetcurrentmax_V); // //For band5, wait another 5 sec here if(band == "5a" || band == "5b") { delay(5); } //Fetch magnet tuning parameters result = ConfigurationReader("name_configmagtune",["nMagnet","stepT","mx_mg_span"],band,lo_freq); // //Tuning strategy: scan nMagnet points over -10% to +10% of nominal value //at the frequency of interest int nMagnet = iround(input_params[4]); double stepT = input_params[5]; double h_mx_mg0 = input_params[1]; double v_mx_mg0 = input_params[2]; double scan_range = input_params[3] / 100.0 * max(h_mx_mg0,v_mx_mg0); double mx_mg_step = -1.0 * scan_range / double(nMagnet); //Starting scan values h_mx_mg0 = h_mx_mg0 - mx_mg_step * double(nMagnet) / 2.0; v_mx_mg0 = v_mx_mg0 - mx_mg_step * double(nMagnet) / 2.0; // //Set magnets to starting value to do backend tuning Set_Magnet_current_proc_fm(h_mx_mg0,v_mx_mg0); // //Tune attenuators of backends before magnet tuning ///The following is not yet done. Still take as input parameter //result = ConfigurationReader("name_configwbs",["tune_target_magnet"],band,lo_freq); //int tune_target_magnet = iround(result[0]{0}); // //Perform tuning: check which backend shall be used int magtune_delay = 0; if(backend_code == "WBS") { Hifi_HIFI_Tune_WBS($BBID,tune_target_magnet); //Get delay result = ConfigurationReader("name_delays",["wbs_tune_delay"],band,0.0); delay(iround(result[0]{0})); // Hifi_HIFI_Tune_mxmgc_useWBS($BBID,stepT,nMagnet,h_mx_mg0,v_mx_mg0,mx_mg_step); //Compute delay magtune_delay = iceil(1.0 + 0.94 + double(nMagnet) * (stepT + 1.05)) + 1; //according to OBS 4.4: extra second added } else { Hifi_HIFI_Tune_HRS($BBID); //Get delay result = ConfigurationReader("name_delays",["hrs_tune_delay"],band,0.0); delay(iround(result[0]{0})); // Hifi_HIFI_Tune_mxmgc_useHRS($BBID,stepT,nMagnet,h_mx_mg0,v_mx_mg0,mx_mg_step); magtune_delay = iceil(1.0 + 0.072 + double(nMagnet) * (stepT + 0.132)) + 1; //according to OBS 4.4: extra second added } // delay(magtune_delay); //debug_print(magtune_delay); //Set mixer bias back to nominal value at frequency of interest Mixerbias(normal_bias_h,normal_bias_v); // } ///////////////////////////////////////////////////////////////// // Procedure to compute total dead times for the mode // {double,double,double} procedure DBS_deadtimes { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // data dump interval int n_chop = 3; // number of chop cycles in one integration int n_load = 0; // number of integrations in one pointing phase -1 double tdead = 10.0; // Dead time from telescope }{ ////////////////////////////////////////////////////////////////////// // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Compute parameters for the instrument timing {double,double} tinst = GetInstDeadSlowChop(data_time,2 * n_chop,"chop",band,lo_freq,backendreadoutparms); // dead time double tdeadint = double(data_time * 2 * n_chop) - tinst{0}; // subtract dead times in switches // keep dead times between A-A and B-B in total dead time tdeadint = tdeadint - double(n_chop) * tinst{1}; // Total dead time per cycle double tdead_tot = tdead + double(2 * (n_load + 1)) * tdeadint; // Integration time double tphaseint = tinst{0} / double(2 * n_chop); return {tdead_tot,tphaseint,tinst{1}}; } // Radiometric noise from a symmetric two-phase observation // This is still to be scaled by a factor 1.0/(B_fluct*T_Allan) double procedure TwoPhaseRadioNoise { double x = 0.1; // value for integration time relative to Allan time }{ double y = AsymmetricRadioNoise(x,x,1.0); return y; } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // CUS scripts for Manual Procedures MOC // // DT - 27-Feb-06 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // The modes //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Write in EEPROM mode HifiManCmd_write_eeprom { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! }{ Mode_status_check_intermediate(); StartMode_block_ops(); mois_comment("EEPROM writing of latest uploaded OBSW"); mois_spacon("This procedure should be executed immediately after any of the OBSM procedures, on the condition that the corresponding uploaded OBSW version needs to be written on the EEPROM. Please check procedure SRON_U/HIFI/PR/2007-007 for background and details applicable to the OBSW version of interest."); Write_EEPROM_block_ops(); StopMode_block_ops(); } //Set LOU to nominal, procedure //Set LOU in nominal mode with no //channel selected procedure Set_LO_Nominal_proc_fm { }{ // //Start_block(); {double,string}[] result = ConfigurationReader("name_delays",["set_to_nominal_delay"],"0",0.0); int set_to_nominal_delay = iround(result[0]{0}); // Hifi_HIFI_HL_Normal($BBID); delay(set_to_nominal_delay); // } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // CUS scripts for LOU and LCU operations. // // DT - 17-Feb-06 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // The modes //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // See fm_testmodes.cus //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // The procedures //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //Block to activate FSW1/FSW2 register block Activate_FSW_register_block_fm HIFI 3955 { string register = "FSW1" in ["FSW1","FSW2"]; //Register to activate: FSW1 or FSW2 }{ if(register == "FSW1") { Hifi_HIFI_HL_set_FSW1($BBID); } else { Hifi_HIFI_HL_set_FSW2($BBID); } } //////////////////////////////////////// // Standing wave analysis, procedure NDW // This is like a radiometry: 4 spectra // retune version procedure Standing_wave_retune_fm { string band = "1a"; // HIFI band int integ_time = 4; //Total integration time in sec. string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast double[] lo_freq_input = [500.0,500.15,0.02]; //Start, end and step lo_freq for the LO scan int nb_retune = 5; //frequency at which we retune }{ // Initial LO tuning at centre frequency of scan (NDW) // Not applicable here double lo_freq_ref = (lo_freq_input[0] + lo_freq_input[1]) / 2.0; //LO_tuning_block_fm(band, lo_freq_ref); double lo_freq = lo_freq_input[0]; // //WBS calibration and backend tuning if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band); WBS_tune_stndwave_proc_fm(band); } if(backend == "hrs" || backend == "both") { HRS_config_block_fm(band,hrs_mode); HRS_tune_block_fm(band); } // //Configure spectrometers integration //Slowchop will be used for all bands - FSW no longer considered for HEBs // int[] res = [0,0]; int total_time = 0; res = Configure_Spectrometer_hc_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); total_time = res[0] * res[1]; // //Loop on LO frequencies. It is assumed that the LO is tuned at the middle frequency of the scan // int retune = 0; while(lo_freq <= lo_freq_input[1]) { // //We will retune at the running frequency every 5 settings (starting with the first) retune = iround((lo_freq - lo_freq_input[0]) / lo_freq_input[2]) % nb_retune; if(retune == 0) { LO_tuning_block_fm(band,lo_freq); } else { //Set synthesizer to new LO freq. LCU_config_nominal_noretune_block_fm(band,lo_freq,lo_freq_ref); // NDW } // //First internal loads Hot_cold(band,hrs_mode,backend,res[0] * res[1],"slowchop",0,0); //Then external loads - this will drop if not ILT-context //Hot_cold_external(band,res[0]*res[1],backend); //Increase lo_freq lo_freq = lo_freq + lo_freq_input[2]; } } // Vector scan calibration for a given LO band // Ues domains of frequencies to be scanned for each LO sub-band procedure Vecscan_calibration_proc_fm_TV { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band }{ // LCU_switchon_proc_fm(band); //Wait an extra delay of 1 min for short term stabilization delay(60); // //Get the list of frequencies to be used for the scan string tab = "config_vecscan_TV.config"; double bandnb = GetBandCode(band); double lofreqlow = dlookup(tab,"" + iceil(bandnb),"lofreqlow"); double lofreqhigh = dlookup(tab,"" + iceil(bandnb),"lofreqhigh"); double lofreqstep = dlookup(tab,"" + iceil(bandnb),"lofreqstep"); // double current_LO = lofreqlow; bool endreached = false; //Loop on key frequencies per LO band while(current_LO <= lofreqhigh && endreached == false) { //Configure FPU at that frequency Init_MSA_fm(band,"CLOSE",current_LO,"ON"); // //Perform vector scan within BLUE limits at that frequency Vector_scan_BLUE_LIMIT_block_fm(band,current_LO); //LCU_CLEAR_ERROR_block_fm(); // //Check last LO freq done if(current_LO == lofreqhigh && endreached == false) { endreached = true; } //Increase LO freq: truncate if step too high current_LO = current_LO + lofreqstep; if(current_LO > lofreqhigh && endreached == false) { current_LO = lofreqhigh; } } // } // Initialisation of FPU, block with both MSA in use // It is for warm context, except FIF1 which is cold context block Init_MSA_fm_warm_FIF1cold HIFI 3219 { string band = "1a"; // HIFI band string chop_loop = "CLOSE"; double lo_freq = 522.0; //LO frequency }{ Start_block(); //Get parameters {double,string}[] result_d = ConfigurationReaderWarm("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,lo_freq); int band_nb = iround(result_d[0]{0}); double diplex_H = 0.0; double diplex_V = 0.0; int diplex_h_ctrl_mode = 0; int diplex_v_ctrl_mode = 0; // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // //Get FIF1-H for cold context result_d = ConfigurationReader("name_confilfpu",["fif1v_h","fif1c_h"],band,lo_freq); volt_H_FIF_1 = result_d[0]{0}; curr_H_FIF_1 = result_d[1]{0}; // // result_d = ConfigurationReaderWarm("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,lo_freq); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // //Get FIF1-V for cold context result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v"],band,lo_freq); volt_V_FIF_1 = result_d[0]{0}; curr_V_FIF_1 = result_d[1]{0}; // // string chop_sine_s = "ON"; // string chop_loop = "CLOSE" ; result_d = ConfigurationReaderWarm("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,lo_freq); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // double calibcurrent = result_d[7]{0}; // //Get biases result_d = ConfigurationReaderWarm("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); double bias_H = result_d[0]{0}; double bias_V = result_d[1]{0}; //For bands 6 and 7, first set to 4mV if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { result_d = ConfigurationReaderWarm("name_confilfpu",["bias_max_h","bias_max_v"],band,lo_freq); bias_H = result_d[0]{0}; bias_V = result_d[1]{0}; } // //Get magnets: not applicable to bands 6 and 7 double magnetcurrent_H = 0.0; double magnetcurrent_V = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReaderWarm("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,lo_freq); magnetcurrent_H = result_d[0]{0}; magnetcurrent_V = result_d[1]{0}; } //Diplexer is interpolated from a table for Bands 3, 4, 6L and 6H if(band_nb <= 2 || band_nb == 5) { diplex_H = 0.0; //For bands 1, 2 and 5 diplex_V = 0.0; diplex_h_ctrl_mode = 0; diplex_v_ctrl_mode = 0; } else { //Get diplexer currents result_d = ConfigurationReaderWarm("name_confilfpu",["diplex_h_ctrl_mode","diplex_v_ctrl_mode"],band,lo_freq); diplex_h_ctrl_mode = iround(result_d[0]{0}); diplex_v_ctrl_mode = iround(result_d[1]{0}); double[] result_dip = Get_Diplexer_setting(band,lo_freq); diplex_H = result_dip[0]; diplex_V = result_dip[1]; } // // result_d = ConfigurationReader("name_chopper",["chop_startup_warm"],band,0.0); double chopper = result_d[0]{0}; //For this configuration we won't convert prime chopper voltage into redundant voltage //Just checking we are in range. //chopper = Check_Chopper_Prime_Redundant(chopper); chopper = Check_Chopper_Range(chopper); // //Switch on upconverter, assuming chopper and mixers are also ON Hifi_HIFI_Configure_FCU_Power($BBID,"ON","ON","ON","ON","ON"); // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result_d = ConfigurationReaderWarm("name_delays",["config_fpu_delay"],band,lo_freq); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // //In case of band 6 or 7, bias have been set to 4mV. Now set to nominal if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { {double,string}[] result = ConfigurationReaderWarm("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); Mixerbias(result[0]{0},result[1]{0}); } // //Magnet are so far at maximum value. Now set to nominal if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReaderWarm("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); Hifi_HIFI_CH1_MX_MG_C($BBID,result_d[0]{0}); Hifi_HIFI_CV1_MX_MG_C($BBID,result_d[1]{0}); delay(1); } // Hifi_HIFI_non_periodic_hk_FCU(); } // Recalculate and verify LCU memory checksum block LcuChecksumRecalc_ops HIFI 7904 { string section = "P" in ["P","R"]; }{ int expected_sum = ilookup("LcuChecksumTable.config",section,"normal"); // initial install of default safe table - simulate transition to normal Hifi_HIFI_LCU_Single($BBID,"HL_DEF_SAFE"); delay(1); //Stop LCU HK collection - see SPR-1679 //Get applicable HK rate mois_comment("Stop LCU HK collection"); {double,string}[] result_d = ConfigurationReader("name_delays",["hk_rate"],"0",0.0); string hk_rate = result_d[0]{1}; Hifi_HIFI_Housekeeping_on(hk_rate,"ON","OFF","ON","ON","ON","ON"); delay(1); // mois_spacon("In the following TC, the third parameter (HP233197) should be treated as FP."); Hifi_HIFI_check_LCU_memory($BBID,3000,expected_sum); //add 2sec to the initial 4sec - SPR-1744 delay(6); //Restore HK mois_comment("Resume LCU HK collection"); Hifi_HIFI_Housekeeping_on(hk_rate,"ON","ON","ON","ON","ON","ON"); delay(1); // mois_tmcheck("Check with HIFI representative that parameter HM245194 has taken the expected checksum value. Also HM247194 should be set to OK"); mois_comment("If the above is not true, the upload has failed and the HIFI ICU needs to be reset. For this, please use the corresponding OBCP."); } //HIFI-COP-2.3-Param-Scan: 1 per pair of scanned parameters obs HifiEng_Parameter_Scan_COP_fine { int index = 1 in [1,7]; // Test case index as of config_paramscan_COP.config int m1_index = 1 in [1,4]; //Index of M1 value - only applicable is phase = 1. Index 1 is least negative int m2_index = 1 in [1,4]; //Index of M2 value - only applicable is phase = 1. Index 1 is least negative int duration_vecscan = 80; //Duration of vector scan phase in sec. int duration_hrsfast = 600; //Duration of HRS fast stability phase in sec. }{ //Read corresponding band string tab = "config_paramscan_COP.config"; string band = slookup(tab,"" + index,"band"); //General parameters in use int integ_time = 4; //Integration time PER PHASE for the slowchop measurement string[] hrs_mode = ["wb1","wb1"]; //For bands 6 and 7, use wb8 if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { hrs_mode = ["wb8","wb8"]; } // // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Parameter_Scan_COP_fine_proc_ops(index,integ_time,hrs_mode,m1_index,m2_index,duration_vecscan,duration_hrsfast)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Parameter_Scan_COP_fine_proc_ops(index,integ_time,hrs_mode,m1_index,m2_index,duration_vecscan,duration_hrsfast); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } // Total noise from an OTF line for the special case of a // multiple scan of the same line // Normalized to mapping without overhead // double procedure OtfRepeatedNoise { double num_scans = 2.0; // number of scans of the same line double n = 10.0; // number of points in one scan double[] parameters = [0.02,0.4,0.05,0.667,2.5]; // Parameters: integration time, delay, slew from OFF relative to Allan time, ratio of t_off time to sqrt(n)*t_on, drift exponent }{ // Assign parameters double x = parameters[0]; double d = parameters[1]; double doff = parameters[2]; double qval = parameters[3]; double alpha = parameters[4]; // Make corrections for different calibration double qcorr = qval * sqrt(num_scans); {double,double} noisevalues = OtfNoiseValues(num_scans * n,[x,d,doff,qcorr,alpha]); // The radiometric noise here is only accurate for nscans=1,2. // For other lengths we make a small error. double yn = noisevalues{0}; yn = yn / num_scans; // The drift noise might also be reduced somewhat due to adding up // different scans. The effect is basically unknown and ignored here. double yd = noisevalues{1}; double y = yn + yd; return y; } //HIFI LO tuning only for M1/M2 investigation in 3b, block //Target current is read from look-up table block LCU_config_w_M1M2M3_block_fm HIFI 3923 { string band = "3b" in ["3b","3b"]; // HIFI band double lo_freq = 930.0; //LO frequency double m1 = 10.0; //M1 multiplier voltage double m2 = -8.0; //M2 multiplier voltage double m3 = 1.5; //M3 multiplier voltage }{ //Clear potential failure mode Set_LO_Nominal_proc_fm(); // //Start_block(); {double,string}[] result = ConfigurationReader("name_confpolar4lotune",[band],band,lo_freq); string mixer_polarization = result[0]{1}; // //Get target mixer current result = ConfigurationReader("name_confilmix",["target_mx_c_h","target_mx_c_v"],band,lo_freq); double target_current = result[0]{0}; if(mixer_polarization == "V") { target_current = result[1]{0}; } if(mixer_polarization == "B") { target_current = 0.5 * (result[1]{0} + result[0]{0}); } // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; name_configlcutune = "name_configlcutune_b"; } // result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = m1; //result[1]{0}; double m2_v = m2; //result[2]{0}; double m3_v = m3; //result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // result = ConfigurationReader(name_configlotune,["step_drain2_v","nsteps","step_time"],band,lo_freq); double step_drain2_v = result[0]{0}; int nsteps = iround(result[1]{0}); double step_time = result[2]{0}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // //Adjust scan cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); double drain2_safe = cresult[0]; // double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); // double drain2_v_start = drain2_bluemax; // result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); // if(band == "3b") { Hifi_HIFI_Conf_nom_LCU_ch3b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,macro_checksum); //Send command: specific to M3 in 3b delay(config_lo_delay); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } // } //////////////////////////////////// // Load chop observing mode // // The implementation now assumes that the corresponding Herschel // pseudo-pointing mode will be available // {int,double,double,double,double,double} obs HifiPointProcLoadChop { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source double raoff = 0.0; // RA coordinate of the OFF position double decoff = 0.0; // DEC coordinate of the OFF position bool refSelected = true; // Dummy parameter required by HSPOT string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rates int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 2 in [1,900]; // number of half load-sky-sky-load cycles on ON int n_switch_off = 2 in [1,900]; // number of half load-sky-sky-load cycles on OFF int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF calibration cycles int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Single Point - Load Chop Ref",{data_time,data_time_off,0,n_switch_on,n_switch_off,0,0,0,n_cycles,load_interval}); // position switch // Call first part of the timing computer {int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int} pre_timing_ps = LoadChop_pre_timing(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,n_switch_on,n_switch_off,n_cycles,load_interval,docommands); // Prepare telescope command {double,double} onPosition = {ra,dec}; {double,double} refPosition = {raoff,decoff}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,int,int,int,int,int,int} tpar_ps = PositionSwitch_telescope(naifid,onPosition,refPosition,band,lo_freq,pre_timing_ps,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = nodding_pointing(false,tpar_ps{0},tpar_ps{1},tpar_ps{2},tpar_ps{3},tpar_ps{4},tpar_ps{5},tpar_ps{6},tpar_ps{7},tpar_ps{8},tpar_ps{9},tpar_ps{10},tpar_ps{11},tpar_ps{12},tpar_ps{13},tpar_ps{14},tpar_ps{15},tpar_ps{16},tpar_ps{17},tpar_ps{18},true); // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int},int,bool,double,double} post_timing_ps = DoubleChop_post_timing(pre_timing_ps,telescopetimes,n_cycles); // Now the actual observation starts // Prepare telescope command tpar_ps = PositionSwitch_telescope(naifid,onPosition,refPosition,band,lo_freq,post_timing_ps{1},n_cycles); // Call telescope command telescopetimes = nodding_pointing(true,tpar_ps{0},tpar_ps{1},tpar_ps{2},tpar_ps{3},tpar_ps{4},tpar_ps{5},tpar_ps{6},tpar_ps{7},tpar_ps{8},tpar_ps{9},tpar_ps{10},tpar_ps{11},tpar_ps{12},tpar_ps{13},tpar_ps{14},tpar_ps{15},tpar_ps{16},tpar_ps{17},tpar_ps{18},true); // Consistency check int totaltime = post_timing_ps{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following ////////////////////////////////////////////////////////////////////// int on_inttime = post_timing_ps{1}{0}; int off_inttime = post_timing_ps{1}{1}; int on_pointing = post_timing_ps{1}{2}; int off_pointing = post_timing_ps{1}{3}; int loadlength = post_timing_ps{1}{4}; int n_loadinterval = post_timing_ps{1}{7}; int n_per_on = post_timing_ps{1}{8}; int n_per_off = post_timing_ps{1}{9}; int n_load_on = post_timing_ps{1}{10}; int n_load_off = post_timing_ps{1}{11}; bool end_load_on = post_timing_ps{1}{12}; bool end_load_off = post_timing_ps{1}{13}; int initshiftlength = post_timing_ps{2}; bool final_load = post_timing_ps{3}; double tscan = post_timing_ps{4}; double tdead = post_timing_ps{5}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands ////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { LoadChop_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,n_per_on,n_per_off,n_loadinterval,n_load_on,n_load_off,end_load_on,end_load_off,final_load,startobs,telescopetimes,loadlength,initshiftlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double,double,double} tact = DoubleChop_deadtimes("lchop",band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,n_per_on,n_per_off,n_load_on,n_load_off,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = LoadChop_noisecomputer(band,lo_freq,effResolution,oneGHzReference,on_inttime,off_inttime,n_cycles,tscan,tact); // Evaluate performance DoubleChop_performance(band,lo_freq,effResolution,noisevalues,timeTaken,n_cycles,n_per_on * (n_load_on + 1),n_per_off * (n_load_off + 1),false,tscan,on_pointing,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // Tune for frequency switch procedure TuneHIFIFsw { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double freq_throw = -40.0; // throw of frequency switch in MHz {bool,int,double[],bool[]} hrs1parms = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets,subbands used} {bool,int,double[],bool[]} hrs2parms = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets,subbands used} bool wbs1parms = true; // WBS1 parameter =used bool wbs2parms = true; // WBS2 parameter =used string level = "normal"; // Name of target level }{ // Check for allowed configuration double maxstep = GetMaxFreqThrow(band,lo_freq); if(abs(freq_throw) > maxstep) { int show_lo = ifloor(lo_freq / 1000.0); IError("Frequency throw too large. Maximum throw allowed at " + show_lo + "GHz: " + maxstep + "MHz."); } // Switch to high HK rate HIFISetHK("fast",true); ConfigureFPU(band,lo_freq + freq_throw / 2.0,true); ConfigureBackend(band,lo_freq + freq_throw / 2.0,hrs1parms,hrs2parms); HIFITuneFsw(band,lo_freq,lo_freq + freq_throw,hrs1parms{0},hrs2parms{0},wbs1parms,wbs2parms,level); // Switch to standard HK rate HIFISetHK("normal",true); } //Stopmode procedure StopMode { }{ {double,string}[] result = ConfigurationReader("name_lastobsid",["last_obsid_current"],"0",0.0); //These are ILT-EGSE commands, not ruled by the 2TC/sec. //HifiIltEgse_FPU_set_BB_ID(0); //HifiIltEgse_FPU_set_OBS_ID(iround(result[0]{0})); //delay(1); //SpireIltEgse_QCC_SETBBID(0); //SpireIltEgse_QCC_SETOBSID(iround(result[0]{0})); //delay(1); //HifiIltEgse_PDU_set_BB_ID(0); //HifiIltEgse_PDU_set_OBS_ID(iround(result[0]{0})); //delay(1); Hifi_HIFI_Set_OBS_ID(0,iround(result[0]{0})); delay(1); } /////////////////////////////////////////////////////////////////// // Procedure to compute detailed post timing for the version of the // load chop mode without baseline measurement // {int,{int,int,int,int,int,int,bool,int,int},double,double} procedure SingleChopNoRef_post_timing { {int,int,int,int,int,int,bool,int,int} pre_timing = {16,16,21,1800,2,0,false,50,0}; // pre_timing parameter list int[] telescopetimes = [300,180,0]; }{ // Get all values from the pre_timing section int on_inttime = pre_timing{0}; int on_pointing = pre_timing{1}; int loadlength = pre_timing{2}; int load_spacing = pre_timing{3}; int n_per_on = pre_timing{4}; int n_load_on = pre_timing{5}; bool end_load_on = pre_timing{6}; int initlength = pre_timing{7}; int dangling = pre_timing{8}; // Get all values from the telescope section int tend = telescopetimes[2]; // Final deceleration time // No further computations needed int looplength = on_pointing; double tscan = double(on_inttime) / double(n_per_on * (n_load_on + 1)); // No telescope dead time in fine pointing double tdead = 0.0; // dangling load time if(end_load_on) { dangling = loadlength; } int closelength = duration(HIFICloseObs()); dangling = imax(dangling + closelength - tend,0); // Compute total duration // The initial time is no longer contained in the total time // int totaltime=imax(initlength,telinit); int totaltime = looplength + dangling + tend; // show gyro-propagation messages // no gyro-propagation for fine_pointing GCPMessages(0,on_pointing,tend); // Return all the times needed in the telescope and instrument modules return {totaltime,{on_inttime,on_pointing,loadlength,load_spacing,n_per_on,n_load_on,end_load_on,initlength,dangling},tscan,tdead}; } // Set magnet currents for both polarizations, block block Set_Magnet_current_block_fm HIFI 3644 { double mag_curr_h = 1.0; //Magnet current H polarization double mag_curr_v = 1.0; //Magnet current V polarization }{ //Start_block(); Hifi_HIFI_CH1_MX_MG_C($BBID,mag_curr_h); Hifi_HIFI_CV1_MX_MG_C($BBID,mag_curr_v); delay(1); } //HIFI-COP-7.2-FT: Regular FT during PV and routine for health monitoring procedure HealthMon_FT_COP_proc_ops { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ //Chopper health check: needs to start in open loop Chopper_FT1_COP_proc_ops(prime_or_redundant); Chopper_FT2_COP_proc_ops(prime_or_redundant); Chopper_FT3_COP_proc_ops(prime_or_redundant); //At that stage the loop is closed again // WBS_FT_COP_proc_ops(prime_or_redundant); HRS_FT_COP_proc_ops(prime_or_redundant); // string[] band = ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // //Reduced version of FP and LO FT: only IVC for(int i = 0 .. 13) { if(i % 2 == 0) { double[] cresult_d = CalibrationReader("name_keyfreq",["keyfreq"],band[i],0.0); FPU_FT_IVC_COP_proc_ops(band[i],prime_or_redundant); } LO_FT_IVC_COP_proc_ops(band[i],prime_or_redundant); } //Chopper response time Chopper_Response_time_COP_proc_ops(prime_or_redundant); //Diplexer response time string[] band_dip = ["3a","4a","6a","7a"]; for(int j = 0 .. 3) { Diplexer_Response_time_COP_proc_ops(band_dip[j],"H"); Diplexer_Response_time_COP_proc_ops(band_dip[j],"V"); } // } //HIFI-COP-2.3-Param-Scan: fine range procedure Parameter_Scan_COP_fine_proc_ops { int index = 1 in [1,7]; // Test case index as of config_paramscan_COP.config int integ_time = 4; //Integration time PER PHASE for the Tsys slowchop measurement string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int m1_index = 1 in [1,4]; //Index of M1 value - only applicable is phase = 1. Index 1 is least negative int m2_index = 1 in [1,4]; //Index of M2 value - only applicable is phase = 1. Index 1 is least negative int duration_vecscan = 80; //Duration of vector scan phase in sec. int duration_hrsfast = 600; //Duration of HRS fast stability phase in sec. }{ // //Read all band+param to perform string tab = "config_paramscan_COP.config"; int total = table_size(tab); double lo_freq = dlookup(tab,"" + index,"lofreq"); string band = slookup(tab,"" + index,"band"); double m1_min = dlookup(tab,"" + index,"m1_1"); double m1_max = dlookup(tab,"" + index,"m1_2"); double m1_step = dlookup(tab,"" + index,"m1_step"); double m2_min = dlookup(tab,"" + index,"m2_1"); double m2_max = dlookup(tab,"" + index,"m2_2"); double m2_step = dlookup(tab,"" + index,"m2_step"); double m1 = m1_max - double(m1_index - 1) * m1_step; double m2 = m2_max - double(m2_index - 1) * m2_step; //General parameters for spectroscopy string backend = "both"; string chopmode = "slowchop"; double sampling_rate = 3.0; //Sampling rate: 2 (2 HRS-H + 2 HRS-V), 4 (HRS-H + HRS-V, 2 HRS-H or 2 HRS-V) or 8 (1 HRS-H or 1 HRS-V) Hz double hrs_h_1 = 7.4; //Position in IF of HRS-H sub-band 1 double hrs_h_2 = 7.4; //Position in IF of HRS-H sub-band 2 double hrs_v_1 = 7.4; //Position in IF of HRS-V sub-band 1 double hrs_v_2 = 7.4; //Position in IF of HRS-V sub-band 2 double[] hrs_subband = [hrs_h_1,hrs_h_2,hrs_v_1,hrs_v_2]; string hrs_polarization = "B"; //HRS polarization: selection works only for 4 and 8 Hz //FPU configuration Init_MSA_HBB_fm(band,"CLOSE",lo_freq,"ON"); message(band + ", " + lo_freq + ", " + m1 + ", " + m2); //Vector scan phase: do LO tuning during the indicated duration int start = time(); int remaining_time = duration_vecscan - (time() - start); while(remaining_time > 0) { LO_tuning_w_M1M2_block_fm(band,lo_freq,m1,m2); remaining_time = duration_vecscan - (time() - start); } //Phase 1 measurement: M1 and M2 pair // //Tsys and HRS-fast measurement if(duration_hrsfast != 0) { start = time(); WBS_calib_fm(band); WBS_tune_proc_fm(band); HRS_config_block_fm(band,["wb1","wb1"]); HRS_tune_block_fm(band); //Configure spectroscopy for slowchop hotcold int[] res = Configure_Spectrometer_hc_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); int total_time = res[0] * res[1]; Hot_cold(band,hrs_mode,backend,total_time,chopmode,0,0); // //HRS fast stability measurment int n = (duration_hrsfast - (time() - start) - 14) * 3; Stability_fast_proc_fm(band,n,hrs_subband,sampling_rate,hrs_polarization); // } } //////////////////////////////////// //Special blocks taken from MOC_CUS //////////////////////////////////// //Chopper rotation block. It takes into account //overshoot risk and performs the rotation in //2 steps if the targetted positions are either of the end stops block Chopper_Rotation_block_fm_COP HIFI 3746 { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string chop_current_position = "chop_hot_ang"; //Current chopper position string chop_target_position = "chop_cold_ang"; //Targetted chopper position string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ //Start_block(); //Retrieve angles of corresponding positions {double,string}[] result_d = ConfigurationReader("name_chopper",[chop_current_position,chop_target_position,"chop_endstopright_ang","chop_endstopleft_ang","overshoot"],band,0.0); double chop_current_angle = result_d[0]{0}; double chop_target_angle = result_d[1]{0}; double chop_endstopright_angle = result_d[2]{0}; double chop_endstopleft_angle = result_d[3]{0}; double overshoot = result_d[4]{0}; string chop_target_name = result_d[1]{1}; string chop_current_name = result_d[0]{1}; int step = 1; // //Check whether the rotation may reach either of the end stops, i.e. //go beyond either the HBB or M3_left ///// We suppose here overshoot to be 0, so the 2 steps only occur when targetting ///// the end stops strictly. overshoot = 0.0; double total_angle = abs(chop_target_angle - chop_current_angle) * (1.0 + overshoot); // //The endstop that one may hit depends on the rotating direction //Case were endstop is the left one double angle_to_endstop = abs(chop_endstopleft_angle - chop_current_angle); if(chop_target_angle > chop_current_angle) { //then end stop is the right one angle_to_endstop = abs(chop_endstopright_angle - chop_current_angle); } //debug_print(total_angle); //debug_print(angle_to_endstop); if(total_angle >= angle_to_endstop) { message("Chopper expected to hit the endstop. Rotation done in two steps"); step = 2; } //If we have two steps necessary, the middle position between current and //targetted position is used. result_d = ConfigurationReader("name_confilfpu",[chop_target_name,chop_current_name],band,0.0); double chop = result_d[0]{0}; double chop_intermediate = (result_d[0]{0} + result_d[1]{0}) / 2.0; // chop = Check_Chopper_Prime_Redundant_COP(chop,prime_or_redundant); if(step == 1) { if(prime_or_redundant == "Prime") { Hifi_HIFI_P_Chopper_Rot($BBID,chop); } else { Hifi_HIFI_R_Chopper_Rot($BBID,chop); } Hifi_HIFI_non_periodic_hk_FCU(); //To get sent voltage delay(1); } if(step == 2) { chop_intermediate = Check_Chopper_Prime_Redundant_COP(chop_intermediate,prime_or_redundant); if(prime_or_redundant == "Prime") { Hifi_HIFI_P_Chopper_Rot($BBID,chop_intermediate); } else { Hifi_HIFI_R_Chopper_Rot($BBID,chop_intermediate); } Hifi_HIFI_non_periodic_hk_FCU(); //To get sent voltage delay(1); if(prime_or_redundant == "Prime") { Hifi_HIFI_P_Chopper_Rot($BBID,chop); } else { Hifi_HIFI_R_Chopper_Rot($BBID,chop); } Hifi_HIFI_non_periodic_hk_FCU(); //To get sent voltage delay(1); } } {string,double,double}[] procedure HifiPointModePositionSwitchSequencerInit { string modeName = "pos"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,5]; // data dump interval limited by the data rates int n_int_on = 3 in [2,1800]; // number of data dumps for integration per phase int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF cycles int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode // limit on data rate {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // limits from noise section // Get the drift parameters to compute the drift noise // System Allan variance double[] allanparms = InterpolateSpecAllan(band,lo_freq,oneGHzReference); // rescale to frequency resolution double alpha = allanparms[1]; double binningexp = 1.0 / allanparms[2]; double allan_time_lores = allanparms[0] * pow(1.0 / effResolution{1},binningexp); // Compute derived quantities int int_time_guess = imax(iceil(0.3 * allan_time_lores),datalimit); int data_time_guess = imin(5,int_time_guess); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } int n_int_on_guess = imax(int_time_guess / data_time_guess,2); int n_int_on_range = 2 - n_int_on_guess; if(n_int_on_range == 0) { n_int_on_range = 1; } // Add pointing requirements condition: >=10s {int,int} new_data_time = MatchMinPointing(data_time_guess,data_time_range,n_int_on_guess); data_time_guess = new_data_time{0}; data_time_range = new_data_time{1}; // Contruct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"n_int_on",double(n_int_on_guess),double(n_int_on_range)}]; return retvalues; } // Stability test, procedure, double-beam-switch chop // Differential stability between M3left and M3right. procedure Proc_stability_dbs { string band = "1a"; // HIFI band int n = 100; //Number of load pairs to be measured string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int integ_time = 4; //Total (co-added) integration time of a phase in sec. string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string shutter = "open" in ["open","closed"]; // Shutter position during measurement string chopmode = "slowchop" in ["slowchop","fastchop"]; //Whether to use slowchop or fastchop double chop_phase = 1.0 in [0.2,2.0]; // Chop phase length }{ // Chopper_Rotation_block_fm(band,"chop_M3_ang","chop_hot_ang"); //Look at HBB for att. tuning //Shutter_rotate_proc_fm(shutter); // //WBS calibration if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band); WBS_tune_proc_fm(band); } if(backend == "hrs" || backend == "both" || backend == "hrsFast") { //Configure and tune backends HRS_config_block_fm(band,hrs_mode); HRS_tune_block_fm(band); } // //Configure spectrometers integration after tuning: done later //Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); // Stability_dbs_fm(band,n,integ_time,hrs_mode,backend,chopmode,chop_phase); //Configure spectrometers integration back to default in tp mode Configure_Spectrometer_proc_fm(band,4,hrs_mode,backend); //2 sec. integration } // Initialisation of FPU, block with both MSA in use // Looks at the hot load ! // It is for cold context ! block Init_MSA_CBB_fm HIFI 3998 { string band = "1a"; // HIFI band string chop_loop = "CLOSE"; double lo_freq = 522.0; //LO frequency string hbb_heater = "ON" in ["ON","OFF"]; //hot source on/off }{ Start_block(); //Get parameters {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,lo_freq); int band_nb = iround(result_d[0]{0}); double diplex_H = 0.0; double diplex_V = 0.0; int diplex_h_ctrl_mode = 0; int diplex_v_ctrl_mode = 0; // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,lo_freq); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // string chop_sine_s = "ON"; // string chop_loop = "CLOSE" ; result_d = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,lo_freq); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // double calibcurrent = result_d[7]{0}; if(hbb_heater == "ON") { result_d = ConfigurationReader("name_confilfpu",["calibrator_current_on"],band,lo_freq); calibcurrent = result_d[0]{0}; } // //Get biases result_d = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); double bias_H = result_d[0]{0}; double bias_V = result_d[1]{0}; //For bands 6 and 7, first set to 4mV if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { result_d = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,lo_freq); bias_H = result_d[0]{0}; bias_V = result_d[1]{0}; } // //Get magnets: not applicable to bands 6 and 7 double magnetcurrent_H = 0.0; double magnetcurrent_V = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,lo_freq); magnetcurrent_H = result_d[0]{0}; magnetcurrent_V = result_d[1]{0}; } //Diplexer is interpolated from a table for Bands 3, 4, 6L and 6H if(band_nb <= 2 || band_nb == 5) { diplex_H = 0.0; //For bands 1, 2 and 5 diplex_V = 0.0; diplex_h_ctrl_mode = 0; diplex_v_ctrl_mode = 0; } else { //Get diplexer currents result_d = ConfigurationReader("name_confilfpu",["diplex_h_ctrl_mode","diplex_v_ctrl_mode"],band,lo_freq); diplex_h_ctrl_mode = iround(result_d[0]{0}); diplex_v_ctrl_mode = iround(result_d[1]{0}); double[] result_dip = Get_Diplexer_setting(band,lo_freq); diplex_H = result_dip[0]; diplex_V = result_dip[1]; } // result_d = ConfigurationReader("name_confilfpu",["chop_cold"],band,0.0); //result_d = ConfigurationReader("name_chopper",["chop_startup_cold"], // band,0.0); if(chop_loop == "OPEN") { result_d = ConfigurationReader("name_chopper",["chop_startup_warm"],band,0.0); } double chopper = result_d[0]{0}; //For this configuration we won't convert prime chopper voltage into redundant voltage //Just checking we are in range. //chopper = Check_Chopper_Prime_Redundant(chopper); chopper = Check_Chopper_Range(chopper); // //Switch on upconverter, assuming chopper and mixers are also ON Hifi_HIFI_Configure_FCU_Power($BBID,"ON","ON","ON","ON","ON"); // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result_d = ConfigurationReader("name_delays",["config_fpu_delay"],band,lo_freq); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // //In case of band 6 or 7, bias have been set to 4mV. Now set to nominal if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { {double,string}[] result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); Mixerbias(result[0]{0},result[1]{0}); } // //Magnet are so far at maximum value. Now set to nominal if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); Hifi_HIFI_CH1_MX_MG_C($BBID,result_d[0]{0}); Hifi_HIFI_CV1_MX_MG_C($BBID,result_d[1]{0}); delay(1); } // //Hifi_HIFI_non_periodic_hk_FCU (); } // Automatic magnet tuning, block // Also assumes backends are ready // This is to be used in cold context block Magnet_tuning_block_aot HIFI 6609 { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b"]; // HIFI band double lo_freq = 978.2; //LO frequency string backend_code = "HRS" in ["WBS","HRS"]; //The backend to be used for tuning }{ //Set mixer bias to special bias for tuning {double,string}[] result = ConfigurationReader("name_confilmix",["bias4magn_h","bias4magn_v","norm_bias_h","norm_bias_v"],band,lo_freq); //For bands 1,2 and 5, we must substract 0.09mV to this value double bias4magnh = result[0]{0}; double bias4magnv = result[1]{0}; if(band == "1a" || band == "1b" || band == "2a" || band == "2b" || band == "5a" || band == "5b") { bias4magnh = bias4magnh - 0.09; bias4magnv = bias4magnv - 0.09; } Mixerbias(bias4magnh,bias4magnv); double normal_bias_h = result[2]{0}; double normal_bias_v = result[3]{0}; // //First set magnets to maximum because of hysteresis result = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,lo_freq); double magnetcurrentmax_H = result[0]{0}; double magnetcurrentmax_V = result[1]{0}; Set_Magnet_current_proc_fm(magnetcurrentmax_H,magnetcurrentmax_V); //For band5, wait another 5 sec here if(band == "5a" || band == "5b") { delay(5); } // //Fetch magnet tuning parameters //Middle of the scan result = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); double h_mx_mg0 = result[0]{0}; double v_mx_mg0 = result[1]{0}; // result = ConfigurationReader("name_configmagtune",["nMagnet","stepT","mx_mg_span"],band,lo_freq); // //Tuning strategy: scan nMagnet points over -span/2 to +span/2% of nominal value //at the frequency of interest int nMagnet = iround(result[0]{0}); double stepT = result[1]{0}; double mx_mg_span = result[2]{0}; double scan_range = mx_mg_span * max(h_mx_mg0,v_mx_mg0) / 100.0; double mx_mg_step = -1.0 * scan_range / double(nMagnet); //Starting scan values h_mx_mg0 = h_mx_mg0 - mx_mg_step * double(nMagnet) / 2.0; v_mx_mg0 = v_mx_mg0 - mx_mg_step * double(nMagnet) / 2.0; // //Set magnets to starting value to do backend tuning Set_Magnet_current_proc_fm(h_mx_mg0,v_mx_mg0); // //Tune attenuators of backends before magnet tuning int magtune_delay = 0; //Perform tuning: check which backend shall be used if(backend_code == "WBS") { // Get target result = ConfigurationReader("name_configwbs",["tune_target_magnet"],band,lo_freq); int tune_target_magnet = iround(result[0]{0}); Tune_WBS_aot(band,tune_target_magnet); // Hifi_HIFI_Tune_mxmgc_useWBS($BBID,stepT,nMagnet,h_mx_mg0,v_mx_mg0,mx_mg_step); //Compute delay magtune_delay = iceil(1.0 + 0.94 + double(nMagnet) * (stepT + 1.05)); //according to OBS 4.4 } else { Tune_HRS_aot(band); // Hifi_HIFI_Tune_mxmgc_useHRS($BBID,stepT,nMagnet,h_mx_mg0,v_mx_mg0,mx_mg_step); magtune_delay = iceil(1.0 + 0.072 + double(nMagnet) * (stepT + 0.132)); //according to OBS 4.4 } // delay(magtune_delay); //debug_print(magtune_delay); //Set mixer bias back to nominal value at frequency of interest Mixerbias(normal_bias_h,normal_bias_v); // } //HIFI-COP-3-Stab-1 procedure Stab_COP_proc_ops { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string stab = "sys" in ["sys","lsw","int","dbs","fsw","stab"]; //category of stability measurement int freq_index = 1; //Frequency index to be applied int throw_index = 1; //FSW throw index to be applied string[] hrs_mode = ["wb1","wb1"]; int integ_time = 4; double chop_phase = 1.0; string shutter = "open"; }{ //Variable declaration string chopmode = "slowchop"; double band_nb = GetBandCode(band); int n = 900; string backend = "both"; // //Get the list of frequencies to be used for the scan string tab = "config_stabfreq_" + band + ".config"; int total = table_size(tab); double stabfreq = 0.0; int time_systab = 0; int time_stabil = 20; if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { time_stabil = 45; } // if(stab == "stab") { // stabfreq = dlookup(tab,"1","freq_sys"); Init_MSA_HBB_fm(band,"CLOSE",stabfreq,"ON"); // LCU_switchon_proc_fm(band); // LO_tuning_block_fm(band,stabfreq); HRS_config_block_fm(band,hrs_mode); WBS_calib_fm(band); WBS_tune_proc_fm(band); HRS_tune_block_fm(band); // chopmode = "tp"; n = time_stabil * 60 / integ_time + 1; // Proc_stability_intcold(band,n,hrs_mode,integ_time,backend,chopmode,chop_phase); } // //Get frequency corresponding to index freq_index if(stab != "stab") { stabfreq = dlookup(tab,"" + freq_index,"freq_" + stab); } time_systab = iround(dlookup(tab,"" + freq_index,"tsystab")); //Only deal with non-zero entries if(stabfreq != 0.0) { // if(stab == "int") { n = 450; // Init_MSA_HBB_fm(band,"CLOSE",stabfreq,"ON"); LO_tuning_block_fm(band,stabfreq); WBS_calib_fm(band); WBS_tune_proc_fm(band); HRS_tune_block_fm(band); // Proc_stability_intcold_inthot(band,n,hrs_mode,integ_time,backend,chopmode,chop_phase); } // if(stab == "lsw") { n = 450; // Init_MSA_CBB_fm(band,"CLOSE",stabfreq,"ON"); LO_tuning_block_fm(band,stabfreq); WBS_calib_fm(band); WBS_tune_proc_fm(band); HRS_tune_block_fm(band); // Proc_stability_intcold_exthot(band,n,hrs_mode,integ_time,backend,chopmode,chop_phase); } // if(stab == "sys") { //Start with 4min fast HRS sampling double sampling_rate = 3.0; //Sampling rate: 2 (2 HRS-H + 2 HRS-V), 4 (HRS-H + HRS-V, 2 HRS-H or 2 HRS-V) or 8 (1 HRS-H or 1 HRS-V) Hz double hrs_h_1 = 7.4; //Position in IF of HRS-H sub-band 1 double hrs_h_2 = 7.4; //Position in IF of HRS-H sub-band 2 double hrs_v_1 = 7.4; //Position in IF of HRS-V sub-band 1 double hrs_v_2 = 7.4; //Position in IF of HRS-V sub-band 2 double[] hrs_subband = [hrs_h_1,hrs_h_2,hrs_v_1,hrs_v_2]; string hrs_polarization = "B"; //HRS polarization: selection works only for 4 and 8 Hz n = 960; backend = "hrs"; // Init_MSA_HBB_fm(band,"CLOSE",stabfreq,"ON"); LO_tuning_block_fm(band,stabfreq); // if(band_nb > 10.0) { Stability_fast_proc_fm(band,n,hrs_subband,sampling_rate,hrs_polarization); } // chopmode = "tp"; backend = "both"; n = time_systab * 60 / integ_time; // HRS_config_block_fm(band,hrs_mode); WBS_calib_fm(band); WBS_tune_proc_fm(band); HRS_tune_block_fm(band); Proc_stability_intcold(band,n,hrs_mode,integ_time,backend,chopmode,chop_phase); } // if(stab == "fsw") { chopmode = "fsw"; n = 225; // Init_MSA_HBB_fm(band,"CLOSE",stabfreq,"ON"); //Look at HBB for further tuning - then move to SKY //LO and backend tunings are done later when tuning FSW1 and FSW2 //LO_tuning_block_fm (band,stabfreq); //WBS_calib_fm(band) ; //WBS_tune_proc_fm(band); //HRS_tune_block_fm(band); // //For FSW, the throw is obtained by index //Retrieve frequency throws from LUT string tabfsw = "config_stabthrow_" + band + ".config"; double bandnb = GetBandCode(band); double throw_inf = dlookup(tabfsw,"" + freq_index,"throw" + throw_index + "_inf"); double throw_sup = dlookup(tabfsw,"" + freq_index,"throw" + throw_index + "_sup"); //Move FSW1 by the left part of the throw stabfreq = stabfreq + throw_inf / 1000.0; //Compute throw double freq_throw = throw_sup - throw_inf; message("" + stabfreq + "," + freq_throw); if(freq_throw != 0.0) { //Check that frequencies to switch are not far by more than 1 index Check_FSW_index_proc_fm(band,stabfreq - freq_throw / 2000.0,stabfreq + freq_throw / 2000.0); Proc_stability_freqswitch_COP(band,stabfreq,freq_throw,n,hrs_mode,integ_time,backend,freq_index); } //For one freq. in 1a, 3a, 6a and 7b, the FSW on the CBB is performed if(band == "1a" || band == "3a" || band == "6a" || band == "7b") { string tabfswcbb = "config_stabfreq_fsw_CBB_" + band + ".config"; double fsw_cbb_freq = dlookup(tabfswcbb,"" + iceil(1.0),"freq") + 0.0010 * dlookup(tabfswcbb,"" + iceil(1.0),"throw" + throw_index + "_inf"); double freq_throw_cbb = dlookup(tabfswcbb,"" + iceil(1.0),"throw" + throw_index + "_sup") - dlookup(tabfswcbb,"" + iceil(1.0),"throw" + throw_index + "_inf"); message("CBB: " + fsw_cbb_freq + "," + freq_throw_cbb); if(fsw_cbb_freq == stabfreq && freq_throw_cbb == freq_throw) { int n_cbb = n; if(bandnb < 6.0) { //only 15 min n_cbb = n / 2; } message("CBB: " + fsw_cbb_freq + "," + freq_throw_cbb); Proc_stability_freqswitch_COP_CBB(band,stabfreq,freq_throw,n_cbb,hrs_mode,integ_time,backend); } } // } // if(stab == "dbs") { n = 450; // Init_MSA_HBB_fm(band,"CLOSE",stabfreq,"ON"); LO_tuning_block_fm(band,stabfreq); WBS_calib_fm(band); WBS_tune_proc_fm(band); HRS_tune_block_fm(band); // Proc_stability_dbs(band,n,hrs_mode,integ_time,backend,shutter,chopmode,chop_phase); } // } } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the observing mode procedure PositionSwitch_commanding { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // chunk size int n_int = 3; // number of data dumps for integration per chop phase int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,20,1,21,0]; // Timing of the observation from telescope int n_loadinterval = 10; // number of nods before a load measurement int loadlength = 21; // Load duration bool final_load = false; // Need for final load measurement }{ // Auxiliary variables // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time int tnodslew = telescopetimes[2]; // slew dead time between points // Consistency checks are performed in the telescope procedure //////////////////////////////////////////////////////////////////////// // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // // Clustering is currently not implemented in MPS - switched off here int clustered = 0; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] rates = dataparms{1}; int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 1) { // Initialization if(clustered != 1) { HIFIInitObs(); TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal"); } delay(tinitslew - (time() - startobs) - loadlength - hkduration); // First load measurement HIFISetHK("normal",false); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } if(state[0] == 7) { // OFF Integration HIFIConfigureContIntegration(data_time,n_int,band,lo_freq,backendreadoutparms); HIFIContOffIntegration(data_time,n_int,rates); // Does a nod slew follow? occurs for odd cycle numbers if(state[2] % 2 == 1 && state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } if(state[0] == 3) { // ON integration HIFIConfigureContIntegration(data_time,n_int,band,lo_freq,backendreadoutparms); HIFIContOnIntegration(data_time,n_int,rates); // Does a nod slew follow? occurs for even cycle numbers if(state[2] % 2 == 0 && state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } if(state[0] == 9) { // Load nod delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } if(state[0] == 5) { delay(readoutdead); if(final_load) { LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } HIFICloseObs(); } } } // General parameter scan, procedure // Allows to check sensitivity or stability in a range of // user-input parameters procedure Parameter_Scan_Investigation_fm { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency string param_scan = "DIPL" in ["DIPL","MAG","MBIAS","VDRAIN2"]; //The parameter to scan: DIPL, MAG, MBIAS, VDRAIN2 double[] param_scan_input = [0.0,10.0,0.0,10.0,1.0]; //Min., Max and step value for parameter to be scanned string measurement_type = "NOISE" in ["NOISE","STAB","IFPOWER"]; //Type of measurement: NOISE (hotcold), IFPOWER (total power meast) or STAB (stability on CBB) int integ_time = 4; //Integration time PER PHASE for the HotCold measurement int n = 100; //The number of 1sec integrations in case of Stability string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string chopmode = "tp" in ["tp","slowchop","fastchop"]; //modulation mode between hot/cold: tp, slowchop, fastchop double chop_phase = 1.0 in [0.2,2.0]; // Chop phase length }{ //Move chopper to hot source Chopper_Rotation_block_fm(band,"chop_M3_ang","chop_hot_ang"); // //WBS calibration and backend tuning if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band); WBS_tune_proc_fm(band); } if(backend == "hrs" || backend == "both") { HRS_tune_block_fm(band); } // //Configure spectroscopy according to the chopmode for hotcold int[] res = [0,0]; int n_wbs1 = 0; int n_hrs_trans = 0; int total_time = 0; // if(chopmode == "tp") { res = Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); total_time = res[0] * res[1]; } if(chopmode == "slowchop") { res = Configure_Spectrometer_hc_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); total_time = res[0] * res[1]; } if(chopmode == "fastchop") { //Integ_time expected here is the TOTAL integration time with both phases + residual HRS time res = Configure_Spectrometer_fast_chop_proc_fm(band,integ_time * 2,chop_phase,hrs_mode,backend); total_time = iceil(chop_phase * double(res[1] * res[2])); //debug_print("Fast chop parameters: n_wbs1 = "+res[2]+", n_hrs_trans = "+res[3]); n_wbs1 = res[2]; n_hrs_trans = res[3]; } // //Start loop on parameter. //We assume backends + FPU + LO are all setup at the frequency of interest // double param_current_value_H = param_scan_input[0]; double param_current_value_V = param_scan_input[2]; int step_H = 1; int step_V = 1; if(param_scan_input[4] != 0.0) { step_H = iceil((param_scan_input[1] - param_scan_input[0]) / param_scan_input[4]); step_V = iceil((param_scan_input[3] - param_scan_input[2]) / param_scan_input[4]); } if(step_H > step_V) { error("The step size and the respective parameters chosen imply more steps for H than for V. Please adjust to get the same amount of steps."); } if(step_V > step_H) { error("The step size and the respective parameters chosen imply more steps for V than for H. Please adjust to get the same amount of steps."); } while(param_current_value_H <= param_scan_input[1]) { //Check parameter type if(param_scan == "DIPL") { //Diplexer scan //Set diplexer current Hifi_HIFI_CH1_DPACT_C($BBID,param_current_value_H); Hifi_HIFI_CV1_DPACT_C($BBID,param_current_value_V); delay(1); } if(param_scan == "MBIAS") { //mixer bias scan //Set mixer bias Mixerbias(param_current_value_H,param_current_value_V); } if(param_scan == "MAG") { //magnet scan //Set magnet current //If first setting, set to max. first if(param_current_value_H == param_scan_input[0]) { {double,string}[] result_d = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,lo_freq); Hifi_HIFI_CH1_MX_MG_C($BBID,result_d[0]{0}); Hifi_HIFI_CV1_MX_MG_C($BBID,result_d[1]{0}); delay(1); } //set to current value Hifi_HIFI_CH1_MX_MG_C($BBID,param_current_value_H); Hifi_HIFI_CV1_MX_MG_C($BBID,param_current_value_V); delay(1); } if(param_scan == "VDRAIN2") { //Drain2 voltage scan LCU_config_nominal_w_D2_proc_fm(band,lo_freq,param_current_value_H); } // //Measurement // if(measurement_type == "NOISE") { //HotCold // //Noise temperature measurement Hot_cold(band,hrs_mode,backend,integ_time,chopmode,n_wbs1,n_hrs_trans); // } if(measurement_type == "IFPOWER") { //Simple total power measurement if(chopmode != "tp") { error("Option IFPOWER cannot be used in chopped mode. Please use total power (tp)"); } else { Spectro_total_power_block_fm(band,res,backend); //Integration is done } } if(measurement_type == "STAB") { //Stability //Noise temperature measurement: removed since 9.15.1. //Hot_cold(band,hrs_mode,backend,total_time,chopmode,n_wbs1,n_hrs_trans); //Stability measurement on cold internal source //Total power stability measurement: WBS only, 2sec. for B1-5, 1sec for B6-7 TP if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { //Stability_intcold_fm (band,n,2,"wbs",hrs_mode,chopmode); Stability_intcold_fm(band,n,integ_time,backend,hrs_mode,chopmode,chop_phase); } else { //Stability_intcold_fm (band,n,1,"wbsFast2",hrs_mode,chopmode); Stability_intcold_fm(band,n,integ_time,backend,hrs_mode,chopmode,chop_phase); } // } //increase parameter param_current_value_H = param_current_value_H + param_scan_input[4]; param_current_value_V = param_current_value_V + param_scan_input[4]; //Case of step = 0: need to avoid infinite loop if(param_scan_input[4] == 0.0) { param_current_value_H = param_current_value_H + 1000.0; param_current_value_V = param_current_value_V + 1000.0; } } // } //Generic procedure for slowchop using the adequate instrument side //It also converts prime voltage into redundant voltage procedure HIFI_Spectr_slow_chop_proc_fm { double chop_angle1 = 0.0; double chop_angle2 = 0.0; }{ //Convert prime voltage into redundant voltage chop_angle1 = Check_Chopper_Prime_Redundant(chop_angle1); chop_angle2 = Check_Chopper_Prime_Redundant(chop_angle2); //check prime or redundant keyword {double,string}[] result_d = ConfigurationReader("name_chopper",["prime_or_redundant"],"0",0.0); if(result_d[0]{1} == "prime") { Hifi_HIFI_P_Spectr_slow_chop($BBID,chop_angle1,chop_angle2); } else { Hifi_HIFI_R_Spectr_slow_chop($BBID,chop_angle1,chop_angle2); } // } {string,double,double}[] procedure HifiSScanModeFSwitchSequencerInit { string modeName = "fs-freq"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles per frequency and pointing int n_switch_off = 1 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles on OFF int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int n_cycles = 1 in [1,600]; // Number of half OFF-ON-ON-OFF cycles at one frequency int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,redundancy,wbs1Used,wbs2Used,data_time); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hr1{0},hr1{1},hr1{3}},{hr2{0},hr2{1},hr2{3}},wb1,wb2}; // Get frequency grid characteristic parameters {double,int,double} gfref = GetFReference(band,lo_freq,lo_freq_up); double reffreq = gfref{0}; int stdredun = gfref{1}; double stdstep = gfref{2}; int increment = stdredun / redundancy; // allowed group size double nocaliblen = GetFNoCalibLength(band,reffreq); int n_freq_point_guess = ifloor(nocaliblen / (stdstep * double(increment)) + 1.0); int n_freq_point_range = 1 - n_freq_point_guess; if(n_freq_point_range == 0) { n_freq_point_range = 1; } // Now general part of Frequency switch modes {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // limits from noise section // spectral scans always use the full bandwidth for reference bool narrowReference = false; {double,double,double,double} phaselengths = FSwitchPhaseLengths(band,lo_freq,effResolution,narrowReference); // Compute derived quantities int data_time_guess = imin(imax(iceil(phaselengths{1}),datalimit),20); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } // How much time for single ON phase int n_switch_on_guess = imax(iceil(2.0 * phaselengths{0} / ((double(n_freq_point_guess) + sqrt(double(n_freq_point_guess))) * 2.0 * double(data_time_guess))),1); int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } // OFF phase int data_time_off_guess = imin(imax(iceil(phaselengths{2}),datalimit),20); int data_time_off_range = datalimit - data_time_off_guess; if(data_time_off_range == 0) { data_time_off_range = 1; } int n_switch_off_guess = imax(iceil(double(data_time_guess * n_switch_on_guess) * sqrt(double(n_freq_point_guess)) / (double(data_time_off_guess) * sqrt(phaselengths{3} / effResolution{1}))),1); int n_switch_off_range = 1 - n_switch_off_guess; if(n_switch_off_range == 0) { n_switch_off_range = 1; } // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"data_time_off",double(data_time_off_guess),double(data_time_off_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)},{"n_switch_off",double(n_switch_off_guess),double(n_switch_off_range)},{"n_freq_point",double(n_freq_point_guess),double(n_freq_point_range)}]; return retvalues; } //General script to read TM1, TM2,etc, procedure procedure LCU_Read_TM_pages_OLD_proc_fm { }{ //Re-implement old way to be consistent with MOIS manual procedures // //Get various TM pages. This will clear error flags too //Hifi_HIFI_LCU_all_tuning_hk(); //delay(2); ///////////////////////////////////// //Temporary work-around for TVTB SFT //Get various TM pages Hifi_HIFI_LCU_macro_tuning_hk("HSK_TM1"); delay(2); Hifi_HIFI_LCU_macro_tuning_hk("HSK_TM2"); delay(2); Hifi_HIFI_LCU_macro_tuning_hk("HSK_TM3"); delay(2); Hifi_HIFI_LCU_macro_tuning_hk("HSK_TM"); delay(2); Hifi_HIFI_LCU_macro_tuning_hk("HSK_G"); delay(2); // //Clear error flags Hifi_HIFI_LCU_Single($BBID,"HL_CLR_ERR"); // } ///////////////////////////////////////////////////////////////////////////// // Procedure to perform the noise level evaluation for the OTF observing mode {double,double,double,double,double} procedure OTFmap_noisecomputer { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF int nlines_tot = 1; // Number of rows in the map int npoints = 10; // Number of data dumps per row int n_supersample = 1; // Supersamplingfactor int n_linesperscan = 2; // Number of lines between two OFFs int n_cover = 1; // Number of map coverages int tslew = 20; // Minimum time between OFF and point double tscan = 60.0; // Total average duration of one scan {double,double,double} tact = {10.0,4.0,12.0}; // field of actual timings }{ // The sum of drift noise and radiometric noise is computed. // double tdead = tact{0}; // Average dead time in one slew double tint_act = tact{1}; // integration time excluding all dead times double tintoff = tact{2}; // integration time on OFF // Get parameters which are needed double tsys = InterpolateTsys(band,lo_freq); double eta_mb = InterpolateCoupling(band,lo_freq); double[] gssb = InterpolateGssb(band,lo_freq); // Get the drift parameters to compute the drift noise double[] allanparms = InterpolateSpecAllan(band,lo_freq,oneGHzReference); // rescale to frequency resolution double alpha = allanparms[1]; double binningexp = 1.0 / allanparms[2]; double allan_time_lores = allanparms[0] * pow(1.0 / eff_resolution{1},binningexp); double allan_time_hires = allanparms[0] * pow(1.0 / eff_resolution{0},binningexp); // Noise computation and OFF integration depends on the number of really // independent points - different treatment for repeated scans of same line double scanpoints = double(n_linesperscan * npoints); double qval = tintoff / (sqrt(scanpoints) * tint_act); if(nlines_tot == 1 && n_linesperscan > 1) { // Get actual noise // This is returned twice: for both limiting resolutions double systemnoise_lores = OtfRepeatedNoise(double(n_linesperscan),scanpoints,[tint_act / allan_time_lores,tdead / allan_time_lores,double(tslew) / allan_time_lores,qval,alpha]); double systemnoise_hires = OtfRepeatedNoise(double(n_linesperscan),scanpoints,[tint_act / allan_time_hires,tdead / allan_time_hires,double(tslew) / allan_time_hires,qval,alpha]); double noiserat = OtfRepeatedNoiseRatio(double(n_linesperscan),scanpoints,[tint_act / allan_time_lores,tdead / allan_time_lores,double(tslew) / allan_time_lores,qval,alpha]); } else { // Get actual noise systemnoise_lores = OtfNoise(scanpoints,[tint_act / allan_time_lores,tdead / allan_time_lores,double(tslew) / allan_time_lores,qval,alpha]); systemnoise_hires = OtfNoise(scanpoints,[tint_act / allan_time_hires,tdead / allan_time_hires,double(tslew) / allan_time_hires,qval,alpha]); noiserat = OtfNoiseRatio(scanpoints,[tint_act / allan_time_lores,tdead / allan_time_lores,double(tslew) / allan_time_lores,qval,alpha]); } // Renormalize systemnoise_lores = systemnoise_lores * scanpoints / (tscan * double(n_cover)); systemnoise_hires = systemnoise_hires * scanpoints / (tscan * double(n_cover)); // Compute total double sideband noise double dsbnoise_lores = tsys * sqrt(systemnoise_lores / (eff_resolution{1} * 1000000.0)); double dsbnoise_hires = tsys * sqrt(systemnoise_hires / (eff_resolution{0} * 1000000.0)); // Translate to the main beam scale, correct for eta_mb // (This is typically not done at ground based telescopes, // but leads often to problems there - to be discussed.) dsbnoise_lores = dsbnoise_lores / eta_mb; dsbnoise_hires = dsbnoise_hires / eta_mb; // Get single sideband noise equivalent double usbnoise_lores = dsbnoise_lores / gssb[0]; double usbnoise_hires = dsbnoise_hires / gssb[0]; double lsbnoise_lores = dsbnoise_lores / gssb[1]; double lsbnoise_hires = dsbnoise_hires / gssb[1]; // Return noise values and the maximum ratio of drift to radiometric noise return {usbnoise_lores,usbnoise_hires,lsbnoise_lores,lsbnoise_hires,noiserat}; } // Change mixer bias block Mixerbias_block_fm HIFI 3205 { double bias_h = 0.0; double bias_v = 0.0; }{ //Start_block() ; Mixerbias(bias_h,bias_v); } // Generic A_M function // DT/MB - 3 June 2005 int[] procedure GetA_M { double flo = 15.0; // Input HRS internal LO freq. in GHz }{ // First guess of M int m = iround(flo / 200.0 - 1.0); int a = iround((flo - 200.0 * (double(m) + 1.0)) / 20.0); // // Adjust if(a < 0) { m = m - 1; a = iround((flo - 200.0 * (double(m) + 1.0)) / 20.0); } // int[] a_m = [a,m]; return a_m; } // HRS partial configuration, procedure // Configures the resolution mode procedure HRS_config_resol_fm { string band = "4a"; // HIFI band string[] hrs_mode = ["wb","wb"]; //HRS resolution code }{ //////////////////////////////////////////////////////////////////// //Now Configure blocks //H-polar string hrs_filename_h = "name_confighrs_" + hrs_mode[0]; {double,string}[] result = ConfigurationReader(hrs_filename_h,["hrh_block_1","hrh_block_2","hrh_block_3","hrh_block_4","hrh_block_5","hrh_block_6","hrh_block_7","hrh_block_8"],band,0.0); string hrh_block_1 = result[0]{1}; string hrh_block_2 = result[1]{1}; string hrh_block_3 = result[2]{1}; string hrh_block_4 = result[3]{1}; string hrh_block_5 = result[4]{1}; string hrh_block_6 = result[5]{1}; string hrh_block_7 = result[6]{1}; string hrh_block_8 = result[7]{1}; // result = ConfigurationReader("name_delays",["hrs_config_delay"],band,0.0); int hrs_config_delay = iround(result[0]{0}); // Hifi_HIFI_Config_HRS_H_blocks($BBID,hrh_block_1,hrh_block_2,hrh_block_3,hrh_block_4,hrh_block_5,hrh_block_6,hrh_block_7,hrh_block_8); //delay(hrs_config_delay); // //V-polar string hrs_filename_v = "name_confighrs_" + hrs_mode[1]; result = ConfigurationReader(hrs_filename_v,["hrv_block_1","hrv_block_2","hrv_block_3","hrv_block_4","hrv_block_5","hrv_block_6","hrv_block_7","hrv_block_8"],band,0.0); string hrv_block_1 = result[0]{1}; string hrv_block_2 = result[1]{1}; string hrv_block_3 = result[2]{1}; string hrv_block_4 = result[3]{1}; string hrv_block_5 = result[4]{1}; string hrv_block_6 = result[5]{1}; string hrv_block_7 = result[6]{1}; string hrv_block_8 = result[7]{1}; // Hifi_HIFI_Config_HRS_V_blocks($BBID,hrv_block_1,hrv_block_2,hrv_block_3,hrv_block_4,hrv_block_5,hrv_block_6,hrv_block_7,hrv_block_8); // //Wait delay to allow all setting to be configured delay(hrs_config_delay); } //Generic procedure to launch engineering scan applied to chopper rotation, procedure procedure Engineering_scan_for_closed_loop_scan_ops { double targetAngle = 0.0; //Target chopper voltage int milliSecSample = 3; // interval between samples int samplesBefore = 30 in [0,50]; // HIF_N_samples_1 int samplesAfter = 1000 in [0,1000]; // HIF_N_samples_2 string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ // if(prime_or_redundant == "Prime") { Hifi_HIFI_P_Chopper_scan_fast(milliSecSample,targetAngle,samplesBefore,samplesAfter); } else { Hifi_HIFI_R_Chopper_scan_fast(milliSecSample,targetAngle,samplesBefore,samplesAfter); } // // delay calculation int nb_HK = 1; //For this TC, the 2 last HK fields are blanked out int millisecondsUsed = 1000 + 10 + milliSecSample * nb_HK * (samplesBefore + samplesAfter); delay(iceil(0.0010 * double(millisecondsUsed))); // } // Single integration at OFF position for a specified time block HIFIContOffIntegration HIFI 6021 { int n_int = 1; // Integration time counter int data_time = 4; // Integration time between two data readouts double[] rates = [120.0,1.0,2.0]; // Data rates between and during integrations }{ HIFI_Spectr_tp_proc_aot(n_int,data_time,rates); } // Interpolate total power system Allan time and exponent double[] procedure InterpolateTpAllan { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency bool subband = false; // 1GHz bandwith reference instead of full IF }{ if(subband) { double[] allan = CalibrationReader("system_Allan_subband",["tp_Allan_time","tp_Allan_exp","tp_binning_exp"],band,lo_freq); } else { allan = CalibrationReader("system_Allan",["tp_Allan_time","tp_Allan_exp","tp_binning_exp"],band,lo_freq); } return allan; } // BLOCK : Functional Test No 4 (HRS Scan the HRS Attenuators) block HRS_functional_test_No_4_block_fm HIFI 3640 { string band = "1a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int integ_time = 4; //Total integration time in sec. string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); int repeats = 32; double hrsH_attenuators_value = 15.5; double hrsV_attenuators_value = 15.5; //Test is done in WB mode string hrsh_blocks_configuration = "corr_wide"; string hrsv_blocks_configuration = "corr_wide"; // Configure spectroscopy Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); // // Configure blocks //================= //H-polar Hifi_HIFI_Config_HRS_H_blocks($BBID,hrsh_blocks_configuration,hrsh_blocks_configuration,hrsh_blocks_configuration,hrsh_blocks_configuration,hrsh_blocks_configuration,hrsh_blocks_configuration,hrsh_blocks_configuration,hrsh_blocks_configuration); // //delay(1); //V-polar Hifi_HIFI_Config_HRS_V_blocks($BBID,hrsv_blocks_configuration,hrsv_blocks_configuration,hrsv_blocks_configuration,hrsv_blocks_configuration,hrsv_blocks_configuration,hrsv_blocks_configuration,hrsv_blocks_configuration,hrsv_blocks_configuration); // delay(1); // // Fetch internal LO settings //=========================== //H-polar string hrs_filename_h = "name_confighrs_" + hrs_mode[0]; {double,string}[] result = ConfigurationReader(hrs_filename_h,["hrh_switch","hrh_up_ol1","hrh_up_ol2","hrh_up_ol3","hrh_up_ol4","hrh_down_ol5","hrh_down_ol6","hrh_down_ol7"],band,0.0); double[] hrsH_LO = [result[1]{0},result[2]{0},result[3]{0},result[4]{0},result[5]{0},result[6]{0},result[7]{0}]; string hrs_polarization_h = result[0]{1}; //V-polar string hrs_filename_v = "name_confighrs_" + hrs_mode[1]; result = ConfigurationReader(hrs_filename_v,["hrv_switch","hrv_up_ol1","hrv_up_ol2","hrv_up_ol3","hrv_up_ol4","hrv_down_ol5","hrv_down_ol6","hrv_down_ol7"],band,0.0); double[] hrsV_LO = [result[1]{0},result[2]{0},result[3]{0},result[4]{0},result[5]{0},result[6]{0},result[7]{0}]; string hrs_polarization_v = result[0]{1}; // //Convert IF frequencies into A and M parameters //Truncate wb or hr keyword: string[] output_hrs_mode = GetHrsMode_proc_fm(hrs_mode); string hrs_mode_h = output_hrs_mode[0]; string hrs_mode_v = output_hrs_mode[1]; // int[] a_m_parameter = ComputeA_M_parameters([hrs_mode_h,hrs_mode_v],hrsH_LO[0],hrsH_LO[1],hrsH_LO[2],hrsH_LO[3],hrsH_LO[4],hrsH_LO[5],hrsH_LO[6],hrsV_LO[0],hrsV_LO[1],hrsV_LO[2],hrsV_LO[3],hrsV_LO[4],hrsV_LO[5],hrsV_LO[6]); // //H-polar int hrsH_LO1_M = a_m_parameter[1]; int hrsH_LO1_A = a_m_parameter[0]; int hrsH_LO2_M = a_m_parameter[3]; int hrsH_LO2_A = a_m_parameter[2]; int hrsH_LO3_M = a_m_parameter[5]; int hrsH_LO3_A = a_m_parameter[4]; int hrsH_LO4_M = a_m_parameter[7]; int hrsH_LO4_A = a_m_parameter[6]; int hrsH_LO5_M = a_m_parameter[9]; int hrsH_LO5_A = a_m_parameter[8]; int hrsH_LO6_M = a_m_parameter[11]; int hrsH_LO6_A = a_m_parameter[10]; int hrsH_LO7_M = a_m_parameter[12]; //V-polar int hrsV_LO1_M = a_m_parameter[14]; int hrsV_LO1_A = a_m_parameter[13]; int hrsV_LO2_M = a_m_parameter[16]; int hrsV_LO2_A = a_m_parameter[15]; int hrsV_LO3_M = a_m_parameter[18]; int hrsV_LO3_A = a_m_parameter[17]; int hrsV_LO4_M = a_m_parameter[20]; int hrsV_LO4_A = a_m_parameter[19]; int hrsV_LO5_M = a_m_parameter[22]; int hrsV_LO5_A = a_m_parameter[21]; int hrsV_LO6_M = a_m_parameter[24]; int hrsV_LO6_A = a_m_parameter[23]; int hrsV_LO7_M = a_m_parameter[25]; // // Loops on the different configurations of the HRS attenuators //=============================================== for(int i = 0 .. repeats - 1) { //======================================= Hifi_HIFI_Config_HRS_H_att_lo($BBID,hrs_polarization_h,hrsH_attenuators_value,hrsH_attenuators_value,hrsH_attenuators_value,hrsH_attenuators_value,hrsH_attenuators_value,hrsH_attenuators_value,hrsH_attenuators_value,hrsH_attenuators_value,hrsH_LO1_M,hrsH_LO1_A,hrsH_LO2_M,hrsH_LO2_A,hrsH_LO3_M,hrsH_LO3_A,hrsH_LO4_M,hrsH_LO4_A,hrsH_LO5_M,hrsH_LO5_A,hrsH_LO6_M,hrsH_LO6_A,hrsH_LO7_M); // //delay(2); Hifi_HIFI_Config_HRS_V_att_lo($BBID,hrs_polarization_v,hrsV_attenuators_value,hrsV_attenuators_value,hrsV_attenuators_value,hrsV_attenuators_value,hrsV_attenuators_value,hrsV_attenuators_value,hrsV_attenuators_value,hrsV_attenuators_value,hrsV_LO1_M,hrsV_LO1_A,hrsV_LO2_M,hrsV_LO2_A,hrsV_LO3_M,hrsV_LO3_A,hrsV_LO4_M,hrsV_LO4_A,hrsV_LO5_M,hrsV_LO5_A,hrsV_LO6_M,hrsV_LO6_A,hrsV_LO7_M); // delay(1); // Take a spectrum //================ HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); //Delay To be sure that the Spectr_total_power finished //========================================== // // Change the value of the 8 attenuators //============================== hrsH_attenuators_value = hrsH_attenuators_value - 0.5; hrsV_attenuators_value = hrsV_attenuators_value - 0.5; } } //////////////////////////////////// // OTF load chop observing mode without baseline calibration // {string,double,double}[] procedure HifiMappingProcLoadChopOTFNoRefSequencerInit { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source {double,double} lineDistance = {0.0050,0.0050}; // Distance between subsequent rows int nlines = 1 in [1,240]; // Number of rows in the map double stepsize = 0.0050 in [0.0,0.13333]; // Distance between subsequent points in the OTF line int npoints = 10 in [1,720]; // Number of data dumps per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // chunk size given by the data rates and optimum speed int n_switch_on = 1 in [1,1800]; // Supersamplingfactor int n_cycles = 1 in [1,1200]; // Number of map coverages int load_interval = 1800 in [10,7200]; // load period defines number of lines between two loads bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode // limit on data rate {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // limits from noise section // Get the drift parameters to compute the drift noise // System Allan variance double[] allanparms = InterpolateSpecAllan(band,lo_freq,oneGHzReference); // rescale to frequency resolution double alpha = allanparms[1]; double binningexp = 1.0 / allanparms[2]; double allan_time_lores = allanparms[0] * pow(1.0 / effResolution{1},binningexp); // Compute derived quantities int data_time_guess = imin(imax(iceil(0.3 * allan_time_lores),datalimit),20); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } // n_switch limited by load_interval - 2 lines should be possible int n_switch_on_guess = load_interval / (4 * npoints * data_time_guess); int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } // Contruct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)}]; return retvalues; } ////////////////////////////////////////////////////////////////// // HRS complete configuration with maximum attenuation, block // Both polarizations are treated block HRS_config_max_att_block_aot HIFI 6634 { string band = "4a"; // HIFI band string[] hrs_mode = ["wb","wb"]; //HRS resolution code }{ // Fetch HRS configuration parameters //=================================== //H-polar string hrs_filename_h = "name_confighrs_" + hrs_mode[0]; {double,string}[] result = ConfigurationReader(hrs_filename_h,["hrh_switch","hrh_1u_att","hrh_1l_att","hrh_2u_att","hrh_2l_att","hrh_3u_att","hrh_3l_att","hrh_4u_att","hrh_4l_att","hrh_up_ol1","hrh_up_ol2","hrh_up_ol3","hrh_up_ol4","hrh_down_ol5","hrh_down_ol6","hrh_down_ol7"],band,0.0); string hrs_polarization_h = result[0]{1}; double[] hrsH_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; //V-polar string hrs_filename_v = "name_confighrs_" + hrs_mode[1]; result = ConfigurationReader(hrs_filename_v,["hrv_switch","hrv_1u_att","hrv_1l_att","hrv_2u_att","hrv_2l_att","hrv_3u_att","hrv_3l_att","hrv_4u_att","hrv_4l_att","hrv_up_ol1","hrv_up_ol2","hrv_up_ol3","hrv_up_ol4","hrv_down_ol5","hrv_down_ol6","hrv_down_ol7"],band,0.0); string hrs_polarization_v = result[0]{1}; double[] hrsV_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; // result = ConfigurationReader("name_delays",["hrs_config_delay"],band,0.0); int hrs_config_delay = iround(result[0]{0}); //Convert IF frequencies into A and M parameters //Truncate wb or hr keyword: string[] output_hrs_mode = GetHrsMode_proc_fm(hrs_mode); string hrs_mode_h = output_hrs_mode[0]; string hrs_mode_v = output_hrs_mode[1]; // int[] a_m_parameter = ComputeA_M_parameters([hrs_mode_h,hrs_mode_v],hrsH_LO[0],hrsH_LO[1],hrsH_LO[2],hrsH_LO[3],hrsH_LO[4],hrsH_LO[5],hrsH_LO[6],hrsV_LO[0],hrsV_LO[1],hrsV_LO[2],hrsV_LO[3],hrsV_LO[4],hrsV_LO[5],hrsV_LO[6]); //H-polar int hrh_up_ol1_m = a_m_parameter[1]; int hrh_up_ol1_a = a_m_parameter[0]; int hrh_up_ol2_m = a_m_parameter[3]; int hrh_up_ol2_a = a_m_parameter[2]; int hrh_up_ol3_m = a_m_parameter[5]; int hrh_up_ol3_a = a_m_parameter[4]; int hrh_up_ol4_m = a_m_parameter[7]; int hrh_up_ol4_a = a_m_parameter[6]; int hrh_down_ol5_m = a_m_parameter[9]; int hrh_down_ol5_a = a_m_parameter[8]; int hrh_down_ol6_m = a_m_parameter[11]; int hrh_down_ol6_a = a_m_parameter[10]; int hrh_down_ol7_m = a_m_parameter[12]; //V-polar int hrv_up_ol1_m = a_m_parameter[14]; int hrv_up_ol1_a = a_m_parameter[13]; int hrv_up_ol2_m = a_m_parameter[16]; int hrv_up_ol2_a = a_m_parameter[15]; int hrv_up_ol3_m = a_m_parameter[18]; int hrv_up_ol3_a = a_m_parameter[17]; int hrv_up_ol4_m = a_m_parameter[20]; int hrv_up_ol4_a = a_m_parameter[19]; int hrv_down_ol5_m = a_m_parameter[22]; int hrv_down_ol5_a = a_m_parameter[21]; int hrv_down_ol6_m = a_m_parameter[24]; int hrv_down_ol6_a = a_m_parameter[23]; int hrv_down_ol7_m = a_m_parameter[25]; //Attenuators are fixed //H-polar double hrh_1u_att = 15.5; double hrh_1l_att = 15.5; double hrh_2u_att = 15.5; double hrh_2l_att = 15.5; double hrh_3u_att = 15.5; double hrh_3l_att = 15.5; double hrh_4u_att = 15.5; double hrh_4l_att = 15.5; //V-polar double hrv_1u_att = 15.5; double hrv_1l_att = 15.5; double hrv_2u_att = 15.5; double hrv_2l_att = 15.5; double hrv_3u_att = 15.5; double hrv_3l_att = 15.5; double hrv_4u_att = 15.5; double hrv_4l_att = 15.5; //Configure HRS-H Hifi_HIFI_Config_HRS_H_att_lo($BBID,hrs_polarization_h,hrh_1u_att,hrh_1l_att,hrh_2u_att,hrh_2l_att,hrh_3u_att,hrh_3l_att,hrh_4u_att,hrh_4l_att,hrh_up_ol1_m,hrh_up_ol1_a,hrh_up_ol2_m,hrh_up_ol2_a,hrh_up_ol3_m,hrh_up_ol3_a,hrh_up_ol4_m,hrh_up_ol4_a,hrh_down_ol5_m,hrh_down_ol5_a,hrh_down_ol6_m,hrh_down_ol6_a,hrh_down_ol7_m); //delay(hrs_config_delay); // //Configure HRS-V Hifi_HIFI_Config_HRS_V_att_lo($BBID,hrs_polarization_v,hrv_1u_att,hrv_1l_att,hrv_2u_att,hrv_2l_att,hrv_3u_att,hrv_3l_att,hrv_4u_att,hrv_4l_att,hrv_up_ol1_m,hrv_up_ol1_a,hrv_up_ol2_m,hrv_up_ol2_a,hrv_up_ol3_m,hrv_up_ol3_a,hrv_up_ol4_m,hrv_up_ol4_a,hrv_down_ol5_m,hrv_down_ol5_a,hrv_down_ol6_m,hrv_down_ol6_a,hrv_down_ol7_m); delay(hrs_config_delay); // //Now Configure blocks HRS_config_resol_fm(band,hrs_mode); } // Standing wave study for FSW model //HIFI-COP-X-StWv-FSW procedure StWv_FSW_COP_proc_ops { string band = "1a"; // HIFI band }{ double bandnb = GetBandCode(band); //Retrieve frequencies from LUT: depends on whether this is diplexer or beamsplitter if(bandnb < 5.0 || bandnb == 9.0 || bandnb == 10.0) { string tabstwv = "config_stabfreq_" + band + ".config"; //"config_stwv_fsw_bs.config"; int nb_freq_st = 3; int nb_freq_end = 4; //Special case of band 5b: only 2 first frequencies if(bandnb == 10.0) { nb_freq_st = 1; nb_freq_end = 2; } string column_name = "freq_fsw"; } else { tabstwv = "config_stwv_fsw_dip.config"; nb_freq_st = 1; nb_freq_end = 16; column_name = "lo_freq_" + band; } // //General parameters for scan double step = 0.015; //GHz int total_stepnb = 21; double stepnb = double(total_stepnb / 2); double[] lo_freq_input = [0.0,0.0,0.0]; //Loop on frequencies for(int i = nb_freq_st .. nb_freq_end) { double lo_freq = dlookup(tabstwv,"" + i,column_name); message(band + ", " + lo_freq); //Switch-on FPU on BB Init_MSA_CBB_fm(band,"CLOSE",lo_freq,"ON"); //Build lo_freq_input array lo_freq_input = [lo_freq - stepnb * step,lo_freq + stepnb * step,step]; Standing_wave_nospectra_fm_COP(band,lo_freq_input); } // } //TM to control heater values of LOU, procedure procedure HL_heater_proc_aot { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band. string context = "nominal" in ["nominal","stby"]; //whether heater applies to stby or nominal context }{ double[] cresult = CalibrationReader("name_loheater",["heater_nominal","heater_stby"],band,0.0); double hifi_HL_heater = cresult[0]; if(context == "stby") { hifi_HL_heater = cresult[1]; } Hifi_HIFI_HL_heater($BBID,hifi_HL_heater); } //Set DC bias without switching on the chain, block //All input parameters shall be given by the user block View_SafetyTablePage_block_fm HIFI 3665 { string band = "1a" in ["ALL","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band int freq_index = 0 in [0,31]; //frequency index }{ // //Start_block(); //Switch to diagnostic {double,string}[] result = ConfigurationReader("name_delays",["set_to_nominal_delay"],"0",0.0); int set_to_nominal_delay = iround(result[0]{0}); // Hifi_HIFI_HL_Diagnostic($BBID); delay(set_to_nominal_delay); //Read safety table string band_new = Translate_band_name(band); Hifi_HIFI_non_periodic_hk_LCU(freq_index,"channel_" + band_new); delay(1); //Switch back to nominal Hifi_HIFI_HL_Normal($BBID); delay(set_to_nominal_delay); // } // Stability test, procedure, only backends // Here for dummy/warm context procedure Proc_stability_backend { string band = "1a"; // HIFI band int n = 100; //Number of load pairs to be measured string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int integ_time = 4; //Total integration time in sec. to be set at end of test string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Band0 setting Band0_fm("0","OPEN"); //Band0_hbb_on_fm("0","CLOSE"); // //WBS calibration if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band); //Configure and tune backends WBS_tune_proc_fm(band); } if(backend == "hrs" || backend == "both" || backend == "hrsFast") { //Configure and tune backends HRS_config_min_att_block_fm(band,hrs_mode); HRS_tune_block_fm(band); } // //Configure spectrometers integration: done later //Configure_Spectrometer_proc_fm(band,4,hrs_mode,backend); //2 sec. integration // Stability_backend_fm(band,n,integ_time,backend,hrs_mode); //Configure spectrometers integration back to default in tp mode Configure_Spectrometer_proc_fm(band,4,hrs_mode,backend); } ////////////////////////////////////////////////////////////////////// // Determine data readout period and corresponding data rate {int,double[]} procedure AllDataRates { {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // Readout parameters for HRS1,HRS2, WBS1,WBS2 int data_time = 4; // Integration time between two data readouts bool mode16bits = true; // whether WBS is used in 16bit mode }{ // Definitions - read from calibration file: // WBS if(mode16bits) { int wbit = ifloor(dlookup("datarates","wbsbitnormal","value")); int nchannelwbs = ifloor(dlookup("datarates","nchannelwbsnormal","value")); } else { wbit = ifloor(dlookup("datarates","wbsbithigh","value")); nchannelwbs = ifloor(dlookup("datarates","nchannelwbshigh","value")); } // HRS=24 bit int hbit = ifloor(dlookup("datarates","hrsbit","value")); int nchannelhrs = ifloor(dlookup("datarates","nchannelhrs","value")); // Maximum data rate int pmax = ifloor(dlookup("datarates","maxbuspackets","value")); int osize = ifloor(dlookup("datarates","packetoverhead","value")); // Check with periodic HK {string,int,double,double,double,double} hkparms = PeriodicHKParms("normal"); int hkpackets = iceil(hkparms{2} + hkparms{4}); pmax = pmax - hkpackets; // Dead packets int deadstartpackets = iceil(dlookup("datarates","dead_startpackets","value")); int deadifpackets = iceil(dlookup("datarates","dead_ifpackets","value")); int deadwbsstartsize = iceil(dlookup("datarates","dead_wbsstartsize","value")); int deadwbsifsize = iceil(dlookup("datarates","dead_wbsifsize","value")); int deadhrsstartsize = iceil(dlookup("datarates","dead_hrsstartsize","value")); int deadhrsifsize = iceil(dlookup("datarates","dead_hrsifsize","value")); // sum up channels int n_wchannels = 0; int packets = 0; int allbits = 0; int allhkbits = 0; int newpackets = 0; // First HRS {int,int,int,int} hrssets = HrsSubbandSelection(backendreadoutparms); int n_hchannels = hrssets{2}; int n_vchannels = hrssets{3}; if(n_hchannels > 0) { newpackets = deadstartpackets + (n_hchannels + nchannelhrs - 1) / nchannelhrs; allbits = allbits + n_hchannels * hbit + newpackets * osize + deadhrsstartsize; allhkbits = allhkbits + deadhrsifsize + deadifpackets * osize; packets = packets + newpackets + deadifpackets; } if(n_vchannels > 0) { newpackets = deadstartpackets + (n_vchannels + nchannelhrs - 1) / nchannelhrs; allbits = allbits + n_vchannels * hbit + newpackets * osize + deadhrsstartsize; allhkbits = allhkbits + deadhrsifsize + deadifpackets * osize; packets = packets + newpackets + deadifpackets; } // Now the WBS channels int maxbands = 4; // First WBS if(backendreadoutparms{2}{0}) { n_wchannels = 0; newpackets = 0; for(int i2 = 1 .. maxbands) { int newchannels = backendreadoutparms{2}{1}[i2 - 1][1] - backendreadoutparms{2}{1}[i2 - 1][0]; newpackets = newpackets + (newchannels + nchannelwbs - 1) / nchannelwbs; n_wchannels = n_wchannels + newchannels; } newpackets = deadstartpackets + newpackets; allbits = allbits + n_wchannels * wbit + newpackets * osize + deadwbsstartsize; allhkbits = allhkbits + deadwbsifsize + deadifpackets * osize; packets = packets + newpackets + deadifpackets; } // Second WBS if(backendreadoutparms{3}{0}) { n_wchannels = 0; newpackets = 0; for(int i3 = 1 .. maxbands) { newchannels = backendreadoutparms{3}{1}[i3 - 1][1] - backendreadoutparms{3}{1}[i3 - 1][0]; newpackets = newpackets + (newchannels + nchannelwbs - 1) / nchannelwbs; n_wchannels = n_wchannels + newchannels; } newpackets = deadstartpackets + newpackets; allbits = allbits + n_wchannels * wbit + newpackets * osize + deadwbsstartsize; allhkbits = allhkbits + deadwbsifsize + deadifpackets * osize; packets = packets + newpackets + deadifpackets; } // Now compute minimum time; int tdatamin = (packets + pmax - 1) / pmax; if(tdatamin < 1) { CError("Internal error: Too low packet rate computed."); } // Data rates in bit/s are returned double sciencerate = double(allbits) / double(data_time); double stdhkrate = hkparms{3}; double hkrate = stdhkrate + double(allhkbits) / double(data_time); return {tdatamin,[sciencerate,stdhkrate,hkrate]}; } ////////////////////////////////////////////////////////////////// // HRS complete configuration with maximum attenuation, block // Both polarizations are treated block HRS_standby_block_ops HIFI 7633 { string band = "0"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code }{ // Fetch HRS configuration parameters //=================================== //H-polar string hrs_filename_h = "name_confighrs_" + hrs_mode[0]; {double,string}[] result = ConfigurationReader(hrs_filename_h,["hrh_switch","hrh_1u_att","hrh_1l_att","hrh_2u_att","hrh_2l_att","hrh_3u_att","hrh_3l_att","hrh_4u_att","hrh_4l_att","hrh_up_ol1","hrh_up_ol2","hrh_up_ol3","hrh_up_ol4","hrh_down_ol5","hrh_down_ol6","hrh_down_ol7"],band,0.0); string hrs_polarization_h = result[0]{1}; double[] hrsH_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; //V-polar string hrs_filename_v = "name_confighrs_" + hrs_mode[1]; result = ConfigurationReader(hrs_filename_v,["hrv_switch","hrv_1u_att","hrv_1l_att","hrv_2u_att","hrv_2l_att","hrv_3u_att","hrv_3l_att","hrv_4u_att","hrv_4l_att","hrv_up_ol1","hrv_up_ol2","hrv_up_ol3","hrv_up_ol4","hrv_down_ol5","hrv_down_ol6","hrv_down_ol7"],band,0.0); string hrs_polarization_v = result[0]{1}; double[] hrsV_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; // result = ConfigurationReader("name_delays",["hrs_config_delay"],band,0.0); int hrs_config_delay = iround(result[0]{0}); // //Convert IF frequencies into A and M parameters //Truncate wb or hr keyword: string[] output_hrs_mode = GetHrsMode_proc_ops(hrs_mode); string hrs_mode_h = output_hrs_mode[0]; string hrs_mode_v = output_hrs_mode[1]; // int[] a_m_parameter = ComputeA_M_parameters([hrs_mode_h,hrs_mode_v],hrsH_LO[0],hrsH_LO[1],hrsH_LO[2],hrsH_LO[3],hrsH_LO[4],hrsH_LO[5],hrsH_LO[6],hrsV_LO[0],hrsV_LO[1],hrsV_LO[2],hrsV_LO[3],hrsV_LO[4],hrsV_LO[5],hrsV_LO[6]); //H-polar int hrh_up_ol1_m = a_m_parameter[1]; int hrh_up_ol1_a = a_m_parameter[0]; int hrh_up_ol2_m = a_m_parameter[3]; int hrh_up_ol2_a = a_m_parameter[2]; int hrh_up_ol3_m = a_m_parameter[5]; int hrh_up_ol3_a = a_m_parameter[4]; int hrh_up_ol4_m = a_m_parameter[7]; int hrh_up_ol4_a = a_m_parameter[6]; int hrh_down_ol5_m = a_m_parameter[9]; int hrh_down_ol5_a = a_m_parameter[8]; int hrh_down_ol6_m = a_m_parameter[11]; int hrh_down_ol6_a = a_m_parameter[10]; int hrh_down_ol7_m = a_m_parameter[12]; //V-polar int hrv_up_ol1_m = a_m_parameter[14]; int hrv_up_ol1_a = a_m_parameter[13]; int hrv_up_ol2_m = a_m_parameter[16]; int hrv_up_ol2_a = a_m_parameter[15]; int hrv_up_ol3_m = a_m_parameter[18]; int hrv_up_ol3_a = a_m_parameter[17]; int hrv_up_ol4_m = a_m_parameter[20]; int hrv_up_ol4_a = a_m_parameter[19]; int hrv_down_ol5_m = a_m_parameter[22]; int hrv_down_ol5_a = a_m_parameter[21]; int hrv_down_ol6_m = a_m_parameter[24]; int hrv_down_ol6_a = a_m_parameter[23]; int hrv_down_ol7_m = a_m_parameter[25]; //Attenuators are fixed //H-polar double hrh_1u_att = 15.5; double hrh_1l_att = 15.5; double hrh_2u_att = 15.5; double hrh_2l_att = 15.5; double hrh_3u_att = 15.5; double hrh_3l_att = 15.5; double hrh_4u_att = 15.5; double hrh_4l_att = 15.5; //V-polar double hrv_1u_att = 15.5; double hrv_1l_att = 15.5; double hrv_2u_att = 15.5; double hrv_2l_att = 15.5; double hrv_3u_att = 15.5; double hrv_3l_att = 15.5; double hrv_4u_att = 15.5; double hrv_4l_att = 15.5; //Configure HRS-H Hifi_HIFI_Config_HRS_H_att_lo($BBID,hrs_polarization_h,hrh_1u_att,hrh_1l_att,hrh_2u_att,hrh_2l_att,hrh_3u_att,hrh_3l_att,hrh_4u_att,hrh_4l_att,hrh_up_ol1_m,hrh_up_ol1_a,hrh_up_ol2_m,hrh_up_ol2_a,hrh_up_ol3_m,hrh_up_ol3_a,hrh_up_ol4_m,hrh_up_ol4_a,hrh_down_ol5_m,hrh_down_ol5_a,hrh_down_ol6_m,hrh_down_ol6_a,hrh_down_ol7_m); //delay(hrs_config_delay); // //Configure HRS-V Hifi_HIFI_Config_HRS_V_att_lo($BBID,hrs_polarization_v,hrv_1u_att,hrv_1l_att,hrv_2u_att,hrv_2l_att,hrv_3u_att,hrv_3l_att,hrv_4u_att,hrv_4l_att,hrv_up_ol1_m,hrv_up_ol1_a,hrv_up_ol2_m,hrv_up_ol2_a,hrv_up_ol3_m,hrv_up_ol3_a,hrv_up_ol4_m,hrv_up_ol4_a,hrv_down_ol5_m,hrv_down_ol5_a,hrv_down_ol6_m,hrv_down_ol6_a,hrv_down_ol7_m); delay(hrs_config_delay); // //Now Configure blocks HRS_config_resol_proc_ops(band,hrs_mode); //Check attenuator values //Now checked at end of procedure during instrument mode status check //mois_tmcheck("Check that parameters HRH_1U_ATT, HRH_1L_ATT, HRH_2U_ATT, HRH_2L_ATT, HRH_3U_ATT, HRH_3L_ATT, HRH_4U_ATT and HRH_4L_ATT are set to 15.5"); //mois_tmcheck("Check that parameters HRV_1U_ATT, HRV_1L_ATT, HRV_2U_ATT, HRV_2L_ATT, HRV_3U_ATT, HRV_3L_ATT, HRV_4U_ATT and HRV_4L_ATT are set to 15.5"); //Check LO locks and values //mois_tmcheck("Check that parameters HRH_LOCK_LO1_S, HRH_LOCK_LO2_S, HRH_LOCK_LO3_S, HRH_LOCK_LO4_S, HRH_LOCK_LO5_S, HRH_LOCK_LO6_S, and HRH_LOCK_LO7_S are all Locked"); //mois_tmcheck("Check that parameters HRV_LOCK_LO1_S, HRV_LOCK_LO2_S, HRV_LOCK_LO3_S, HRV_LOCK_LO4_S, HRV_LOCK_LO5_S, HRV_LOCK_LO6_S, and HRV_LOCK_LO7_S are all Locked"); //Check_HRS_LO_proc_ops([hrs_mode_h,hrs_mode_v],hrsH_LO[0],hrsH_LO[1],hrsH_LO[2],hrsH_LO[3], // hrsH_LO[4],hrsH_LO[5],hrsH_LO[6],hrsV_LO[0],hrsV_LO[1],hrsV_LO[2], // hrsV_LO[3],hrsV_LO[4],hrsV_LO[5],hrsV_LO[6]); } /////////////////////////////////////////////// // Generation of messages common to all observing modes // opening for all messages procedure OpenMessages { string modename = "HIFI-Point-PositionSwitch"; // identifier of obsmode {int,int,int,int,int,int,int,int,int,int} seq = {0,0,0,0,0,0,0,0,0,0}; // sequence parameters }{ message(""); message("

Observing mode: " + modename + " executed

"); message("

Sequence parameters

"); message("

"); if(seq{0} != 0) { message("Backend readout period on source: " + seq{0} + "s
"); } if(seq{1} != 0) { message("Backend readout period on OFF: " + seq{1} + "s
"); } if(seq{2} != 0) { message("Number of continuous data dumps per source point: " + seq{2} + "
"); } if(seq{3} != 0) { message("Number of switch cycles on source: " + seq{3} + "
"); } if(seq{4} != 0) { message("Number of cycles on OFF: " + seq{4} + "
"); } if(seq{5} != 0) { message("Number of lines between two OFF measurements: " + seq{5} + "
"); } if(seq{6} != 0) { message("Number of points in one nodding phase: " + seq{6} + "
"); } if(seq{7} != 0) { message("Number of frequencies to combine with one load: " + seq{7} + "
"); } if(seq{8} != 0) { message("Number of pointing cycles: " + seq{8} + "
"); } if(seq{9} != 0) { message("Interval between load measurements: " + seq{9} + "s
"); } message("

"); message("

"); } // Stability test, procedure, double-beam-switch chop // Differential stability between M3left and M3right. block Stability_dbs_fm HIFI 3435 { string band = "1a"; // HIFI band int n = 100; //The number of integration pairs int integ_time = 4; //Total (co-added) integration time of ONE SINGLE phase in sec. string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string chopmode = "slowchop" in ["slowchop","fastchop"]; //Whether to use slowchop or fastchop double chop_phase = 1.0 in [0.2,2.0]; // Chop phase length }{ Start_block(); //Get chopper settings {double,string}[] result = ConfigurationReader("name_confilfpu",["chop_M3left","chop_M3right"],band,0.0); double chop_left = result[0]{0}; double chop_right = result[1]{0}; // //We implement a special slow-chop spectroscopy between //internal cold and external hot if(chopmode == "slowchop") { Slow_chop_spectro_for_Stability_proc_fm(band,n,integ_time * 2,backend,hrs_mode,chop_left,chop_right); } else { Fast_chop_spectro_for_Stability_proc_fm(band,n,integ_time * 2,backend,hrs_mode,chop_left,chop_right,chop_phase); } } //HIFI LO tuning, block //Special testmode to test influence of best guess and slope block LO_tuning_investigation_block_fm HIFI 3674 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency double d2_v_middle = 2.0; //Best-guess for scan middle double scan_width = 10.0; //Total scan span in percentage of the best-guess }{ //Clear potential failure mode Set_LO_Nominal_proc_fm(); // //Start_block(); {double,string}[] result = ConfigurationReader("name_confpolar4lotune",[band],band,lo_freq); string mixer_polarization = result[0]{1}; //Get target mixer current result = ConfigurationReader("name_confilmix",["target_mx_c_h","target_mx_c_v"],band,lo_freq); double target_current = result[0]{0}; if(mixer_polarization == "V") { target_current = result[1]{0}; } if(mixer_polarization == "B") { target_current = 0.5 * (result[1]{0} + result[0]{0}); } // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; name_configlcutune = "name_configlcutune_b"; } // result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // result = ConfigurationReader(name_configlotune,["step_drain2_v","nsteps","step_time"],band,lo_freq); double step_drain2_v = result[0]{0}; int nsteps = iround(result[1]{0}); double step_time = result[2]{0}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // //Adjust scan cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); double drain2_safe = cresult[0]; // double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); // //For all bands, scan will be done with decreasing drain2 voltages //The best guess is taken from look-up table double tune_range = scan_width / 100.0; //0.1; result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lo_freq); double middle_d2 = d2_v_middle; //result[0]{0}; double drain2_v_start = min(middle_d2 * (1.0 + tune_range / 2.0),drain2_bluemax); double drain2_v_end = (1.0 - tune_range / 2.0) / (1.0 + tune_range / 2.0) * drain2_v_start; step_drain2_v = (drain2_v_end - drain2_v_start) / double(nsteps - 1); // result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); // //Send command HIFI_Configure_LCU_proc_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,macro_checksum,config_lo_delay); // //delay(5); //to settle at this value // //Load vector scan //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Load_vector_safe_1a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "1b") { //Band 1b Hifi_HIFI_Load_vector_safe_1b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2a") { //Band 2a Hifi_HIFI_Load_vector_safe_2a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2b") { //Band 2b Hifi_HIFI_Load_vector_safe_2b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3a") { //Band 3a Hifi_HIFI_Load_vector_safe_3a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3b") { //Band 3b Hifi_HIFI_Load_vector_nom_3b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "4a") { //Band 4a Hifi_HIFI_Load_vector_safe_4a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "4b") { //Band 4b Hifi_HIFI_Load_vector_safe_4b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "5a") { //Band 5a Hifi_HIFI_Load_vector_nom_5a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "5b") { //Band 5b Hifi_HIFI_Load_vector_nom_5b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6a") { //Band 6a Hifi_HIFI_Load_vector_nom_6a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6b") { //Band 6b Hifi_HIFI_Load_vector_nom_6b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7a") { //Band 7a Hifi_HIFI_Load_vector_nom_7a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7b") { //Band 7b Hifi_HIFI_Load_vector_nom_7b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } // delay(1); // //Execute tuning: check which mixer is to be used if(mixer_polarization == "V") { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCV($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCV($BBID,target_current); } } else { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCH($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCH($BBID,target_current); } } // double time_needed = double(nsteps) * step_time; delay(iround(time_needed + 2.0 + 0.5)); //0.5s added for completion of load_vector // //Store settings into available register HIFI_HL_store_tm_only_proc_fm(); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } // Initialisation of FPU, block with only V-MSA in use // It is only for warm context ! block Init_MSA_V_fm_warm HIFI 3218 { string band = "1a"; string chop_loop = "CLOSE"; double lo_freq = 522.0; //LO frequency }{ Start_block(); {double,string}[] result_d = ConfigurationReaderWarm("name_confilfpu",["band"],band,lo_freq); int band_nb = iround(result_d[0]{0}); double diplex_H = 0.0; double diplex_V = 0.0; int diplex_h_ctrl_mode = 0; int diplex_v_ctrl_mode = 0; // result_d = ConfigurationReaderWarm("name_confilfpu",["fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],"0",0.0); // double volt_H_FIF_1 = result_d[0]{0}; double curr_H_FIF_1 = result_d[1]{0}; double volt_H_FIF_2 = result_d[2]{0}; double curr_H_FIF_2 = result_d[3]{0}; // double volt_H_SIF_1 = result_d[4]{0}; double curr_H_SIF_1 = result_d[5]{0}; double volt_H_SIF_2 = result_d[6]{0}; double curr_H_SIF_2 = result_d[7]{0}; double volt_H_SIF_3 = result_d[8]{0}; double curr_H_SIF_3 = result_d[9]{0}; // result_d = ConfigurationReaderWarm("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,lo_freq); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // string chop_sine_s = "ON"; // string chop_loop = "CLOSE" ; result_d = ConfigurationReaderWarm("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,lo_freq); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // double calibcurrent = result_d[7]{0}; // //Get biases result_d = ConfigurationReaderWarm("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); double bias_H = result_d[0]{0}; double bias_V = result_d[1]{0}; // //Get magnets: not applicable to bands 6 and 7 double magnetcurrent_H = 0.0; double magnetcurrent_V = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReaderWarm("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); magnetcurrent_H = result_d[0]{0}; magnetcurrent_V = result_d[1]{0}; } //Diplexer is interpolated from a table for Bands 3, 4, 6L and 6H if(band_nb <= 2 || band_nb == 5) { diplex_H = 0.0; //For bands 1, 2 and 5 diplex_V = 0.0; diplex_h_ctrl_mode = 0; diplex_v_ctrl_mode = 0; } else { //Get diplexer currents result_d = ConfigurationReaderWarm("name_confilfpu",["diplex_h_ctrl_mode","diplex_v_ctrl_mode","diplexer_current_normal_h","diplexer_current_normal_v"],band,lo_freq); diplex_h_ctrl_mode = iround(result_d[0]{0}); diplex_v_ctrl_mode = iround(result_d[1]{0}); //double[] result_dip = Get_Diplexer_setting(band,lo_freq); diplex_H = result_d[2]{0}; //result_dip[0]; diplex_V = result_d[3]{0}; //result_dip[1]; } // result_d = ConfigurationReader("name_chopper",["chop_startup_warm"],band,0.0); double chopper = result_d[0]{0}; //For this configuration we won't convert prime chopper voltage into redundant voltage //Just checking we are in range. //chopper = Check_Chopper_Prime_Redundant(chopper); chopper = Check_Chopper_Range(chopper); // //Switch on upconverter, assuming chopper and mixers are also ON Hifi_HIFI_Configure_FCU_Power($BBID,"ON","ON","ON","ON","ON"); // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result_d = ConfigurationReaderWarm("name_delays",["config_fpu_delay"],band,lo_freq); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // Hifi_HIFI_non_periodic_hk_FCU(); } ///////////////////////////////////////////////////////////////// // Auxiliary routine to determine the two loop phase durations and // the OFF resolution for all FSwitch modes {double,double,double,double} procedure FSwitchPhaseLengths { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF }{ // limits from noise section // resolution of OFF phase double sw_resolution = GetFSwitchSWResolution(band,lo_freq); sw_resolution = max(effResolution{1},sw_resolution); // Get the drift parameters to compute the drift noise // System Allan variance double[] allanparms = InterpolateSpecAllan(band,lo_freq,oneGHzReference); // rescale to frequency resolution double alpha = allanparms[1]; double binningexp = 1.0 / allanparms[2]; double allan_time_lores = allanparms[0] * pow(1.0 / effResolution{1},binningexp); double allan_time_off = allanparms[0] * pow(1.0 / sw_resolution,binningexp); // Differential Allan variance allanparms = InterpolateSpecFSwitchAllan(band,lo_freq,oneGHzReference); // rescale to frequency resolution double dalpha = allanparms[1]; binningexp = 1.0 / allanparms[2]; double dallan_time_lores = allanparms[0] * pow(1.0 / effResolution{1},binningexp); // phase lengths double main_phase = 0.3 * dallan_time_lores; double chop_phase = 0.3 * allan_time_lores; double chop_phase_off = 0.3 * allan_time_off; // Constrain by load period int loadper = LoadPeriod(band,lo_freq,effResolution{0}); main_phase = min(main_phase,0.4 * double(loadper)); return {main_phase,chop_phase,chop_phase_off,sw_resolution}; } // Detector heater control: COP version does not switch magnet back to normal at end block Heater_cop HIFI 3940 { string band = "1a"; }{ //Get name of FPU configuration file {double,string}[] result_d = ConfigurationReader("name_confilfpu",["normal_heater_time_h","normal_heater_time_v","heater_delay_h","heater_delay_v","magnet_current_max_h","magnet_current_max_v"],band,0.0); double normal_heater_time_h = result_d[0]{0}; double normal_heater_time_v = result_d[1]{0}; int heater_delay_h = iround(result_d[2]{0}); int heater_delay_v = iround(result_d[3]{0}); //Magnets need to be switched to 0 prior to the deflux Hifi_HIFI_CH1_MX_MG_C($BBID,0.0); Hifi_HIFI_CV1_MX_MG_C($BBID,0.0); delay(1); // Hifi_HIFI_HF_CH1_DHTR_C($BBID,normal_heater_time_h); delay(iceil(normal_heater_time_h / 1000.0) + 1); // int startobs = time(); //Extra delay for cooling down temperature: will be included in the V-mixer delay //delay(heater_delay_h); Hifi_HIFI_HF_CV1_DHTR_C($BBID,normal_heater_time_v); delay(iceil(normal_heater_time_v / 1000.0) + 1); //Extra delay for cooling down temperature: both mixers cool down together delay(heater_delay_v); // } //Set data rate - used after boot command block HKrate_block_ops HIFI 7924 { double rate = 0.2; }{ StartBlock_ops(); string hk_rate = "1_pkt_per_10_s"; if(rate < 0.2) { hk_rate = "1_pkt_per_10_s"; } if(rate >= 0.2 && rate < 0.25) { hk_rate = "1_pkt_per_5_s"; } if(rate >= 0.25 && rate < 0.33) { hk_rate = "1_pkt_per_4_s"; } if(rate >= 0.33 && rate < 1.0) { hk_rate = "1_pkt_per_3_s"; } if(rate >= 1.0) { hk_rate = "1_pkt_per_s"; } Hifi_HIFI_Housekeeping_on(hk_rate,"ON","ON","ON","ON","ON","ON"); mois_tmcheck("Verify that HIFI telemetry packets (3,25,1025) - HIFI_PERIODIC_HK - are arriving at a " + hk_rate + " rate."); delay(1); } //Procedure checking the consistency of slow chop spectroscopy //parameters to be sent to configuration command. bool procedure Check_fast_chop_parameters_proc { int n_wbs_start = 1; //Nb of loops int r_hrs = 1; //Nb of HRS readout per WBS readout int n_wbs_integr = 4; //Number of wbs readout packetized per WBS frame int n_hrs_integr = 4; //Number of hrs readout packetized per HRS frame int del_hrs = 5; //Delay before starting HRS integration int del_wbs = 5; //Delay before starting WBS integration int t_acc_wbs = 1005; //Duration of WBS frame: it sets the chopping rate int t_acc_hrs = 950; //Duration of HRS frame int wbsh_offset1 = 0; int wbsh_width1 = 2048; int wbsh_offset2 = 2048; int wbsh_width2 = 2048; int wbsh_offset3 = 4096; int wbsh_width3 = 2048; int wbsh_offset4 = 6144; int wbsh_width4 = 2048; int wbsv_offset1 = 0; int wbsv_width1 = 2048; int wbsv_offset2 = 2048; int wbsv_width2 = 2048; int wbsv_offset3 = 4096; int wbsv_width3 = 2048; int wbsv_offset4 = 6144; int wbsv_width4 = 2048; int hrs_rshift = 0; //HRS bit shift int wbs_rshift = 0; //WBS bit shift int hrsh_sel = 255; //HRS-H band selection int hrsv_sel = 255; //HRS-V band selection string wbs_packing = "24_bits_format"; int n_wbs_1 = 8; //n_wbs_1: number of WBS cycles (should be even) int n_hrs_trans = 1; //n_hrs_trans: HRS loop when transferring WBS packets string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4,wb5 string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ error("Procedure Check_fast_chop_parameters_proc is not used anymore."); return false; } //HIFI-COP-1.2-WBS_FT obs HifiEng_WBS_FT_COP { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(WBS_FT_COP_proc_ops(prime_or_redundant)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution WBS_FT_COP_proc_ops(prime_or_redundant); } if(state[0] == 5) { HIFISetHK("normal",true); StopMode_block_ops(); } } } {string,double,double}[] procedure HifiSScanModeDBSSequencerInit { string modeName = "freq"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_switch_on = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per frequency and pointing int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int n_cycles = 1 in [1,600]; // Number of half OFF-ON-ON-OFF cycles at one frequency int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,redundancy,wbs1Used,wbs2Used,data_time); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hr1{0},hr1{1},hr1{3}},{hr2{0},hr2{1},hr2{3}},wb1,wb2}; // Get frequency grid characteristic parameters {double,int,double} gfref = GetFReference(band,lo_freq,lo_freq_up); double reffreq = gfref{0}; int stdredun = gfref{1}; double stdstep = gfref{2}; int increment = stdredun / redundancy; // allowed group size double nocaliblen = GetFNoCalibLength(band,reffreq); int n_freq_point_guess = ifloor(nocaliblen / (stdstep * double(increment)) + 1.0); int n_freq_point_range = 1 - n_freq_point_guess; if(n_freq_point_range == 0) { n_freq_point_range = 1; } // Now general part of DBS modes {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // Get the drift parameters to compute the drift noise // spectral scans always use the full bandwidth for reference bool narrowReference = false; {double,double} phaselengths = DBSPhaseLengths(band,reffreq,effResolution,continuumDetection,narrowReference); // Compute derived quantities int data_time_guess = imin(imax(iceil(phaselengths{1}),datalimit),20); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } // remaining part for n_switch int n_switch_on_guess = iceil(phaselengths{0}) / (n_freq_point_guess * 2 * data_time_guess) + 1; int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)},{"n_freq_point",double(n_freq_point_guess),double(n_freq_point_range)}]; return retvalues; } ///////////////////////////////////////////////////////////////// // Procedure to compute detailed timing for a // Spectral Scan DBS engineering mode // {{int,int,int,int,int,int,int,int,int,bool,int,int,int},{int,double[]}} procedure EngSScanDBS_pre_timing { string band = "4a"; // HIFI band double reffreq = 978200.0; // Reference LO frequency in MHz string freqgridfile = "config_StWv_scan_onsky"; // file of frequency grid string scan_name = "CO(7-6)"; // name of the relevant column in the grid file bool retunediplexer = false; // whether to change the diplexer with freq bool retunelo = false; // whether to retune LO Vd2 with freq {double,double} eff_resolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_chop = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per frequency and pointing int n_cycles = 1 in [1,600]; // Number of half OFF-ON-ON-OFF cycles at one frequency }{ ////////////////////////////////////////////////////////////////////// // Create composite readout structure for backends {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Get frequency grid characteristic parameters double[] freqgrid = dcolumn(freqgridfile,scan_name); int nfreq = length(freqgrid); ////////////////////////////////////////////////////////////////////// // Get timing within the normal DBS observations // Compute load integration time int loadlength = duration(SScanLoadMeasurement(band,reffreq,reffreq,true,eff_resolution{0},data_time,backendreadoutparms)); int readoutdead = SlowChopReadoutDelay(band,reffreq,backendreadoutparms); loadlength = loadlength + readoutdead; // Integration time per frequency and pointing int inttime = 2 * n_chop * data_time; int readouttime = data_time; // Tuning delays int bigtunestep = duration(HIFIChangeLO(band,reffreq,reffreq,retunediplexer,retunelo)); // Correct for variation within the band double lo_freq_low = freqgrid[0]; double lo_freq_up = freqgrid[nfreq - 1]; int tunediff = ComputeLOTimeDifference(band,lo_freq_low,lo_freq_up,reffreq); bigtunestep = bigtunestep + tunediff; // For double phases I can use the added jitterdead in both phases for tune int jitterdead = GetMaxTimeJitter(band,reffreq); int halftunestep = (bigtunestep - jitterdead + 1) / 2; // Duration of initial set up int initlength = duration(HIFIInitObs()); initlength = initlength + duration(TuneHIFI(band,reffreq,hrs1,hrs2,wbs1{0},wbs2{0},"sscan_normal")); // Add time for HK readout int hkduration = HkReadoutTime(band,reffreq,backendreadoutparms,false); initlength = initlength + hkduration + bigtunestep + loadlength; // recompute load length during slews loadlength = duration(SScanLoadMeasurement(band,reffreq,reffreq,false,eff_resolution{0},data_time,backendreadoutparms)); loadlength = loadlength + readoutdead; // Telescope command parameters int pointing = inttime + halftunestep + jitterdead; int n_loadinterval = n_cycles; // Dummy parameters for the engineering mode to use the same // telescope API as for the standard modes int n_bchop = n_chop; int load_spacing = 8; int dangling = 0; bool end_load = false; // Return all the times needed for telescope call and post_timing processing return {{inttime,pointing,readouttime,loadlength,jitterdead,load_spacing,bigtunestep,n_loadinterval,n_bchop,end_load,halftunestep,initlength,dangling},{nfreq,freqgrid}}; } // Spectrometer configuration for total power, procedure // Uses the efficient AOT assumptions, but also their scos_jitter int[] procedure Configure_Spectrometer_AOTlike_proc_fm { string band = "1a"; // HIFI band int integ_time = 4; //Total integration time in sec. string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4,wb5,wb6,wb7,wb8 string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //First derive backend setting codes as expected by VO's routine //Build up backend parameter tupple: {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = BackendSettings(band,0.0,hrs_mode,backend); // Readout parameters for HRS1,HRS2, WBS1,WBS2 //Compute data_time and n_switch use the wrapper int[] res = ConfigSlowChop(integ_time,"tp",band,0.0,backendreadoutparms); int data_time = res[0]; int n_switch = res[1]; // Now call the spectroscopy setup: it is common to ILT and AOT CUS. // The deadtimes output is not used at ILT level. {double,double} dtimes = ConfigSpectroscopySlowChop(data_time,n_switch,"tp",band,0.0,backendreadoutparms,true); // //Necessary for call in Dip_FSW_COP_proc_ops Hifi_HIFI_noop(); return res; } // LCU configuration into NOMINAL mode, procedure procedure LCU_config_nominal_proc_aot { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978.2; //LO frequency }{ //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlcutune = "name_configlcutune_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1_v = result[0]{1}; string curlim2_v = result[1]{1}; // result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); //Fetch best guess, and clip to blue max double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lo_freq); drain2_v = min(result[0]{0},drain2_bluemax); //Send command: expect that we have already switched to NOMINAL //We set D2 to best guess and wait some time to stabilize chain temperature HIFI_Configure_LCU_block_aot(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum,config_lo_delay); // //TM page dump and error flag clearance now contained in the above block } ///////////////////////////////////////////////////////////////// // Fast-chop spectral scan observing modes // // Combination of four modules implementing the new structure // // Implemented as procedure returning time and noise levels for HSPOT {int,double,double,double,double,double} obs HifiSScanProcFastDBS { /* Setup parameters */ int naifid = 0; // Tracing object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz int redundancy = 4 in [1,12]; // Frequency scan redundancy {double,double} effResolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool wbs1Used = true; // whether WBS1 is used bool wbs2Used = true; // whether WBS2 is used /* Sequence parameters */ int data_time = 10 in [4,80]; // data dump interval int n_int_on = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_switch_on = 1 in [1,1800]; // number of data transfer cycles per pointing int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int n_cycles = 1 in [1,600]; // Number of half OFF-ON-ON-OFF cycles at one frequency int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Spectral Scan - DBS fastChop",{data_time,0,n_switch_on,n_int_on,0,0,0,n_freq_point,n_cycles,load_interval}); // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,redundancy,wbs1Used,wbs2Used,data_time / 2); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; ////////////////////////////////////////////////////////////////////// // Call first part of the timing computer {{int,int,int,int,int,int,int,int,int,bool,int,int,int},{int,double,double[],int[][],bool,double[],int,bool}} pre_timing = FastSScanDBS_pre_timing(band,lo_freq,lo_freq_up,redundancy,effResolution,hr1,hr2,wb1,wb2,data_time,n_int_on,n_switch_on,n_freq_point,n_cycles,load_interval,docommands); // frequency parameters int groupnumber = pre_timing{1}{0}; double reffreq = pre_timing{1}{1}; double[] freqgrid = pre_timing{1}{2}; int[][] grouporder = pre_timing{1}{3}; bool retuning = pre_timing{1}{4}; double[] targetlevels = pre_timing{1}{5}; int nfreq_if = pre_timing{1}{6}; bool dsb = pre_timing{1}{7}; int n_total = groupnumber * n_cycles; ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,int,int,int,int,int,int} tpar = DBS_telescope(naifid,onPosition,band,reffreq,"",pre_timing{0},n_total); // Dummy call to spacecraft command int[] telescopetimes = nodding_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},false); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,bool,int,int,int},double,double,double} post_timing = SScanDBS_post_timing(pre_timing{0},telescopetimes,n_freq_point,groupnumber,n_cycles,true); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = DBS_telescope(naifid,onPosition,band,reffreq,"",post_timing{1},n_total); // Call telescope command telescopetimes = nodding_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},false); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following // normal pre_timing values int n_loadinterval = post_timing{1}{7}; int n_bchop = post_timing{1}{8}; int shiftlength = post_timing{1}{10}; int initlength = post_timing{1}{11}; double avnumchop = post_timing{2}; // efficiency parameters double tscan = post_timing{3}; double tdead = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { FastSScanDBS_commanding(band,reffreq,effResolution,hr1,hr2,wb1,wb2,n_freq_point,grouporder,freqgrid,retuning,targetlevels,data_time,n_int_on,n_cycles,n_total,n_bchop,n_switch_on,n_loadinterval,startobs,telescopetimes,shiftlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double} tact = FastSScanDBS_deadtimes(band,reffreq,hr1,hr2,wb1,wb2,n_freq_point,data_time,n_int_on,n_bchop,n_switch_on,n_cycles,avnumchop,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = SScanDBS_noisecomputer(band,reffreq,nfreq_if,dsb,effResolution,continuumDetection,n_cycles,tscan,tact); // Evaluate performance SScanDBS_performance(band,reffreq,nfreq_if,dsb,effResolution,noisevalues,timeTaken,n_total,groupnumber * n_freq_point,avnumchop * double(n_int_on),tscan,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // HRS attenuator tuning, block // Both polarizations are treated block HRS_tune_block_fm HIFI 3601 { string band = "1a"; // HIFI band }{ //Start_block(); //Now tune attenuators: it sets the HRS to ultra_wide Hifi_HIFI_Tune_HRS($BBID); //Get delay {double,string}[] result_d = ConfigurationReader("name_delays",["hrs_tune_delay"],band,0.0); int hrs_tune_delay = iround(result_d[0]{0}); delay(hrs_tune_delay); // } // Stability test, procedure, case 4 // Measurement of internal cold against external hot procedure Proc_stability_intcold_exthot { string band = "1a"; // HIFI band int n = 100; //Number of load pairs to be measured string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int integ_time = 4; //Total (co-added) integration time of a phase in sec. string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string chopmode = "slowchop" in ["slowchop","fastchop"]; //Whether to use slowchop or fastchop double chop_phase = 1.0 in [0.2,2.0]; // Chop phase length }{ // Chopper_Rotation_block_fm(band,"chop_hot_ang","chop_M3_ang"); //Look at external HBB //Open shutter //Shutter_rotate_proc_fm("open"); // //WBS calibration if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band); WBS_tune_proc_fm(band); } if(backend == "hrs" || backend == "both" || backend == "hrsFast") { //Configure and tune backends HRS_config_block_fm(band,hrs_mode); HRS_tune_block_fm(band); } // //Configure spectrometers integration after tuning: done later //Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); // Stability_intcold_exthot_fm(band,n,integ_time,hrs_mode,backend,chopmode,chop_phase); //Configure spectrometers integration back to default in tp mode Configure_Spectrometer_proc_fm(band,4,hrs_mode,backend); //2 sec. integration } ////////////////////////////////////////////////////////////////////////// // Procedure to compute detailed timing of OTF observing mode {int,int,int,int,int,int,int,int} procedure OTFmap_pre_timing { int nlines_tot = 1; // Number of rows in the map int npoints = 10; // Number of data dumps per row string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4 in [1,5]; // chunk size given by the data rates and optimum speed int n_supersample = 1 in [1,1800]; // Supersamplingfactor int n_linesperscan = 1 in [1,32]; // Number of lines between two OFFs int n_intoff = 3 in [1,3600]; // Number of data dumps for the OFF integration time int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // First check validity of frequencies CheckLOFrequencies(band,lo_freq,lo_freq); // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // First perform consistency checks // Check chunk size given by the data rates CheckDataTaking(backendreadoutparms,data_time); // Is the map size an integer multiple of the scan size? if(nlines_tot == 1) { int n_scans = 1; } else { if(nlines_tot % n_linesperscan != 0) { SError("Map size is no integer multiple of the scan size."); } n_scans = nlines_tot / n_linesperscan; } // Compute parameters for the instrument timing CheckReasonableLineNumber(nlines_tot,true); int n_pp = npoints * n_supersample; // compute load integration time int loadlength = duration(LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms)); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); loadlength = loadlength + readoutdead; // Compute parameters for the pointing command int jitterdead = GetMaxTimeJitter(band,lo_freq); int off_inttime = n_intoff * data_time; // OFF integration time int off_pointing = off_inttime + jitterdead; // increase by commanding jitter // Duration of initial set up // determine exact duration only in case of full commanding if(docommands) { int initlength = duration(HIFIInitObs()); initlength = initlength + duration(TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal")); // Add time for HK readout int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); initlength = initlength + hkduration; } else { initlength = GetRoughInitLength(band,lo_freq,false); } initlength = initlength + loadlength; // First estimate of the load interval int scan_time = n_linesperscan * n_pp * data_time + off_pointing; if(scan_time > load_interval) { IError("Scan duration too long for required load period. " + "Reduce the map size or increase the step size."); } int n_loadinterval = imax(load_interval / scan_time,1); n_loadinterval = imin(n_loadinterval,32); // Make sure that load slews occur at the same position in each coverage n_loadinterval = IMultiple(n_loadinterval,n_scans); // dangling time given by readout dead time int dangling = readoutdead; // Return all the times needed in the observing mode modules return {n_pp,n_scans,off_inttime,off_pointing,loadlength,n_loadinterval,initlength,dangling}; } //PDU switch on of a S/S, procedure procedure PDU_switch_on_proc_ops { string subsystem = "ICU_Prime" in ["ICU_Prime","ICU_Red","LO_Prime","LO_Red","WBS_H","WBS_V","HRS_H","HRS_V"]; }{ ////HifiIltEgse_PDU_switch_on($BBID,subsystem); //The TEI command: WILL BE DONE BY SPACON mois_spacon("Please power ON Sub-System " + subsystem); if(subsystem == "ICU_Prime" || subsystem == "ICU_Red") { mois_tmcheck("Verify PDU current for HIFI ICU is 1.0A +/- 10%"); mois_tmcheck("Verify arrival of (5,1) telemetry packet from HIFI after 10sec. (5,1) packets should then arrive every 10sec."); if(subsystem == "ICU_Prime") { mois_tmcheck("If the (5,1) telemetry packet is not received, HIFI is in RESCUE mode and the following procedures shall be executed: HIFI_Rescue_to_SwitchedOff_Prime, then HIFI_SwitchedOff_to_Intermediate_Redundant if this has not yet been attempted. Please contact the HIFI ICC in any case."); mois_tmcheck("If a (5,4) telemetry packet has been received, HIFI is in RESCUE mode and the following procedure shall be executed: HIFI_Rescue_to_SwitchedOff_Prime. Please contact the HIFI ICC."); } if(subsystem == "ICU_Redundant") { mois_tmcheck("If the (5,1) telemetry packet is not received, HIFI is in RESCUE mode and the following procedure shall be executed: HIFI_Rescue_to_SwitchedOff_Redundant, then HIFI_SwitchedOff_to_Intermediate_Prime if this has not yet been attempted. Please contact the HIFI ICC in any case."); mois_tmcheck("If a (5,4) telemetry packet has been received, HIFI is in RESCUE mode and the following procedure shall be executed: HIFI_Rescue_to_SwitchedOff_Redundant. Please contact the HIFI ICC."); } } //Check current for other S/S if(subsystem == "LO_Prime" || subsystem == "LO_Red") { mois_tmcheck("Verify PDU current for HIFI LCU is 0.9A +/- 0.25A"); } if(subsystem == "WBS_H") { mois_tmcheck("Verify PDU current for HIFI WBS-H is 0.92A +/- 10%"); } if(subsystem == "WBS_V") { mois_tmcheck("Verify PDU current for HIFI WBS-V is 0.92A +/- 10%"); } if(subsystem == "HRS_H") { mois_tmcheck("Verify PDU current for HIFI HRS-H is 2.32A +/- 10%"); } if(subsystem == "HRS_V") { mois_tmcheck("Verify PDU current for HIFI HRS-V is 2.32A +/- 10%"); } //delay(1); } //General LO configuration command procedure HIFI_Configure_LCU_proc_fm { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency int freq_nx = 0; // HL_freq_nx int lsu_main = 0; // HL_LSU_main int lsu_offset = 0; // HL_LSU_offset int d2_step = 1; // HL_D2_step double plevel_v = 0.0; double m1_v = 9.0; double m2_v = -2.0; double m3_v = 0.0; double gate1_v = -2.5; double gate2_v = -2.5; double drain1_v = 2.8; string curlim1_v = "1.4"; double drain2_v = 2.6; string curlim2_v = "1.4"; int macro_checksum = 0; // HL_macro_checksum int config_lo_delay = 6; }{ //Check that Vd2 is within the blue limits drain2_v = Check_BLUE_LIMIT_D2_proc_fm(band,lo_freq,drain2_v); // // //Execute configuration //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Conf_safe_LCU_ch1a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "1b") { //Band 1b Hifi_HIFI_Conf_safe_LCU_ch1b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "2a") { //Band 2a Hifi_HIFI_Conf_safe_LCU_ch2a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "2b") { //Band 2b Hifi_HIFI_Conf_safe_LCU_ch2b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "3a") { //Band 3a Hifi_HIFI_Conf_safe_LCU_ch3a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "3b") { //Band 3b Hifi_HIFI_Conf_nom_LCU_ch3b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "4a") { //Band 4a Hifi_HIFI_Conf_safe_LCU_ch4a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "4b") { //Band 4b Hifi_HIFI_Conf_safe_LCU_ch4b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "5a") { //Band 5a Hifi_HIFI_Conf_nom_LCU_ch5a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "5b") { //Band 5b Hifi_HIFI_Conf_nom_LCU_ch5b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "6a") { //Band 6a Hifi_HIFI_Conf_nom_LCU_ch6a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "6b") { //Band 6b Hifi_HIFI_Conf_nom_LCU_ch6b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "7a") { //Band 7a Hifi_HIFI_Conf_nom_LCU_ch7a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "7b") { //Band 7b Hifi_HIFI_Conf_nom_LCU_ch7b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } // delay(config_lo_delay); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } //Set LCU4a back to standby status, procedure procedure LCU4a_standby_proc_fm { string band = "4a"; // HIFI band double lo_freq = 1000.0 in [967.0,1042.0]; //LO frequency }{ error("This module is obsolete: use LCU_standby_proc_fm instead"); } // Standing wave analysis // Retune case for band 2a //HIFI-COP-3-StWv1 procedure Standing_wave_retune_COP_proc_ops { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string backend = "both"; string[] hrs_mode = ["wb1","wb1"]; int freq_index = 1; //The frequency index to consider: 1 to 4 string los_code = "sc" in ["sc","sh","ss"]; //The line-of-sight code: sc (sky-CBB), sh (sky-HBB), ss (sky-sky) }{ //Retrieve frequencies from LUT string tabstwv = "config_stwvfreq.config"; double bandnb = GetBandCode(band); // //Check consistency of request if(freq_index > 1 && (los_code == "sh" || los_code == "ss")) { error("You cannot select this line-of-sight with this frequency index"); } if(iround(bandnb) % 2 == 0 && (los_code == "sh" || los_code == "ss")) { error("You cannot select this line-of-sight with b-bands"); } //Fetch observing parameters double lo_freq = dlookup(tabstwv,"" + iceil(bandnb),"freq" + freq_index); int integ_time = ilookup(tabstwv,"" + iceil(bandnb),"t" + freq_index); int total_stepnb = ilookup(tabstwv,"" + iceil(bandnb),"n" + freq_index + "_" + los_code); // if(lo_freq == 0.0) { error("There is no frequency associated with this band and this frequency index"); } // HRS_config_block_fm(band,hrs_mode); // int[] res = [0,0]; if(los_code == "sh") { res = Configure_Spectrometer_hc_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); } else { res = Configure_Spectrometer_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); } int total_time = res[0] * res[1]; // double step = 0.015; //GHz double stepnb = double(total_stepnb / 2); double[] lo_freq_input = [0.0,0.0,0.0]; //Build lo_freq_input array lo_freq_input = [lo_freq - stepnb * step,lo_freq + stepnb * step,step]; int nb_retune = 1; Standing_wave_retune_fm_COP(band,total_time,hrs_mode,backend,lo_freq_input,los_code,nb_retune); // } // Spectrometer configuration for frequency switch, low level procedure int[] procedure Configure_Spectrometer_freq_switching_proc_fm { string band = "1a"; // HIFI band int integ_time = 8; //Total integration time in sec. for the two phases ! string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4,wb5 string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //First derive backend setting codes as expected by VO's routine //Build up backend parameter tupple: {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = BackendSettings(band,0.0,hrs_mode,backend); // Readout parameters for HRS1,HRS2, WBS1,WBS2 //Compute data_time and n_switch use the wrapper int[] res = ConfigSlowChop(integ_time,"fs",band,0.0,backendreadoutparms); int data_time = res[0]; int n_switch = res[1]; // Now call the spectroscopy setup: it is common to ILT and AOT CUS. // The deadtimes output is not used at ILT level. {double,double} dtimes = ConfigSpectroscopySlowChop_IST(data_time,n_switch,"fs",band,0.0,backendreadoutparms,true); // return res; } // Procedure to get the instrument boresight string for the used band string procedure GetBoresight { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency bool chopped = false; // left chopper or center chopper position }{ // Get major number double[] x = CalibrationReader("beam",["beamnumber"],band,lo_freq); int major = iround(x[0]); // Polarization is not used any more - only synthesized beam int bestWbs = 0; // Construct minor number // Frequency: this is coded in the next digit of the beamnumber if(iround(x[0] * 10.0 % 10.0) > 0) { int freqbeam = 1; } else { freqbeam = 0; } // chop angle if(chopped) { int chopbeam = 1; } else { chopbeam = 0; } int minor = bestWbs + 2 * freqbeam + 4 * chopbeam + 1; // Construct finally the boresight string string boresight = "H" + major + minor + "_0"; return boresight; } // Procedure to compute all parameters needed in a Configure_spectroscopy {int,int,int,int,int,int,int,int,int,int,int,int,int} procedure FastConfigureSpectroscopyParams_IST { /* Integration time */ int data_time = 10 in [4,128]; // data dump interval int n_int = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_data = 2; // Integration time counter /* Parameters determining the delays - used in calibration reader */ string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency /* Backend settings */ bool wbs_used = true; // whether at least one WBS is used }{ // Get fixed parameters from configuration and calibration files // WBS delta time given by switch dead time double res = GetSkyChopDeadTime(band,lo_freq); int del_wbs = iceil(res * 1000.0); // Additional delays in the readout loops - given in OBS user manual {double,string}[] result = ConfigurationReader("name_delays",["add_hrs","add_wbs","add_jitter","wbs_readout","wbs_chunksize","tacc_add","max_hrs_phase","wbs_init"],band,lo_freq); int add_hrs = iround(result[0]{0}); int add_wbs = iround(result[1]{0}); int add_jitter = iround(result[2]{0}); int wbs_readout = iround(result[3]{0}); int wbs_chunksize = iround(result[4]{0}); int tacc_add = iround(result[5]{0}); int max_hrs_phase = iround(result[6]{0}); int wbs_init = iround(result[7]{0}); // In fast chop del_hrs can be zero, but see SCR 854 int del_hrs = add_jitter; // WBS // Fixed parameter - we never split a transfer int n_wbs_integr = 1; int n_wbs1 = 2 * n_int; int n_wbs_start = n_data; // HRS is integrated up as long as the WBS int n_hrs_integr = n_int; // Split data_time into chop phases // Dead time per read out (not clear whether add_wbs applies here) int tdead_data = 2 * (wbs_readout + add_jitter) + add_wbs - add_jitter; // Initial dead time - distribute over all readouts int tdead_init = (wbs_init + n_data - 1) / n_data; int chop_phase = (1000 * data_time - tdead_data - tdead_init) / (2 * n_int); // dead time has to be an integer multiple of the 10ms chunk time int tdead_chop = del_wbs + add_jitter; int nchunk = (tdead_chop - 1) / wbs_chunksize + 1; int tcorr = nchunk * wbs_chunksize - tdead_chop; del_wbs = del_wbs + tcorr; tdead_chop = tdead_chop + tcorr; // Accumulation time int t_acc_wbs = chop_phase - tdead_chop; // discretize in 10ms chunks nchunk = (t_acc_wbs - tacc_add) / wbs_chunksize; t_acc_wbs = nchunk * wbs_chunksize + tacc_add; // HRS // Fixed parameter here int r_hrs = 1; int t_acc_hrs = t_acc_wbs - add_jitter - del_hrs - add_hrs; if(t_acc_hrs > max_hrs_phase) { SError("Chop phase length too long for HRS. Increase chop frequency."); } // How many HRS integrations possible during WBS readout int t_hrs_per = t_acc_hrs + del_wbs + add_hrs; int n_hrs_trans = wbs_readout / t_hrs_per; // This currently does not work - SCR 854: skipped n_hrs_trans = 0; // Actual integration time and dead time per readout // If WBS is used count only the WBS time if(wbs_used) { tdead_chop = tdead_chop + tacc_add; int tint_act = nchunk * wbs_chunksize * n_wbs1 * n_data; } else { tdead_chop = tdead_chop + r_hrs * add_hrs; tdead_data = tdead_data + add_jitter - 2 * (n_hrs_trans * t_hrs_per - add_jitter); tint_act = t_acc_hrs * r_hrs * (n_wbs1 + 2 * n_hrs_trans) * n_data; } // Return all config_spectroscopy timing parameters return {n_wbs_start,r_hrs,n_wbs_integr,n_hrs_integr,del_hrs,del_wbs,t_acc_wbs,t_acc_hrs,n_wbs1,n_hrs_trans,tdead_chop,tdead_data,tint_act}; } //TM to control heater values of LOU, procedure procedure HL_heater_proc_ops { string band = "1a" in ["ALL","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band. ALL does all bands and all multipliers string context = "nominal" in ["nominal","stby"]; //whether heater applies to stby or nominal context }{ mois_step("Switch on LO heater for standby"); double[] cresult = CalibrationReader("name_loheater",["heater_nominal","heater_stby"],band,0.0); double hifi_HL_heater = cresult[0]; if(context == "stby") { hifi_HL_heater = cresult[1]; } Hifi_HIFI_HL_heater($BBID,hifi_HL_heater); delay(1); mois_spacon("Check that parameter HL_Eheater is set to " + hifi_HL_heater); } // LO SFT, following procedure of MPI, procedure // Uses SFT approach with old 5 TM TC call procedure LO_SFT_proc_sft { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ // double lo_freq = 0.0; double drain2_v = 0.0; double[] cresult_d = CalibrationReader("name_keyfreq",["keyfreq","key_d2v_P","key_d2v_R"],band,0.0); lo_freq = cresult_d[0]; //applies to cold LO //Switch on with safe Vd2 LCU_switchon_proc_sft(band); //LO freq and Vd2 to use is embedded in the proc //Wait total of 20 sec. delay(20); //Check what d2_v to use depending on test circumstances drain2_v = cresult_d[1]; //Value for prime case, and fm H/W // if(prime_or_redundant == "Red") { drain2_v = cresult_d[2]; } // LCU_config_nominal_w_D2_proc_sft(band,lo_freq,drain2_v); } ///////////////////////////////////////////////////////////////// // Procedure to compute total dead times for the mode // {double,double,double} procedure FastSScanDBS_deadtimes { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int grouplen = 1; // Number of frequency steps per nodding phase int data_time = 4; // chunk size int n_int = 20; // Number of integrations in one readout cycle int n_bchop = 1; // Normal number of chop cycles per frequency and pointing int n_long = 1; // Chop cycles per frequency and pointing without retuning int n_cycles = 1; // Number of half OFF-ON-ON-OFF cycles at one frequency double avnumchop = 1.0; // Average number of chop cycles per frequency double tdead = 10.0; // Dead time from telescope }{ ////////////////////////////////////////////////////////////////////// // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Compute parameters for the instrument timing in normal phases {double,double} tinst = GetInstDeadFastChop(data_time,n_int,n_long,band,lo_freq,backendreadoutparms); // dead time double tdeadint = double(data_time * n_long) - tinst{0}; // subtract dead times in switches // only half of them are subtracted due to ABAB scheme tdeadint = tdeadint - double(n_int * n_long) * tinst{1}; // treat integration times of other frequencies as dead time double tdeadother = double(data_time * 2 * n_long); // Store double tswitch = tinst{1}; // Integration time double tphaseint = tinst{0}; // Correcton in case of cycles with shorter integrations if(n_cycles > 1) { tinst = GetInstDeadFastChop(data_time,n_int,n_bchop,band,lo_freq,backendreadoutparms); // dead time double tdeadshort = double(data_time * n_bchop) - tinst{0}; // subtract dead times in switches tdeadshort = tdeadshort - double(n_int * n_bchop) * tinst{1}; // weigh tdeadint = (tdeadint * double(n_cycles - 1) + tdeadshort) / double(n_cycles); tphaseint = (tphaseint * double(n_cycles - 1) + tinst{0}) / (2.0 * avnumchop * double(n_cycles) * double(n_int)); tdeadother = (tdeadother * double(n_cycles - 1) + double(data_time * 2 * n_bchop)) / double(n_cycles); } else { tphaseint = tphaseint / (2.0 * avnumchop * double(n_int)); } // Total dead time per cycle double tdead_tot = tdead + 2.0 * tdeadint; // Add integration times of other frequencies as dead time tdead_tot = tdead_tot + double(grouplen - 1) * tdeadother; return {tdead_tot,tphaseint,tswitch}; } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the observing mode procedure SScanLoadChop_commanding { string band = "4a"; // HIFI band double reffreq = 978300.0; // Reference characteristic LO frequency {double,double} eff_resolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int grouplen = 1; // Number of frequency steps per nodding phase int[][] grouporder = [[0],[0]]; // Sequence to trace frequency points in both phases double[] freqgrid = [978053.7,978301.8,978381.1]; // Table of frequency points bool retuning = false; // need for WBS retuning double[] targetlevels = [1.0,1.0,1.0]; // WBS tuning levels int data_time = 4; // chunk size int data_time_off = 4; // data dump interval on OFF int n_per_on = 1; // number of half nu1-nu2-nu2-nu1 cycles on ON int n_per_off = 1; // number of half nu1-nu2-nu2-nu1 cycles on OFF int n_long_on = 1; // number of cycles on ON without retuning int n_long_off = 1; // number of cycles on OFF without retuning int n_cycles = 1; // Number of half OFF-ON-ON-OFF cycles at one frequency int allsteps = 4; // Total number of frequency pointing periods int n_loadinterval = 1; // number of nods before a load measurement bool final_load = false; // Need for final load measurement int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,20,1,21,0]; // Timing of the observation from telescope int shiftlength = 0; // Shift of the loop start relative to the pointing }{ // Auxiliary variables // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time int tnodslew = telescopetimes[2]; // slew dead time between points // First frequency double runningfreq = freqgrid[grouporder[1][0]]; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] onrates = dataparms{1}; dataparms = DataTaking(backendreadoutparms,data_time_off); double[] offrates = dataparms{1}; int hkduration = HkReadoutTime(band,reffreq,backendreadoutparms,false); int readoutdead = SlowChopReadoutDelay(band,reffreq,backendreadoutparms); // recompute load duration for initial load measurement int loadlength = duration(SScanLoadMeasurement(band,runningfreq,reffreq,true,eff_resolution{0},data_time,backendreadoutparms)); loadlength = loadlength + readoutdead; bool retuneload = n_loadinterval > 1; // Tuning levels string[] targetnames = TargetNames(band,reffreq,retuning,targetlevels); string target = targetnames[0]; // All commands with a duration possibly depending on the frequency // are taken at the reference frequency to guarantee synchonization // Declare auxiliary variables to be used in the loops int i_freqcycles = 0; int i_group = 0; int i_phase = 0; // variables storing the configuration setting bool islong = false; bool isinvalid = true; //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; bool runintostate = false; while(state[0] >= 0) { if(runintostate) { state = next_state_no_check(); } else { state = next_state(); } if(state[0] == 1) { // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // HIFIInitObs(); TuneHIFI(band,runningfreq,hrs1,hrs2,wbs1{0},wbs2{0},target); delay(tinitslew - (time() - startobs) - loadlength + shiftlength - hkduration); // First load measurement HIFISetHK("normal",false); SScanLoadMeasurement(band,runningfreq,reffreq,true,eff_resolution{0},data_time,backendreadoutparms); if(shiftlength > 0) { runintostate = true; } else { runintostate = false; } } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 7) { // The NOD-state represents our OFF position // Reset group counter i_group = 0; runintostate = false; // long integrations not possible in last and first PS cycle if(n_cycles > 1 && state[2] % n_cycles != state[2] % 2) { if(isinvalid || !islong) { HIFIConfigureLoadChopIntegration(data_time_off,n_long_off,band,reffreq,backendreadoutparms); islong = true; isinvalid = false; } HIFILoadChopOffIntegration(data_time_off,n_long_off,band,reffreq,offrates); } else { if(isinvalid || islong) { HIFIConfigureLoadChopIntegration(data_time_off,n_per_off,band,reffreq,backendreadoutparms); islong = false; isinvalid = false; } // No group scanning on OFF HIFILoadChopOffIntegration(data_time_off,n_per_off,band,reffreq,offrates); // Now we switch to the next frequency group or repeat the cycle if(state[2] % n_cycles == 0 && state[2] % 2 == 0) { // Big tuning step, but not at end of observation if(state[2] < allsteps) { i_freqcycles = i_freqcycles + 1; runningfreq = freqgrid[grouporder[1][0] + i_freqcycles * grouplen]; target = targetnames[i_freqcycles]; HIFIRetuneFreq(band,runningfreq,target); runintostate = true; } else { // final load measurement if requested if(final_load) { delay(readoutdead); SScanLoadMeasurement(band,runningfreq,reffreq,retuneload,eff_resolution{0},data_time,backendreadoutparms); runintostate = true; } } } } // Active WBS HK if we have a nod slew without calibration if(state[2] % 2 == 1) { isinvalid = true; if(state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } } if(state[0] == 3) { // The POINT-state represents our source position i_phase = state[2] % 2; // ON integration runintostate = false; // long integrations not possible in last and first nod cycle if(n_cycles > 1 && state[2] % n_cycles != (state[2] % 2 + 1) % 2) { if(isinvalid || !islong) { HIFIConfigureLoadChopIntegration(data_time,n_long_on,band,reffreq,backendreadoutparms); islong = true; isinvalid = false; } HIFILoadChopOnIntegration(data_time,n_long_on,band,reffreq,onrates); } else { if(isinvalid || islong) { HIFIConfigureLoadChopIntegration(data_time,n_per_on,band,reffreq,backendreadoutparms); islong = false; isinvalid = false; } HIFILoadChopOnIntegration(data_time,n_per_on,band,reffreq,onrates); } // Other frequencies // Reset group counter i_group = 1; while(i_group <= grouplen - 1) { // retune runningfreq = freqgrid[grouporder[i_phase][i_group] + i_freqcycles * grouplen]; HIFIChangeFreq(band,runningfreq); if(i_group == 1) { if(isinvalid || islong) { HIFIConfigureLoadChopIntegration(data_time,n_per_on,band,reffreq,backendreadoutparms); islong = false; isinvalid = false; } } HIFILoadChopOnIntegration(data_time,n_per_on,band,reffreq,onrates); i_group = i_group + 1; } // Now we switch to the next frequency group or repeat the cycle if(state[2] % n_cycles == 0 && i_phase == 1) { // Big tuning step, but not at end of observation if(state[2] < allsteps) { i_freqcycles = i_freqcycles + 1; runningfreq = freqgrid[grouporder[0][0] + i_freqcycles * grouplen]; target = targetnames[i_freqcycles]; HIFIRetuneFreq(band,runningfreq,target); runintostate = true; } else { // final load measurement if requested if(final_load) { delay(readoutdead); SScanLoadMeasurement(band,runningfreq,reffreq,retuneload,eff_resolution{0},data_time,backendreadoutparms); runintostate = true; } } } // Active WBS HK if we have a nod slew without calibration if(state[2] % 2 == 0) { isinvalid = true; if(state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } } if(state[0] == 9) { // Load switch delay(readoutdead); SScanLoadMeasurement(band,runningfreq,reffreq,retuneload,eff_resolution{0},data_time,backendreadoutparms); isinvalid = true; runintostate = false; } // Danging load - already covered above // otherwise the instrument stops halftunelength before the telescope if(state[0] == 5) { // finished shift of instrument operations relative to pointing command runintostate = false; HIFICloseObs(); } } } // Initialisation of FPU, block with only H-MSA in use // It is only for warm context ! block Init_MSA_H_fm_warm HIFI 3217 { string band = "1a"; string chop_loop = "CLOSE"; double lo_freq = 522.0; //LO frequency }{ Start_block(); //Get parameters {double,string}[] result_d = ConfigurationReaderWarm("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,lo_freq); int band_nb = iround(result_d[0]{0}); double diplex_H = 0.0; double diplex_V = 0.0; int diplex_h_ctrl_mode = 0; int diplex_v_ctrl_mode = 0; // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],"0",0.0); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // string chop_sine_s = "ON"; // string chop_loop = "CLOSE" ; result_d = ConfigurationReaderWarm("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,lo_freq); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // double calibcurrent = result_d[7]{0}; // //Get biases result_d = ConfigurationReaderWarm("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); double bias_H = result_d[0]{0}; double bias_V = result_d[1]{0}; // //Get magnets: not applicable to bands 6 and 7 double magnetcurrent_H = 0.0; double magnetcurrent_V = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReaderWarm("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); magnetcurrent_H = result_d[0]{0}; magnetcurrent_V = result_d[1]{0}; } //Diplexer is interpolated from a table for Bands 3, 4, 6L and 6H if(band_nb <= 2 || band_nb == 5) { diplex_H = 0.0; //For bands 1, 2 and 5 diplex_V = 0.0; diplex_h_ctrl_mode = 0; diplex_v_ctrl_mode = 0; } else { //Get diplexer currents result_d = ConfigurationReaderWarm("name_confilfpu",["diplex_h_ctrl_mode","diplex_v_ctrl_mode","diplexer_current_normal_h","diplexer_current_normal_v"],band,lo_freq); diplex_h_ctrl_mode = iround(result_d[0]{0}); diplex_v_ctrl_mode = iround(result_d[1]{0}); //double[] result_dip = Get_Diplexer_setting(band,lo_freq); diplex_H = result_d[2]{0}; //result_dip[0]; diplex_V = result_d[3]{0}; //result_dip[1]; } // result_d = ConfigurationReader("name_chopper",["chop_startup_warm"],band,0.0); double chopper = result_d[0]{0}; //For this configuration we won't convert prime chopper voltage into redundant voltage //Just checking we are in range. //chopper = Check_Chopper_Prime_Redundant(chopper); chopper = Check_Chopper_Range(chopper); // //Switch on upconverter, assuming chopper and mixers are also ON Hifi_HIFI_Configure_FCU_Power($BBID,"ON","ON","ON","ON","ON"); // // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result_d = ConfigurationReaderWarm("name_delays",["config_fpu_delay"],band,lo_freq); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // Hifi_HIFI_non_periodic_hk_FCU(); } //PDU switch on of a S/S, block block PDU_switch_on_block_ops HIFI 7657 { string subsystem = "ICU_Prime" in ["ICU_Prime","ICU_Red","LO_Prime","LO_Red","WBS_H","WBS_V","HRS_H","HRS_V"]; }{ if(subsystem != "ICU_Prime" && subsystem != "ICU_Red") { StartBlock_ops(); //This has no delay } ////HifiIltEgse_PDU_switch_on($BBID,subsystem); //The TEI command: WILL BE DONE BY SPACON mois_spacon("Please power ON Sub-System " + subsystem); if(subsystem == "ICU_Prime" || subsystem == "ICU_Red") { mois_tmcheck("Verify PDU current for HIFI ICU is 1.0A +/- 10%"); mois_tmcheck("Verify arrival of (5,1) telemetry packet from HIFI after 10sec. (5,1) packets should then arrive every 10sec."); if(subsystem == "ICU_Prime") { mois_tmcheck("If the (5,1) telemetry packet is not received, HIFI is in RESCUE mode and the following procedures shall be executed: HIFI_Rescue_to_SwitchedOff_Prime, then HIFI_SwitchedOff_to_Intermediate_Redundant if this has not yet been attempted. Please contact the HIFI ICC in any case."); mois_tmcheck("If a (5,4) telemetry packet has been received, HIFI is in RESCUE mode and the following procedure shall be executed: HIFI_Rescue_to_SwitchedOff_Prime. Please contact the HIFI ICC."); } if(subsystem == "ICU_Redundant") { mois_tmcheck("If the (5,1) telemetry packet is not received, HIFI is in RESCUE mode and the following procedure shall be executed: HIFI_Rescue_to_SwitchedOff_Redundant, then HIFI_SwitchedOff_to_Intermediate_Prime if this has not yet been attempted. Please contact the HIFI ICC in any case."); mois_tmcheck("If a (5,4) telemetry packet has been received, HIFI is in RESCUE mode and the following procedure shall be executed: HIFI_Rescue_to_SwitchedOff_Redundant. Please contact the HIFI ICC."); } // } //Check current for other S/S if(subsystem == "LO_Prime" || subsystem == "LO_Red") { mois_tmcheck("Verify PDU current for HIFI LCU is 0.9A +/- 0.25A"); } if(subsystem == "WBS_H") { mois_tmcheck("Verify PDU current for HIFI WBS-H is 0.92A +/- 10%"); } if(subsystem == "WBS_V") { mois_tmcheck("Verify PDU current for HIFI WBS-V is 0.92A +/- 10%"); } if(subsystem == "HRS_H") { mois_tmcheck("Verify PDU current for HIFI HRS-H is 2.32A +/- 10%"); } if(subsystem == "HRS_V") { mois_tmcheck("Verify PDU current for HIFI HRS-V is 2.32A +/- 10%"); } //delay(1); } // HRS partial configuration, block // Configures the resolution mode block HRS_config_resol_block_fm HIFI 3618 { string band = "1a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code }{ //Start_block(); //////////////////////////////////////////////////////////////////// //Now Configure blocks //H-polar string hrs_filename_h = "name_confighrs_" + hrs_mode[0]; {double,string}[] result = ConfigurationReader(hrs_filename_h,["hrh_block_1","hrh_block_2","hrh_block_3","hrh_block_4","hrh_block_5","hrh_block_6","hrh_block_7","hrh_block_8"],band,0.0); string hrh_block_1 = result[0]{1}; string hrh_block_2 = result[1]{1}; string hrh_block_3 = result[2]{1}; string hrh_block_4 = result[3]{1}; string hrh_block_5 = result[4]{1}; string hrh_block_6 = result[5]{1}; string hrh_block_7 = result[6]{1}; string hrh_block_8 = result[7]{1}; // result = ConfigurationReader("name_delays",["hrs_config_delay"],band,0.0); int hrs_config_delay = iround(result[0]{0}); // Hifi_HIFI_Config_HRS_H_blocks($BBID,hrh_block_1,hrh_block_2,hrh_block_3,hrh_block_4,hrh_block_5,hrh_block_6,hrh_block_7,hrh_block_8); //delay(hrs_config_delay); // //V-polar string hrs_filename_v = "name_confighrs_" + hrs_mode[1]; result = ConfigurationReader(hrs_filename_v,["hrv_block_1","hrv_block_2","hrv_block_3","hrv_block_4","hrv_block_5","hrv_block_6","hrv_block_7","hrv_block_8"],band,0.0); string hrv_block_1 = result[0]{1}; string hrv_block_2 = result[1]{1}; string hrv_block_3 = result[2]{1}; string hrv_block_4 = result[3]{1}; string hrv_block_5 = result[4]{1}; string hrv_block_6 = result[5]{1}; string hrv_block_7 = result[6]{1}; string hrv_block_8 = result[7]{1}; // Hifi_HIFI_Config_HRS_V_blocks($BBID,hrv_block_1,hrv_block_2,hrv_block_3,hrv_block_4,hrv_block_5,hrv_block_6,hrv_block_7,hrv_block_8); // //Wait delay to allow all setting to be configured delay(hrs_config_delay); } // Configuration for load-chop integration block HIFIConfigureLoadChopIntegration HIFI 6034 { int data_time = 4; // Integration time between two data readouts int n_cycle = 1; // chop cycle number string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // HRS1/2 {used,resolution,subbands used}, WBS1/2 {used, channel windows} }{ // Call procedure doing the work ConfigureSpectroscopy(data_time,2 * n_cycle,"lchop",band,lo_freq,backendreadoutparms); } // WBS laser temperature control switched on, block block Laser_T_check_on_fm HIFI 3704 { double laserT_limit = 40.0; //new limit above which OBS switches off the laser }{ int nbreach = 5; Hifi_HIFI_WH_Laser_T_check_on(nbreach,laserT_limit); Hifi_HIFI_WV_Laser_T_check_on(nbreach,laserT_limit); delay(1); } //HIFI-COP-1.2-IF_FT obs HifiEng_IF_FT_COP { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(IF_FT_COP_proc_ops(band,lo_freq,prime_or_redundant)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution IF_FT_COP_proc_ops(band,lo_freq,prime_or_redundant); } if(state[0] == 5) { HIFISetHK("normal",true); StopMode_block_ops(); } } } ////////////////////////////////////////////////////// // Definitions to test peakup functions // // DT - 20-03-07 ////////////////////////////////////////////////////// // Reminder information: // peak positions are labelled as follows: // i dimension is along chopper rotation // j dimension is along M3 long axis // (i,j) -1 0 1 // 1 3 6 9 // 0 2 5 8 // -1 1 4 7 ////////////////////////////////////////////////////// //modes: see fm_testmodes.cus ////////////////////////////// // Procedures and blocks ////////////////////////////// // Simulating PU report packet emission block Simulate_PU_block_fm HIFI 3822 { int hifi_HI_microrot_y = 5; // HI_microrot_y int hifi_HI_microrot_z = 7; // HI_microrot_z }{ Start_block(); Hifi_HIFI_simulate_peakup(hifi_HI_microrot_y,hifi_HI_microrot_z); delay(1); } ///////////////////////////////////////////////////////////////// // Procedure to compute total dead times for the mode // {double,double,double,double,double} procedure OTFDoubleChop_deadtimes { string chopmode = "chop" in ["chop","lchop","fs"]; // chop mode string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // chunk size given by the data rates and optimum speed int data_time_off = 4; // data dump interval on OFF int n_switch_on = 1; // Supersamplingfactor int n_switch_off = 3; // Number of data dumps for the OFF integration time int n_linesperscan = 1 in [1,32]; // Number of lines between two OFFs int n_pp = 10; // Number of data dumps per line double tdead = 10.0; // Dead time from telescope }{ ////////////////////////////////////////////////////////////////////// // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Dead time in OFF {double,double} tinst = GetInstDeadSlowChop(data_time_off,2 * n_switch_off,chopmode,band,lo_freq,backendreadoutparms); // dead time within OFF double tdeadint = double(data_time_off * 2 * n_switch_off) - tinst{0}; // subtract dead times in switches tdeadint = tdeadint - double(n_switch_off) * tinst{1}; // add to total dead time double tdead_tot = tdead + tdeadint; double tswitch_off = tinst{1}; double tphaseint_off = tinst{0} / double(2 * n_switch_off); // Dead time in one line tinst = GetInstDeadSlowChop(data_time,n_pp,chopmode,band,lo_freq,backendreadoutparms); // Dead time for each line tdeadint = double(data_time * n_pp) - tinst{0}; tdead_tot = tdead_tot + double(n_linesperscan) * tdeadint; double tswitch_on = tinst{1}; double tphaseint_on = tinst{0} / double(n_pp); // Return total dead time and actual integration times return {tdead_tot,tphaseint_on,tphaseint_off,tswitch_on,tswitch_off}; } //Procedure checking whether the requested integration //time is compliant with the allowed packet/datarate //in slow chop spectroscopy context bool procedure Check_Slow_Chop_datarate { int n_wbs_start = 2; //Nb of frames int r_hrs = 1; //Nb of HRS readout per WBS readout int n_wbs_integr = 1; //Number of wbs readout packetized per WBS frame int n_hrs_integr = 1; //Number of hrs readout packetized per HRS frame int del_hrs = 5; //Delay before starting HRS integration int del_wbs = 5; //Delay before starting WBS integration int t_acc_wbs = 4005; //Duration of WBS frame int t_acc_hrs = 1950; //Duration of HRS frame int wbsh_offset1 = 0; int wbsh_width1 = 2048; int wbsh_offset2 = 2048; int wbsh_width2 = 2048; int wbsh_offset3 = 4096; int wbsh_width3 = 2048; int wbsh_offset4 = 6144; int wbsh_width4 = 2048; int wbsv_offset1 = 0; int wbsv_width1 = 2048; int wbsv_offset2 = 2048; int wbsv_width2 = 2048; int wbsv_offset3 = 4096; int wbsv_width3 = 2048; int wbsv_offset4 = 6144; int wbsv_width4 = 2048; int hrs_rshift = 0; //HRS bit shift int wbs_rshift = 0; //WBS bit shift int hrsh_sel = 255; //HRS-H band selection int hrsv_sel = 255; //HRS-V band selection string wbs_packing = "24_bits_format"; string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3 string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ error("Procedure Check_Slow_Chop_datarate is not used anymore."); return false; } // Change LO frequency but keep backend configuration - used in spectral scans // procedure HIFIRetuneFreq { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency ion MHz string level = "sscan_normal"; // Name of target level }{ ConfigureFPU(band,lo_freq,false); HIFITuneFreq(band,lo_freq,true,level); } //Set mixer bias procedure Mixerbias { double bias_h = 0.0; double bias_v = 0.0; }{ Hifi_HIFI_CH1_MXBIAS_V($BBID,bias_h); Hifi_HIFI_CV1_MXBIAS_V($BBID,bias_v); delay(1); } //////////////////////////////////// // OTF load-chop observing mode without baseline calibration // // Return time and noise levels {int,double,double,double,double,double} obs HifiMappingProcLoadChopOTFNoRef { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source {double,double} lineDistance = {0.0050,0.0050}; // Distance between subsequent rows int nlines = 1 in [1,240]; // Number of rows in the map double stepsize = 0.0050 in [0.0,0.13333]; // Distance between subsequent points in the OTF line int npoints = 10 in [1,720]; // Number of data dumps per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // chunk size given by the data rates and optimum speed int n_switch_on = 1 in [1,1800]; // Supersamplingfactor int n_cycles = 1 in [1,1200]; // Number of map coverages int load_interval = 1800 in [10,7200]; // load period defines number of lines between two loads bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Mapping - OTF Map Load Chop noRef",{data_time,0,0,n_switch_on,0,0,0,0,n_cycles,load_interval}); // Auxiliary routine for API parameter correction {double,double,int} mapused = ValidMapSize(band,lo_freq,lineDistance,nlines,stepsize,npoints,2 * data_time * n_switch_on); double line_used = mapused{0}; double scanvelocity = mapused{1}; int npoints_used = mapused{2}; // Call first part of the timing computer {int,int,int,int,bool,int,int} pre_timing = OTFLoadChopNoRef_pre_timing(nlines,npoints_used,band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_switch_on,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,double,double,int,int,int} tpar = OTFDoubleChopNoRef_telescope(naifid,onPosition,lineDistance,nlines,line_used,scanvelocity,band,lo_freq,n_cycles,pre_timing); // Dummy call to spacecraft command int[] telescopetimes = line_scan_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17}); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,bool,int,int},double,double} post_timing = OTFDoubleChopNoRef_post_timing(pre_timing,telescopetimes,nlines,data_time,n_cycles); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = OTFDoubleChopNoRef_telescope(naifid,onPosition,lineDistance,nlines,line_used,scanvelocity,band,lo_freq,n_cycles,post_timing{1}); // Call telescope command telescopetimes = line_scan_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17}); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{0}; bool end_load_on = post_timing{1}{4}; int n_loadinterval = post_timing{1}{2}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { OTFLoadChopNoRef_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,npoints_used * n_switch_on,n_loadinterval,nlines * n_cycles,end_load_on,startobs,telescopetimes,loadlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double} tact = SingleChop_deadtimes("fs",band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,npoints_used * n_switch_on); double tscan = 2.0 * (tact{1} + tact{2}); double tdead = 2.0 * tact{2}; // // Call noise computer {double,double,double,double,double} noisevalues = PositionSwitch_noisecomputer(band,lo_freq,effResolution,oneGHzReference,n_switch_on * n_cycles,tscan,tdead); // Evaluate performance OTFDoubleChopNoRef_performance(band,lo_freq,effResolution,noisevalues,timeTaken,nlines,npoints_used,n_switch_on * n_cycles,false,tscan,tdead); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } //TM to control FDIR on LOU temp block Set_LO_FDIR_temperatures_block_aot HIFI 6953 { }{ // BBID needs to be set manually as the main TC command has no BBID argument Hifi_HIFI_Set_OBS_ID($BBID,$OBSID); //Fetch values to apply: band-independent so far double[] cresult = CalibrationReader("name_loheater",["tmin","tmax","nbreach"],"1a",0.0); double tmin = cresult[0]; //Min threshold double tmax = cresult[1]; //Max threshold int nbreach = iround(cresult[2]); //Number of breach // Hifi_HIFI_LOU_T_check_on(nbreach,tmax,tmin); delay(1); // } // SFT: Init of all S/S, procedure // This is only for warm context procedure HIFI_SFT_proc_warm { string band = "1a"; // HIFI band double lo_freq = 500.0; //LO frequency string mixer_polarization = "H" in ["H","V","B"]; //Polarization: H, V or Both string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code string chop_loop = "CLOSE"; //The chopper loop status int integ_time = 4; //Total integration time in sec. string laser_H = "Laser1" in ["Laser1","Laser2"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2"]; //WBS-V laser to be set ON string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ // //Init of instrument: depends on polarization // if(mixer_polarization == "H") { Init_MSA_H_fm_warm(band,chop_loop,lo_freq); } if(mixer_polarization == "V") { Init_MSA_V_fm_warm(band,chop_loop,lo_freq); } if(mixer_polarization == "B") { Init_MSA_fm_warm(band,chop_loop,lo_freq); } // //Configure WBS laser according to user inputs. Delays are included //Maximum attenuation is used since it is what is set in the default config file //In fact laser should have been switched on previously for the 2 min. stabilization if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_config_w_laser_block_fm(band,laser_H,laser_V); } if(backend == "hrs" || backend == "both") { HRS_config_max_att_block_fm(band,hrs_mode); } // //Init of LO: configuration. Delays are included Set_LO_Nominal_block_fm(); LCU_switchon_proc_fm(band); // //Configure spectroscopy integration Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); // } //HIFI-COP-2.2-VecscanCal obs HifiEng_Vecscan_calibration_COP { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Vecscan_calibration_proc_fm_COP(band)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Vecscan_calibration_proc_fm_COP(band); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } // WBS bitflip test, block // Done for laser1 block FT_WBS_bitflip HIFI 3709 { string band = "1a"; // HIFI band int n = 100; //number of loops int integ_time = 4; //Total integration time in sec. string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); // //Set zero and comb off Hifi_HIFI_Single_cmd($BBID,"HWH_ZERO_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWV_ZERO_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWH_COMB_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWV_COMB_OFF"); delay(2); // //Initial configuration: overall attenuators set to max., individual attenuators to 0 //H-Polarization // {double,string}[] result = ConfigurationReader("name_configwbs",["hwh_heater","hwh_latchup_s"],band,0.0); string hwh_laser1_s = "OFF"; string hwh_laser2_s = "ON"; int hwh_heater = iround(result[0]{0}); string hwh_latchup_s = result[1]{1}; int hwh_att_band4 = 0; int hwh_att_band3 = 0; int hwh_att_band2 = 0; int hwh_att_band1 = 0; int hwh_att_in = 10; // result = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result[0]{0}); // //V-Polarization // result = ConfigurationReader("name_configwbs",["hwv_heater","hwv_latchup_s"],band,0.0); string hwv_laser1_s = "ON"; string hwv_laser2_s = "OFF"; int hwv_heater = iround(result[0]{0}); string hwv_latchup_s = result[1]{1}; int hwv_att_band4 = 0; int hwv_att_band3 = 0; int hwv_att_band2 = 0; int hwv_att_band1 = 0; int hwv_att_in = 10; // //Loop on overall attenuators for(int i = 0 .. n) { //======================================== // Set WBS //======== //0dB attenuation on individual attenuators hwh_att_band4 = 0; hwh_att_band3 = 0; hwh_att_band2 = 0; hwh_att_band1 = 0; Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); delay(wbs_config_delay); //Wait for configuration to be applied // hwv_att_band4 = 0; hwv_att_band3 = 0; hwv_att_band2 = 0; hwv_att_band1 = 0; Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); delay(wbs_config_delay); //Wait for configuration to be applied // HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // // //1dB attenuation on individual attenuators hwh_att_band4 = 1; hwh_att_band3 = 1; hwh_att_band2 = 1; hwh_att_band1 = 1; Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); delay(wbs_config_delay); //Wait for configuration to be applied // hwv_att_band4 = 1; hwv_att_band3 = 1; hwv_att_band2 = 1; hwv_att_band1 = 1; Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); delay(wbs_config_delay); //Wait for configuration to be applied // HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // } // } // LCU configuration into NOMINAL mode, procedure procedure LCU_config_nominal_w_D2_proc_fm { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency double drain2_v = 1.4; //Drain2 voltage in V }{ //Clear potential failure mode Set_LO_Nominal_block_fm(); // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v_start = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1_v = result[0]{1}; string curlim2_v = result[1]{1}; // result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); // //Send command: expect that we have already switched to NOMINAL //Contrary to QM, the channel is automatically switched ON HIFI_Configure_LCU_block_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum,config_lo_delay); // } // LCU6La configuration into SAFE mode, procedure procedure LCU6La_config_safe_proc_fm { string band = "6a"; // HIFI band double lo_freq = 1500.0 in [1410.0,1575.0]; //LO frequency }{ error("This module is obsolete: use LCU_config_nominal_proc_fm instead"); } ////////////////////////////////////////////////////////////////////// // Procedure to display performance parameters of the observing mode procedure DoubleChop_performance { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {double,double,double,double,double} noisevalues = {1.0,1.0,1.0,1.0,0.0}; // Noise values from noisecomputer int totaltime = 200; // Total observing time int n_cycles = 1; // Number of ON-OFF cycles int n_chop_on = 1; // number of half load-sky-sky-load cycles on ON int n_chop_off = 1; // number of half load-sky-sky-load cycles on OFF bool fs = false; // whether frequency switch used double tscan = 60.0; // Total average duration of one scan int pointing = 20; // Pointing duration in the source phase {double,double,double,double,double} tact = {10.0,4.9,4.9,0.05,0.05}; // Field of actual dead and integration times }{ double inttimeperonphase = tact{1}; // Actual integration time in ON phase double inttimeperoffphase = tact{2}; // Actual integration time in OFF phase // Get performance of ideal instrument for comparison {int,double,double,double,double,double} idealvalues = IdealInstrument(band,lo_freq,eff_resolution,totaltime); double idealnoise = idealvalues{1} * idealvalues{1}; double obsnoise = noisevalues{0} * noisevalues{0}; double efficiency = idealnoise / obsnoise; // Compute the actual integration time double posinttime = double(n_cycles * 2 * n_chop_on) * inttimeperonphase; double posofftime = double(n_cycles * 2 * n_chop_off) * inttimeperoffphase; int instrumenttime = iceil(double(n_cycles) * tscan); // Check total integration time double timeefficiency = (posinttime + posofftime) / double(totaltime); // Noise contribution double relnoise = noisevalues{4} / (1.0 + noisevalues{4}); // General messages PerformanceMessages(band,lo_freq,totaltime,posinttime,posofftime,timeefficiency,efficiency,relnoise,fs); } // Standing wave analysis // Procedure looping on freq and los to compute total times per band //HIFI-COP-3-StWv1 procedure Standing_wave_noretune_MOIS_proc_ops { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string backend = "both"; string[] hrs_mode = ["wb1","wb1"]; }{ //Retrieve frequencies from LUT string tabstwv = "config_stwvfreq.config"; double bandnb = GetBandCode(band); //Include LO switch-on to compute full time: approximative if(bandnb < 11.0) { delay(1850); } else { delay(3060); } // int nb_lo_freq = 4; string[] los_code = ["sc","sh","ss"]; int[] res = [0,0]; double step = 0.015; //GHz double[] lo_freq_input = [0.0,0.0,0.0]; //Loop on frequencies for(int j = 1 .. nb_lo_freq) { double lo_freq = dlookup(tabstwv,"" + iceil(bandnb),"freq" + j); int integ_time = ilookup(tabstwv,"" + iceil(bandnb),"t" + j); //Loop on line-of-sight int nb_los = 3; if(j > 1) { nb_los = 1; } for(int i = 0 .. nb_los - 1) { if(lo_freq != 0.0) { int total_stepnb = ilookup(tabstwv,"" + iceil(bandnb),"n" + j + "_" + los_code[i]); double stepnb = double(total_stepnb / 2); if(total_stepnb != 0) { HRS_config_block_fm(band,hrs_mode); // if(los_code[i] == "sh") { res = Configure_Spectrometer_hc_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); } else { res = Configure_Spectrometer_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); } int total_time = res[0] * res[1]; lo_freq_input = [lo_freq - stepnb * step,lo_freq + stepnb * step,step]; Standing_wave_noretune_fm_COP(band,total_time,hrs_mode,backend,lo_freq_input,los_code[i]); } } } } //For band 2a, we need to add the retune case if(band == "2a") { Standing_wave_retune_COP_proc_ops(band,"both",["mr","mr"],1,"sc"); } } // Interpolate differential frequency switch Allan time and exponent // // This might actually depend on the frequency throw, but no information // is available. Thus a restructuring of this routine is probable. // double[] procedure InterpolateSpecFSwitchAllan { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency bool subband = false; // 1GHz bandwith reference instead of full IF }{ if(subband) { double[] allan = CalibrationReader("fs_Allan_subband",["spec_Allan_time","spec_Allan_exp","spec_binning_exp"],band,lo_freq); } else { allan = CalibrationReader("fs_Allan",["spec_Allan_time","spec_Allan_exp","spec_binning_exp"],band,lo_freq); } return allan; } //HIFI investigation of diplexer with M1, procedure //Perform diplexer scans at a series of M1 values //Frequencies and M1 values to use are pre-tabulated procedure Diplexerscan_M1_proc_fm_COP { string band = "7b" in ["3b","5a","5b","7a","7b"]; // HIFI band int testblock = 1 in [0,3]; //Test block }{ //Sanity checks: no blocks 0 and 3 for 7b if(band == "7b" && (testblock == 0 || testblock == 3)) { error("There's no such testblock allowed in 7b"); } mois_comment("Start of Diplexer scan investigation in band " + band); mois_comment("For this test, a special LCU safety table should have been uploaded via dedicated TPF files"); //We will loop on tabulated frequencies //For each we will tune LO power and do diplexer scans //for various M1/M2 settings for 3b and 7b //1. Get the list of frequencies to be used for the scan if(band == "7b") { string tab1 = "config_purity_cop_" + band + ".config"; } else { tab1 = "config_M1calib_" + band + "_" + testblock + ".config"; if(testblock == 0) { tab1 = "config_M1calib_" + band + "_COP.config"; string tab2 = "config_M2calib_" + band + "_COP.config"; } } if(band == "7a") { tab1 = "config_purity_cop_" + band + ".config"; } if(band == "5a") { tab1 = "config_purity_cop_" + band + ".config"; } if(band == "5b") { tab1 = "config_purity_cop_" + band + ".config"; } if(band == "3b") { int total = table_size(tab1); double[] freq = []; double[] m1_1 = []; double[] m1_2 = []; double[] m1_3 = []; double[] m1_4 = []; double[] m1_5 = []; double[] m1_6 = []; double[] m1_7 = []; double[] m1_8 = []; double[] m2 = []; double[] m3 = []; //Read all entries for(int j = 1 .. total) { freq[j] = dlookup(tab1,"" + j,"frequency"); m1_1[j] = dlookup(tab1,"" + j,"m1_1"); m1_2[j] = dlookup(tab1,"" + j,"m1_2"); m1_3[j] = dlookup(tab1,"" + j,"m1_3"); m1_4[j] = dlookup(tab1,"" + j,"m1_4"); m1_5[j] = dlookup(tab1,"" + j,"m1_5"); m1_6[j] = dlookup(tab1,"" + j,"m1_6"); m1_7[j] = dlookup(tab1,"" + j,"m1_7"); //m1_8[j] = dlookup(tab1,"" + j,"m1_8"); if(testblock > 0) { m2[j] = dlookup(tab1,"" + j,"m2_" + testblock); m3[j] = dlookup(tab1,"" + j,"m3_" + testblock); } else { m2[j] = dlookup(tab2,"" + j,"m2_1"); m3[j] = dlookup(tab2,"" + j,"m3_1"); } //Check whether this combination of band+freq is allowed in the current CUS Check_Band_vs_Freq_proc_fm(band,freq[j]); } // } mois_step("Switch-on LO band (only for testblocks 0 or 1)"); //Only if first testblock if(testblock <= 1 && band == "3b") { LCU_switchon_proc_spur(band); //Wait an extra delay of 10 min for mid term stabilization delay(600); mois_tmcheck("Check that parameter HL_Channel_S is " + band); // } // if(band == "3b") { mois_step("Loop on frequencies and multiplier settings"); //Start loop on diplexer scans double[] m1_array = []; double[] m2_array = []; for(int i = 1 .. total) { //Configure FPU at that frequency Init_MSA_fm(band,"CLOSE",freq[i],"ON"); // //Loop on M1 settings int nb_m1 = 7; int nb_m2 = 1; if(band == "3b") { m1_array = [m1_1[i],m1_2[i],m1_3[i],m1_4[i],m1_5[i],m1_6[i],m1_7[i]]; //now work with 3 blocks of 1 M2 m2_array = [m2[i]]; if(testblock == 2) { m2_array = [m2[i]]; } if(testblock == 3) { m2_array = [m2[i]]; } if(testblock == 0) { m2_array = [m2[i]]; } } // //Loop on M1 for(int k = 0 .. nb_m1 - 1) { //Loop on M2 for(int l = 0 .. nb_m2 - 1) { //Prepare for diplexer scan //Use nominal diplexer values double[] result_dip = Get_Diplexer_setting(band,freq[i]); Set_Diplexer_current_block_fm(result_dip[0],result_dip[1]); //Set the maximum Vd2 available LCU_config_w_M1M2M3_block_fm(band,freq[i],m1_array[k],m2_array[l],m3[i]); message(band + ", " + freq[i] + ", " + m1_array[k] + ", " + m2_array[l] + ", " + m3[i]); //Perform diplexer scan at that frequency and M1 setting double diplexer_current_min_h = -2.24; double diplexer_current_max_h = 2.24; double diplexer_current_step = -0.073; //i.e. approx 4.48/61 int n_steps = 61; double stepTime = 0.1; // //Perform 2 diplexer scans: one immediately after, and one X sec after the tuning macro //so that total time between tuning macros is 1min, or 30sec between tuning macro and 2nd scan Scan_diplexer_block_fm(band,diplexer_current_max_h,diplexer_current_max_h,diplexer_current_step,n_steps,stepTime); // //Add delay: //For one minute between each tuning macro: 25sec more on average //For 30sec between tuning macro and second scan: 16sec more on average //Req. is now: 30sec between 2 tuning macros -> 4sec delay(4); //Second scan Scan_diplexer_block_fm(band,diplexer_current_max_h,diplexer_current_max_h,diplexer_current_step,n_steps,stepTime); } } // } } //Band 7a measurement if(band == "7a") { //Read scan parameters for block of interest double lo_freq_low = dlookup(tab1,"" + testblock,"lo_freq1"); double lo_freq_high = dlookup(tab1,"" + testblock,"lo_freq2"); double lo_freq_step = dlookup(tab1,"" + testblock,"freq_step"); double m1_low = dlookup(tab1,"" + testblock,"m1_low"); double m1_step = dlookup(tab1,"" + testblock,"m1_step"); double m1_high = dlookup(tab1,"" + testblock,"m1_high"); //Init MSA Init_MSA_fm(band,"CLOSE",lo_freq_low,"ON"); //Mixer should be biased to 3mV to avoid oscillation {double,string}[] result = ConfigurationReader("name_confilfpu",["bias_dipscan_h","bias_dipscan_v","bias_max_h","bias_max_v"],band,lo_freq_low); //First go to 6mV Mixerbias_block_fm(result[2]{0},result[3]{0}); //Then to 3mV Mixerbias_block_fm(result[0]{0},result[1]{0}); //Loop on frequencies double lo_freq = lo_freq_low; while(lo_freq <= lo_freq_high) { //Whole FPU not re-configured. Only diplexers are re-adjusted result_dip = Get_Diplexer_setting(band,lo_freq); Set_Diplexer_current_block_fm(result_dip[0],result_dip[1]); //First set at nominal M1, M2, and best-guess Vd2 result = ConfigurationReader("name_configlcu_b",["m1_v","m2_v"],band,lo_freq); double m1_7a = result[0]{0}; double nominal_m1 = m1_7a; double m2_7a = result[1]{0}; double nominal_m2 = m2_7a; //Get safe Vd2 double[] cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); double vd2_safe = cresult[0]; //Get max Vd2 double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); // // LCU_config_w_M1M2D2_block_fm(band,lo_freq,nominal_m1,nominal_m2,drain2_bluemax); //message("Initial config at nominal settings and max Vd2"); //message(band+", "+lo_freq+", "+nominal_m1+", "+nominal_m2+", "+drain2_bluemax); //Loop on M1 with nominal M2 m1_7a = m1_low; message("Loop on M1: -7 to nominal"); while(m1_7a <= nominal_m1) { //Reset to diplexers of interest result_dip = Get_Diplexer_setting(band,lo_freq); Set_Diplexer_current_block_fm(result_dip[0],result_dip[1]); //Configure LO at these settings LCU_config_w_M1M2D2_block_fm(band,lo_freq,m1_7a,nominal_m2,drain2_bluemax); message(band + ", " + lo_freq + ", " + m1_7a + ", " + nominal_m2 + ", " + drain2_bluemax); //Do diplexer scan //Prepare for diplexer scan //Perform diplexer scan at that frequency and M1 setting diplexer_current_min_h = -2.24; diplexer_current_max_h = 2.24; diplexer_current_step = -0.073; //i.e. approx 4.48/61 n_steps = 61; stepTime = 0.1; // //Perform 2 diplexer scans: one immediately after, and one X sec after the tuning macro //so that total time between tuning macros is 1min, or 30sec between tuning macro and 2nd scan Scan_diplexer_block_fm(band,diplexer_current_max_h,diplexer_current_max_h,diplexer_current_step,n_steps,stepTime); delay(4); Scan_diplexer_block_fm(band,diplexer_current_max_h,diplexer_current_max_h,diplexer_current_step,n_steps,stepTime); // result_dip = Get_Diplexer_setting(band,lo_freq); Set_Diplexer_current_block_fm(result_dip[0],result_dip[1]); //LO tuning with 0.6mV bias result = ConfigurationReader("name_confilfpu",["bias_LO_tuning_h","bias_LO_tuning_v","bias_max_h","bias_max_v"],band,lo_freq_low); //First go to 6mV Mixerbias_block_fm(result[2]{0},result[3]{0}); //Then to 3mV Mixerbias_block_fm(result[0]{0},result[1]{0}); LO_tuning_w_M1M2_block_fm(band,lo_freq,m1_7a,nominal_m2); //Re-do diplexer scan result = ConfigurationReader("name_confilfpu",["bias_dipscan_h","bias_dipscan_v","bias_max_h","bias_max_v"],band,lo_freq_low); //First go to 6mV Mixerbias_block_fm(result[2]{0},result[3]{0}); //Then to 3mV Mixerbias_block_fm(result[0]{0},result[1]{0}); Scan_diplexer_block_fm(band,diplexer_current_max_h,diplexer_current_max_h,diplexer_current_step,n_steps,stepTime); //next step m1_7a = m1_7a + m1_step; if(m1_7a > -6.0 && m1_7a < nominal_m1) { m1_7a = nominal_m1; } } lo_freq = lo_freq + lo_freq_step; } //end of freq loop //Set nominal settings back - use safe Vd2 LCU_config_w_M1M2D2_block_fm(band,lo_freq - lo_freq_step,nominal_m1,nominal_m2,vd2_safe); } // //Band 7b measurement if(band == "7b") { //Read scan parameters for block of interest lo_freq_low = dlookup(tab1,"" + testblock,"lo_freq1"); lo_freq_high = dlookup(tab1,"" + testblock,"lo_freq2"); lo_freq_step = dlookup(tab1,"" + testblock,"freq_step"); m1_low = dlookup(tab1,"" + testblock,"m1_low"); m1_step = dlookup(tab1,"" + testblock,"m1_step"); double m2_low = dlookup(tab1,"" + testblock,"m2_low"); double m2_high = dlookup(tab1,"" + testblock,"m2_high"); double m2_step = dlookup(tab1,"" + testblock,"m2_step"); //Init MSA Init_MSA_fm(band,"CLOSE",lo_freq_low,"ON"); //Mixer should be biased to 3mV to avoid oscillation result = ConfigurationReader("name_confilfpu",["bias_dipscan_h","bias_dipscan_v","bias_max_h","bias_max_v"],band,lo_freq_low); //First go to 6mV Mixerbias_block_fm(result[2]{0},result[3]{0}); //Then to 3mV Mixerbias_block_fm(result[0]{0},result[1]{0}); //Loop on frequencies lo_freq = lo_freq_low; while(lo_freq <= lo_freq_high) { //Whole FPU not re-configured. Only diplexers are re-adjusted result_dip = Get_Diplexer_setting(band,lo_freq); Set_Diplexer_current_block_fm(result_dip[0],result_dip[1]); //First set at nominal M1, M2, and best-guess Vd2 result = ConfigurationReader("name_configlcu_b",["m1_v","m2_v"],band,lo_freq); double m1_7b = result[0]{0}; nominal_m1 = m1_7b; double m2_7b = result[1]{0}; nominal_m2 = m2_7b; //Get safe Vd2 cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); vd2_safe = cresult[0]; //Get best-guess Vd2 result = ConfigurationReader("name_configlcutune_b",["drain2_v"],band,lo_freq); double drain2_v_best_guess = result[0]{0}; // LCU_config_w_M1M2D2_block_fm(band,lo_freq,nominal_m1,nominal_m2,vd2_safe); message("Initial config at nominal settings and safe Vd2 (no RF)"); message(band + ", " + lo_freq + ", " + nominal_m1 + ", " + nominal_m2 + ", " + vd2_safe); //Then loop on M2 with nominal M1 m2_7b = m2_low; message("Loop on M2: -12 to -8"); while(m2_7b <= m2_high) { //Configure LO at these settings LCU_config_w_M1M2D2_block_fm(band,lo_freq,nominal_m1,m2_7b,drain2_v_best_guess); message(band + ", " + lo_freq + ", " + nominal_m1 + ", " + m2_7b + ", " + drain2_v_best_guess); m2_7b = m2_7b + m2_step; } //Finally, loop on M1 with nominal M2 m1_7b = m1_low; message("Loop on M1: -8.5 to nominal"); while(m1_7b <= nominal_m1) { //Configure LO at these settings LCU_config_w_M1M2D2_block_fm(band,lo_freq,m1_7b,nominal_m2,drain2_v_best_guess); message(band + ", " + lo_freq + ", " + m1_7b + ", " + nominal_m2 + ", " + drain2_v_best_guess); m1_7b = m1_7b + m1_step; } lo_freq = lo_freq + lo_freq_step; } //end of freq loop //Set nominal settings back - use safe Vd2 LCU_config_w_M1M2D2_block_fm(band,lo_freq - lo_freq_step,nominal_m1,nominal_m2,vd2_safe); } // //Band 5a measurement if(band == "5a") { //Read scan parameters for block of interest lo_freq_low = dlookup(tab1,"" + testblock,"lo_freq1"); lo_freq_high = dlookup(tab1,"" + testblock,"lo_freq2"); lo_freq_step = dlookup(tab1,"" + testblock,"freq_step"); m1_low = dlookup(tab1,"" + testblock,"m1_low"); m1_step = dlookup(tab1,"" + testblock,"m1_step"); m1_high = dlookup(tab1,"" + testblock,"m1_high"); double vd2_min = dlookup(tab1,"" + testblock,"vd2_min"); //Loop on frequencies lo_freq = lo_freq_low; while(lo_freq <= lo_freq_high) { //Whole FPU re-configured. Init_MSA_fm(band,"CLOSE",lo_freq_low,"ON"); //Get nominal M1, M2 result = ConfigurationReader("name_configlcu_b",["m1_v","m2_v"],band,lo_freq); double m1_5a = result[0]{0}; nominal_m1 = m1_5a; double m2_5a = result[1]{0}; nominal_m2 = m2_5a; //Get safe Vd2 cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); vd2_safe = cresult[0]; //Get max Vd2 drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); //Loop on M1 with nominal M2 m1_5a = m1_low; message("Loop on M1: -6.5 to -4.0"); while(m1_5a <= m1_high) { //Vector scan at these settings Vector_scan_w_M1M2D2_block_fm(band,lo_freq,m1_5a,nominal_m2,vd2_min); message(band + ", " + lo_freq + ", " + m1_5a + ", " + nominal_m2 + ", " + drain2_bluemax); //next step m1_5a = m1_5a + m1_step; } lo_freq = lo_freq + lo_freq_step; } //end of freq loop //Set nominal settings back - use safe Vd2 LCU_config_w_M1M2D2_block_fm(band,lo_freq - lo_freq_step,nominal_m1,nominal_m2,vd2_safe); } // //Band 5b measurement if(band == "5b") { //Read scan parameters for block of interest lo_freq_low = dlookup(tab1,"" + testblock,"lo_freq1"); lo_freq_high = dlookup(tab1,"" + testblock,"lo_freq2"); lo_freq_step = dlookup(tab1,"" + testblock,"freq_step"); m1_low = dlookup(tab1,"" + testblock,"m1_low"); m1_step = dlookup(tab1,"" + testblock,"m1_step"); m1_high = dlookup(tab1,"" + testblock,"m1_high"); vd2_min = dlookup(tab1,"" + testblock,"vd2_min"); //Loop on frequencies lo_freq = lo_freq_low; while(lo_freq <= lo_freq_high) { //Whole FPU re-configured. Init_MSA_fm(band,"CLOSE",lo_freq_low,"ON"); //Get nominal M1, M2 result = ConfigurationReader("name_configlcu_b",["m1_v","m2_v"],band,lo_freq); double m1_5b = result[0]{0}; nominal_m1 = m1_5b; double m2_5b = result[1]{0}; nominal_m2 = m2_5b; //Get safe Vd2 cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); vd2_safe = cresult[0]; //Get max Vd2 drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); //Loop on M1 with nominal M2 m1_5b = m1_low; message("Loop on M1: -7.0 to -4.0"); while(m1_5b <= m1_high) { //Vector scan at these settings Vector_scan_w_M1M2D2_block_fm(band,lo_freq,m1_5b,nominal_m2,vd2_min); message(band + ", " + lo_freq + ", " + m1_5b + ", " + nominal_m2 + ", " + drain2_bluemax); //next step m1_5b = m1_5b + m1_step; } lo_freq = lo_freq + lo_freq_step; } //end of freq loop //Set nominal settings back - use safe Vd2 LCU_config_w_M1M2D2_block_fm(band,lo_freq - lo_freq_step,nominal_m1,nominal_m2,vd2_safe); } // mois_comment("At the end of this test, the standard LCU safety table should be uploaded again."); } // Interpolate differential sky chop Allan time and exponent double[] procedure InterpolateSpecChopAllan { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency bool subband = false; // 1GHz bandwith reference instead of full IF }{ // subband is not used yet double[] allan = CalibrationReader("chop_Allan",["spec_Allan_time","spec_Allan_exp","spec_binning_exp"],band,lo_freq); return allan; } // IF gain and noise temperature, procedure procedure IFcalibration { string band = "1a"; // HIFI band int integ_time = 4; //Total integration time in sec.: at least 2sec ! string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ HKrate(1.0); //Get biases. No LO freq. given here. {double,string}[] result = ConfigurationReader("name_confilfpu",["bias_low_resistive_h","bias_high_resistive_h","bias_low_resistive_v","bias_high_resistive_v"],band,0.0); double bias_low_h = result[0]{0}; double bias_high_h = result[1]{0}; double bias_low_v = result[2]{0}; double bias_high_v = result[3]{0}; //Set magnets to 0 Set_Magnet_current_block_fm(0.0,0.0); // Spectra_resistive_low_fm(band,bias_low_h,bias_low_v,integ_time,backend); Spectra_resistive_high_fm(band,bias_high_h,bias_high_v,integ_time,backend); //Back to normal bias and normal magnets //Need a representative frequency: take keyfreq double[] result_d = CalibrationReader("name_keyfreq",["keyfreq"],band,0.0); double lo_freq = result_d[0]; result = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v","norm_bias_h","norm_bias_v"],band,lo_freq); double magnet_h = result[0]{0}; double magnet_v = result[1]{0}; double bias_h = result[2]{0}; double bias_v = result[3]{0}; Mixerbias_block_fm(bias_h,bias_v); Set_Magnet_current_block_fm(magnet_h,magnet_v); } // Function computing HRS LO for SPACON check message procedure Check_HRS_LO_proc_ops { string[] hrs_mode = ["wb","wb"]; //HRS resolution mode for both polar: hr, mr, lr, wb double hrh_up_ol1 = 4.5; // IF1 frequency for H-polar double hrh_up_ol2 = 4.5; // IF2 frequency for H-polar double hrh_up_ol3 = 4.5; // IF3 frequency for H-polar double hrh_up_ol4 = 4.5; // IF4 frequency for H-polar double hrh_down_ol5 = 10.5; // LO5 frequency for H-polar double hrh_down_ol6 = 1.25; // LO6 frequency for H-polar double hrh_down_ol7 = 490.0; // LO7 frequency for H-polar double hrv_up_ol1 = 4.5; // IF1 frequency for V-polar double hrv_up_ol2 = 4.5; // IF2 frequency for V-polar double hrv_up_ol3 = 4.5; // IF3 frequency for V-polar double hrv_up_ol4 = 4.5; // IF4 frequency for V-polar double hrv_down_ol5 = 10.5; // LO5 frequency for V-polar double hrv_down_ol6 = 1.25; // LO6 frequency for V-polar double hrv_down_ol7 = 490.0; // LO7 frequency for V-polar }{ //Initialize array //Defaults are: lo1=13, lo2=14, lo3=15, lo4=16 GHz int[] a_m_parameter = [0,64,0,64,0,64,0,64,5,51,0,49,7,0,64,0,64,0,64,0,64,5,51,0,49,7]; int[] a_m = [0,0]; // //The number of A and M parameters to compute depends on the mode // //First rename LO7 and convert to GHz double flo7_h = hrh_down_ol7 / 1000.0; double flo7_v = hrv_down_ol7 / 1000.0; //Initialize freq. double flo_u1_h = 0.0; double flo_u1_v = 0.0; double flo_l2_h = 0.0; double flo_l2_v = 0.0; double flo_u3_h = 0.0; double flo_u3_v = 0.0; double flo_l4_h = 0.0; double flo_l4_v = 0.0; // //Available sub-band width: as of SPR-2479 double bw_h = flo7_h / 2.0 - 0.015; double bw_v = flo7_v / 2.0 - 0.015; //High-Resolution if(hrs_mode[0] == "hr") { //H-polar flo_u1_h = (9.25 - bw_h / 2.0 + hrh_up_ol1) * 1000.0; mois_tmcheck("Check that parameter HRH_LO1_F is " + flo_u1_h + " MHz"); } // if(hrs_mode[1] == "hr") { //V-polar flo_u1_v = (9.25 - bw_v / 2.0 + hrv_up_ol1) * 1000.0; mois_tmcheck("Check that parameter HRV_LO1_F is " + flo_u1_v + " MHz"); } // //Medium-Resolution if(hrs_mode[0] == "mr") { //H-polar flo_u1_h = (9.25 - bw_h / 2.0 + hrh_up_ol1) * 1000.0; flo_l4_h = (9.25 + bw_h / 2.0 + hrh_up_ol4) * 1000.0; mois_tmcheck("Check that parameters HRH_LO1_F and HRH_LO4_F are " + flo_u1_h + " and " + flo_l4_h + " MHz respectively."); } // //Medium-Resolution if(hrs_mode[1] == "mr") { //V-polar flo_u1_v = (9.25 - bw_v / 2.0 + hrv_up_ol1) * 1000.0; flo_l4_v = (9.25 + bw_v / 2.0 + hrv_up_ol4) * 1000.0; mois_tmcheck("Check that parameters HRV_LO1_F and HRV_LO4_F are " + flo_u1_v + " and " + flo_l4_v + " MHz respectively."); } // //Low-Resolution if(hrs_mode[0] == "lr") { //H-polar flo_u1_h = (9.25 - bw_h / 2.0 + hrh_up_ol1) * 1000.0; flo_l2_h = (9.25 + bw_h / 2.0 + hrh_up_ol2) * 1000.0; flo_u3_h = (9.25 - bw_h / 2.0 + hrh_up_ol3) * 1000.0; flo_l4_h = (9.25 + bw_h / 2.0 + hrh_up_ol4) * 1000.0; mois_tmcheck("Check that parameters HRH_LO1_F, HRH_LO2_F, HRH_LO3_F and HRH_LO4_F are " + flo_u1_h + ", " + flo_l2_h + ", " + flo_u3_h + " and " + flo_l4_h + " MHz respectively."); } // //Low-Resolution if(hrs_mode[1] == "lr") { //V-polar flo_u1_v = (9.25 - bw_v / 2.0 + hrv_up_ol1) * 1000.0; flo_l2_v = (9.25 + bw_v / 2.0 + hrv_up_ol2) * 1000.0; flo_u3_v = (9.25 - bw_v / 2.0 + hrv_up_ol3) * 1000.0; flo_l4_v = (9.25 + bw_v / 2.0 + hrv_up_ol4) * 1000.0; mois_tmcheck("Check that parameters HRV_LO1_F, HRV_LO2_F, HRV_LO3_F and HRV_LO4_F are " + flo_u1_v + ", " + flo_l2_v + ", " + flo_u3_v + " and " + flo_l4_v + " MHz respectively."); } // //Wide-Band if(hrs_mode[0] == "wb") { //H-polar flo_u1_h = (9.25 + hrh_up_ol1) * 1000.0; flo_l2_h = (9.25 + hrh_up_ol2) * 1000.0; flo_u3_h = (9.25 + hrh_up_ol3) * 1000.0; flo_l4_h = (9.25 + hrh_up_ol4) * 1000.0; mois_tmcheck("Check that parameters HRH_LO1_F, HRH_LO2_F, HRH_LO3_F and HRH_LO4_F are " + flo_u1_h + ", " + flo_l2_h + ", " + flo_u3_h + " and " + flo_l4_h + " MHz respectively."); } // //Wide-Band if(hrs_mode[1] == "wb") { //V-polar flo_u1_v = (9.25 + hrv_up_ol1) * 1000.0; flo_l2_v = (9.25 + hrv_up_ol2) * 1000.0; flo_u3_v = (9.25 + hrv_up_ol3) * 1000.0; flo_l4_v = (9.25 + hrv_up_ol4) * 1000.0; mois_tmcheck("Check that parameters HRV_LO1_F, HRV_LO2_F, HRV_LO3_F and HRV_LO4_F are " + flo_u1_v + ", " + flo_l2_v + ", " + flo_u3_v + " and " + flo_l4_v + " MHz respectively."); } // //LO5 to LO7 // mois_tmcheck("Check that parameters HRH_LO5_F, HRH_LO6_F and HRH_LO7_F are " + hrh_down_ol5 * 1000.0 + ", " + hrh_down_ol6 * 1000.0 + " and " + hrh_down_ol7 + " MHz respectively."); mois_tmcheck("Check that parameters HRV_LO5_F, HRV_LO6_F and HRV_LO7_F are " + hrv_down_ol5 * 1000.0 + ", " + hrv_down_ol6 * 1000.0 + " and " + hrv_down_ol7 + " MHz respectively."); } // Standing wave analysis, mode // Specific retune case for 2a //HIFI-COP-3-StWv1 obs HifiEng_standing_wave_retune_COP { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band }{ //This is only meant for band 2a if(band != "2a") { error("this test is only meant for band 2a"); } //General parameters in use int freq_index = 1; string los_code = "sc"; string backend = "both"; string[] hrs_mode = ["mr","mr"]; // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Standing_wave_retune_COP_proc_ops(band,backend,hrs_mode,freq_index,los_code)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Standing_wave_noretune_COP_proc_ops(band,backend,hrs_mode,freq_index,los_code); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } // Get system temperatures for a whole array of frequencies double[] procedure GetAllTsys { string band = "4a"; // HIFI band double[] freqgrid = [978200.0,979600.0]; // Grid of frequencies }{ int nstep = length(freqgrid); double[] tsys = []; for(int i = 0 .. nstep - 1) { tsys[i] = InterpolateTsys(band,freqgrid[i]); } return tsys; } //HIFI start up and reboot, mode //Boots, and notify PDU status ON for ICU mode HifiManCmd_startup_and_reboot { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! int partition_ID = 0; //0 if forceboot_default. Partition ID in case it should be used. string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ Mode_status_check_switched_off(); mois_comment("Start of Boot procedure"); mois_step("Power ON the ICU"); string icu_subsys = "ICU_Prime"; if(prime_or_redundant == "Red") { icu_subsys = "ICU_Red"; } PDU_switch_on_block_ops(icu_subsys); mois_step("Force boot ICU"); HIFI_force_boot_block_ops(partition_ID); //check OBS version {double,string}[] result = ConfigurationReader("name_delays",["hi_sw_version","hi_sw_revision","hi_sw_patch"],"0",0.0); int hi_sw_version = iround(result[0]{0}); int hi_sw_revision = iround(result[1]{0}); int hi_sw_patch = iround(result[2]{0}); mois_tmcheck("Check that HI_SW_Version is " + hi_sw_version); mois_tmcheck("Check that HI_SW_Revision is " + hi_sw_revision); mois_tmcheck("Check that HI_SW_Patch is " + hi_sw_patch); // //Get applicable HK rate result = ConfigurationReader("name_delays",["hk_rate"],"0",0.0); double hk_rate = result[0]{0}; // mois_step("Adjust HK data rate."); HKrate_block_ops(hk_rate); //FPU HK needs to be polled mois_step("Notify PDU status for FCU"); HIFI_notify_PDU_status_on_block_ops("ON","OFF","OFF","OFF","OFF","OFF","FCU"); StopMode_block_ops(); // -> to issue last obsd/bbid Mode_status_check_intermediate(); } //Generic procedure to obtain the data-rate computations using DataTaking double[] procedure ILT_datarate_proc_fm { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string chopmode = "tp" in ["tp","slowchop","fastchop","fsw"]; //modulation mode between hot/cold: tp, slowchop, fastchop int integ_time = 8; //TOTAL integration time }{ //Build up backend parameter tupple: {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = BackendSettings(band,0.0,["wb1","wb1"],backend); // //Compute data_time and n_switch using the wrapper if(chopmode == "slowchop" || chopmode == "tp" || chopmode == "fsw") { if(chopmode == "slowchop") { chopmode = "chop"; } if(chopmode == "fsw") { chopmode = "fs"; } int[] res = ConfigSlowChop(integ_time,chopmode,band,0.0,backendreadoutparms); int data_time = res[0]; } if(chopmode == "fastchop") { res = ConfigFastChop(integ_time,1.0,band,0.0,backendreadoutparms); data_time = res[0] / 2; } // //Compute data-rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] rates = dataparms{1}; // return rates; } //Set LCU back to standby status without setting any particular LO band, procedure procedure LCU0_standby_proc_fm { string band = "0"; // HIFI band }{ error("This module is obsolete: use LCU_standby_proc_fm instead"); } //LO parameter scan without HotCold measurement procedure LCU_power_scan_without_Tsys { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4 double lo_freq = 500.0; //LO frequency double param_min = 1.0; //Min. of scanned parameter double param_max = 2.0; //Max. of scanned parameter double step_size = 0.1; //Step size string param_name = "D2"; //Code of scanned parameter: M1,M2,G1,G2,D1,D2. }{ //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // cresult = CalibrationReader("name_lcu_safe_values",["d1_v","d2_v"],band,lo_freq); double drain1_safe = cresult[0]; double drain2_safe = cresult[1]; // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1_v = result[0]{1}; string curlim2_v = result[1]{1}; // result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); // //First set to nominal values HIFI_Configure_LCU_block_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_safe,curlim1_v,drain2_safe,curlim2_v,macro_checksum,config_lo_delay); // double current_param = param_min; //Loop up on parameter of interest, all other values set to //optimum value at the frequency of interest. while(current_param <= param_max) { //Identify parameter to be scanned. if(param_name == "M1") { m1_v = current_param; } if(param_name == "M2") { m2_v = current_param; } if(param_name == "G1") { gate1_v = current_param; } if(param_name == "G2") { gate2_v = current_param; } if(param_name == "D1") { drain1_v = current_param; } if(param_name == "D2") { drain2_v = current_param; } HIFI_Configure_LCU_block_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum,config_lo_delay); current_param = current_param + step_size; // } //Back to nominal values result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); plevel_v = result[0]{0}; m1_v = result[1]{0}; m2_v = result[2]{0}; m3_v = result[3]{0}; d2_step = iround(result[4]{0}); // cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); gate1_v = cresult[0]; gate2_v = cresult[1]; drain1_v = cresult[2]; drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); freq_nx = iround(result[0]{0}); //Compute lsu_main and offset resu = ComputeLSU_A_M_R(band,lo_freq); lsu_main = resu[0]; lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); macro_checksum = iround(result[0]{0}); // HIFI_Configure_LCU_block_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_safe,curlim1_v,drain2_safe,curlim2_v,macro_checksum,config_lo_delay); // } //HIFI-FCP-HC1: chopper health check#2 obs HifiEng_Chopper_FT2_COP { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Chopper_FT2_COP_proc_ops(prime_or_redundant)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Chopper_FT2_COP_proc_ops(prime_or_redundant); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } // Needs the chopper in open-loop mode !! block Chopper_openloop_set_block_fm HIFI 3693 { int position = 0 in [0,1]; }{ //Start_block (); int rot = 2048 + 70 * position; HIFI_CPR_Chopper_Rot_RAW_proc_fm(rot); //Rotate chopper Hifi_HIFI_non_periodic_hk_FCU(); //To get sent value delay(2); } // Procedure to compute all parameters needed in a Configure_spectroscopy // This is a special version for IST, not to be used in normal AOTs // see HIFI SCRs 1029 and 1483 {int,int,int,int,int,int,int,int,int,int} procedure ConfigureSpectroscopyParams_IST { /* Integration time */ int data_time = 4; // Integration time between two data readouts int n_data = 2; // Integration time counter /* Parameters determining the delays - used in calibration reader */ string chopmode = "chop" in ["chop","lchop","fs","hot-cold","tp","chopcal"]; // Chop mode determining the modulation dead time string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency /* Backend settings */ {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // HRS1/2 {used,resolution,subbands used}, WBS1/2 {used,channel windows} }{ // Get fixed parameters from configuration and calibration files // Command jitter time is the default delay {double,string}[] result = ConfigurationReader("name_delays",["add_jitter"],band,lo_freq); int add_jitter = iround(result[0]{0}); // WBS delta time // Default total power. This should be 0. int del_wbs = add_jitter; // WBS delta time given by switch dead time if(chopmode == "chop") { double res = GetSkyChopDeadTime(band,lo_freq); del_wbs = iceil(res * 1000.0); } if(chopmode == "lchop") { res = GetLoadChopDeadTime(band,lo_freq); del_wbs = iceil(res * 1000.0); } if(chopmode == "fs") { res = GetFSwitchDeadTime(band,lo_freq); del_wbs = iceil(res * 1000.0); } if(chopmode == "chopcal") { res = GetHotColdDeadTime(band,lo_freq); del_wbs = iceil(res * 1000.0); } if(chopmode == "hot-cold") { bool wbsused = backendreadoutparms{2}{0} || backendreadoutparms{3}{0}; res = HotColdRelaxTime(band,lo_freq,wbsused); del_wbs = iceil(res * 1000.0); } // HRS delta time - should be zero as well int del_hrs = add_jitter; // Additional delays in the readout loops - given in OBS user manual result = ConfigurationReader("name_delays",["add_hrs","add_wbs","add_jitter","wbs_init","wbs_chunksize","tacc_add","hrs_phase","min_wbs_acc","stdchop_phase"],band,lo_freq); int add_hrs = iround(result[0]{0}); int add_wbs = iround(result[1]{0}); int wbs_init = iround(result[3]{0}); int wbs_chunksize = iround(result[4]{0}); int tacc_add = iround(result[5]{0}); int hrs_phase = iround(result[6]{0}); // HRS standard phase length int min_wbs_acc = iround(result[7]{0}); // WBS transfer time int stdchopphase = iround(result[8]{0}); // Split total integration time int tint = data_time * n_data * 1000; int n_wbs_integr = data_time * 1000 / stdchopphase; // dead time has to be an integer multiple of the 10ms chunk time int tdead = del_wbs + add_wbs + add_jitter; int nchunk = (tdead - 1) / wbs_chunksize + 1; int tcorr = nchunk * wbs_chunksize - tdead; del_wbs = del_wbs + tcorr; tdead = tdead + tcorr; // Accumulation time // Ignores that total power can be slightly more efficient int t_acc_wbs = (tint - wbs_init) / (n_data * n_wbs_integr) - tdead; // discretize in 10ms chunks nchunk = (t_acc_wbs - tacc_add) / wbs_chunksize; t_acc_wbs = nchunk * wbs_chunksize + tacc_add; // Check relative to minimum accumulation tim if(t_acc_wbs + del_wbs + add_wbs < min_wbs_acc + add_jitter) { SError("WBS integration too short for readout. Increase duration."); } int n_wbs_start = n_data * n_wbs_integr; // HRS int hrs_fullphase = hrs_phase + del_hrs + add_hrs; int r_hrs = (t_acc_wbs + hrs_fullphase - add_jitter) / hrs_fullphase; int t_acc_hrs = (t_acc_wbs - add_jitter) / r_hrs - del_hrs - add_hrs; // for n_wbs_integr=1 identical to r_hrs int n_hrs_integr = r_hrs * n_wbs_integr; // Compute actual integration time and dead time per readout // If WBS is used count only the WBS time if(backendreadoutparms{2}{0} || backendreadoutparms{3}{0}) { int tint_act = nchunk * wbs_chunksize * n_data * n_wbs_integr; tdead = tdead + tacc_add; } else { tint_act = t_acc_hrs * r_hrs * n_data * n_wbs_integr; tdead = tdead + r_hrs * (del_hrs + add_hrs) + add_jitter; } // Return all config_spectroscopy timing parameters return {n_wbs_start,r_hrs,n_wbs_integr,n_hrs_integr,del_hrs,del_wbs,t_acc_wbs,t_acc_hrs,tdead,tint_act}; } // WBS attenuator tuning, block // Both polarizations are treated block WBS_tune_block_fm HIFI 3603 { string band = "1a"; // HIFI band int tune_target = 80 in [10,85]; //target illumination percentage }{ //Start_block(); // //Tune attenuators. Hifi_HIFI_Tune_WBS($BBID,tune_target); //Get delay {double,string}[] result_d = ConfigurationReader("name_delays",["wbs_tune_delay"],band,0.0); int wbs_tune_delay = iround(result_d[0]{0}); delay(wbs_tune_delay); // } //Force boot, block block HIFI_force_boot_block_fm HIFI 3600 { int partition_ID = 0; //0 if forceboot_default. Partition ID in case it should be used. }{ if(partition_ID == 0) { Hifi_HIFI_force_bootdefault(); } else { Hifi_HIFI_force_bootpartition(partition_ID); } //Increase delay - SPR-1354 delay(5); //This is not standard practice but here we can only start //to stamp HKs with obsid/bbid pair after ICU is up and running Start_block_no_hk_request(); } //TM check when intermediate procedure Mode_status_check_intermediate { }{ mois_comment("Checking instrument status in intermediate mode"); //Get applicable HK rate {double,string}[] result_d = ConfigurationReader("name_delays",["hk_rate"],"0",0.0); string hk_rate = result_d[0]{1}; mois_tmcheck("Check that HIFI telemetry packets (3,25,1025)- HIFI_PERIODIC_HK - are arriving at a " + hk_rate + " rate."); } // General version used in non-spectral scan FSW modes procedure DoubleLoadMeasurement { string band = "4a"; // HIFI band (needed to estimate stabilization) double lo_freq = 978200.0; // LO frequency double freq_throw = -40.0; // throw of frequency switch in MHz double deltanu = 1.0; // minimum effective resolution of the calibrated data int data_time = 4; // time between subsequent data readouts {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // Readout parameters for HRS1,HRS2, WBS1,WBS2 }{ // Call generic version with fixed parameters SScanDoubleLoadMeasurement(band,lo_freq,lo_freq,freq_throw,true,deltanu,data_time,backendreadoutparms); } // Get dead time for chopper motion between HBB and CBB double procedure GetHotColdDeadTime { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency }{ double[] dead = CalibrationReader("hotcold_deadtime",["hotcold"],band,lo_freq); return dead[0]; } // HRS complete configuration with minimum attenuation, block // Both polarizations are treated block HRS_config_min_att_block_fm HIFI 3635 { string band = "1a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code }{ //Start_block(); // Fetch HRS configuration parameters //=================================== //H-polar string hrs_filename_h = "name_confighrs_" + hrs_mode[0]; {double,string}[] result = ConfigurationReader(hrs_filename_h,["hrh_switch","hrh_1u_att","hrh_1l_att","hrh_2u_att","hrh_2l_att","hrh_3u_att","hrh_3l_att","hrh_4u_att","hrh_4l_att","hrh_up_ol1","hrh_up_ol2","hrh_up_ol3","hrh_up_ol4","hrh_down_ol5","hrh_down_ol6","hrh_down_ol7"],band,0.0); string hrs_polarization_h = result[0]{1}; double[] hrsH_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; //V-polar string hrs_filename_v = "name_confighrs_" + hrs_mode[1]; result = ConfigurationReader(hrs_filename_v,["hrv_switch","hrv_1u_att","hrv_1l_att","hrv_2u_att","hrv_2l_att","hrv_3u_att","hrv_3l_att","hrv_4u_att","hrv_4l_att","hrv_up_ol1","hrv_up_ol2","hrv_up_ol3","hrv_up_ol4","hrv_down_ol5","hrv_down_ol6","hrv_down_ol7"],band,0.0); string hrs_polarization_v = result[0]{1}; double[] hrsV_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; // result = ConfigurationReader("name_delays",["hrs_config_delay"],band,0.0); int hrs_config_delay = iround(result[0]{0}); //Convert IF frequencies into A and M parameters //Truncate wb or hr keyword: string[] output_hrs_mode = GetHrsMode_proc_fm(hrs_mode); string hrs_mode_h = output_hrs_mode[0]; string hrs_mode_v = output_hrs_mode[1]; // int[] a_m_parameter = ComputeA_M_parameters([hrs_mode_h,hrs_mode_v],hrsH_LO[0],hrsH_LO[1],hrsH_LO[2],hrsH_LO[3],hrsH_LO[4],hrsH_LO[5],hrsH_LO[6],hrsV_LO[0],hrsV_LO[1],hrsV_LO[2],hrsV_LO[3],hrsV_LO[4],hrsV_LO[5],hrsV_LO[6]); //H-polar int hrh_up_ol1_m = a_m_parameter[1]; int hrh_up_ol1_a = a_m_parameter[0]; int hrh_up_ol2_m = a_m_parameter[3]; int hrh_up_ol2_a = a_m_parameter[2]; int hrh_up_ol3_m = a_m_parameter[5]; int hrh_up_ol3_a = a_m_parameter[4]; int hrh_up_ol4_m = a_m_parameter[7]; int hrh_up_ol4_a = a_m_parameter[6]; int hrh_down_ol5_m = a_m_parameter[9]; int hrh_down_ol5_a = a_m_parameter[8]; int hrh_down_ol6_m = a_m_parameter[11]; int hrh_down_ol6_a = a_m_parameter[10]; int hrh_down_ol7_m = a_m_parameter[12]; //V-polar //V-polar int hrv_up_ol1_m = a_m_parameter[14]; int hrv_up_ol1_a = a_m_parameter[13]; int hrv_up_ol2_m = a_m_parameter[16]; int hrv_up_ol2_a = a_m_parameter[15]; int hrv_up_ol3_m = a_m_parameter[18]; int hrv_up_ol3_a = a_m_parameter[17]; int hrv_up_ol4_m = a_m_parameter[20]; int hrv_up_ol4_a = a_m_parameter[19]; int hrv_down_ol5_m = a_m_parameter[22]; int hrv_down_ol5_a = a_m_parameter[21]; int hrv_down_ol6_m = a_m_parameter[24]; int hrv_down_ol6_a = a_m_parameter[23]; int hrv_down_ol7_m = a_m_parameter[25]; //Attenuators are fixed //H-polar double hrh_1u_att = 0.0; double hrh_1l_att = 0.0; double hrh_2u_att = 0.0; double hrh_2l_att = 0.0; double hrh_3u_att = 0.0; double hrh_3l_att = 0.0; double hrh_4u_att = 0.0; double hrh_4l_att = 0.0; //V-polar double hrv_1u_att = 0.0; double hrv_1l_att = 0.0; double hrv_2u_att = 0.0; double hrv_2l_att = 0.0; double hrv_3u_att = 0.0; double hrv_3l_att = 0.0; double hrv_4u_att = 0.0; double hrv_4l_att = 0.0; //Configure HRS-H Hifi_HIFI_Config_HRS_H_att_lo($BBID,hrs_polarization_h,hrh_1u_att,hrh_1l_att,hrh_2u_att,hrh_2l_att,hrh_3u_att,hrh_3l_att,hrh_4u_att,hrh_4l_att,hrh_up_ol1_m,hrh_up_ol1_a,hrh_up_ol2_m,hrh_up_ol2_a,hrh_up_ol3_m,hrh_up_ol3_a,hrh_up_ol4_m,hrh_up_ol4_a,hrh_down_ol5_m,hrh_down_ol5_a,hrh_down_ol6_m,hrh_down_ol6_a,hrh_down_ol7_m); //delay(hrs_config_delay); // //Configure HRS-V Hifi_HIFI_Config_HRS_V_att_lo($BBID,hrs_polarization_v,hrv_1u_att,hrv_1l_att,hrv_2u_att,hrv_2l_att,hrv_3u_att,hrv_3l_att,hrv_4u_att,hrv_4l_att,hrv_up_ol1_m,hrv_up_ol1_a,hrv_up_ol2_m,hrv_up_ol2_a,hrv_up_ol3_m,hrv_up_ol3_a,hrv_up_ol4_m,hrv_up_ol4_a,hrv_down_ol5_m,hrv_down_ol5_a,hrv_down_ol6_m,hrv_down_ol6_a,hrv_down_ol7_m); delay(hrs_config_delay); // //Now Configure blocks HRS_config_resol_fm(band,hrs_mode); } //Startblock procedure StartBlock_ops { }{ //This will only be used if the first TC in a block does //not has argument $BBID mois_spacon("In the following command, the second parameter (OBS_ID) shall be replaced by a Formal Parameter value according to the list provided by the instrument ICC."); Hifi_HIFI_Set_OBS_ID($BBID,$OBSID); } //HIFI-COP-3-Tsys obs HifiEng_Tsys_COP { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band }{ //General parameters in use int integ_time = 4; string backend = "both"; string[] hrs_mode = ["wb1","wb1"]; int n_wbs1 = 0; int n_hrs_trans = 0; string chopmode = "slowchop"; //For bands 6 and 7, use wb8 if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { hrs_mode = ["wb8","wb8"]; } // // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Tsys_COP_proc_ops(band,integ_time,backend,hrs_mode,n_wbs1,n_hrs_trans,chopmode)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Tsys_COP_proc_ops(band,integ_time,backend,hrs_mode,n_wbs1,n_hrs_trans,chopmode); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } // LCU configuration AT START-UP into NOMINAL mode, procedure // Uses SFT approach with safe call for 3b, BUT combined TM page dump procedure LCU_switchon_proc_spur { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band }{ //Clear potential failure mode Set_LO_Nominal_block_fm(); // //We use a constant frequency for each band, regardless of the input double lo_freq = 0.0; double[] result_d = CalibrationReader("name_keyfreq",["keyfreq","midfreq","keyfreqwarm","keyfreq_dummy"],band,0.0); lo_freq = result_d[0]; //this is for cold operations // lo_freq = result_d[2]; //this is for warm operations // lo_freq = result_d[3]; //this is for dummy operations ////FM_CUS_11.5: replace keyfreq by the only allowed frequency for warm IST //For band 7b, 1723.5 may be problematic. Take mid freq. instead //if (band == "7b") { // lo_freq = result_d[1]; // } // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_confindex = "name_confindex_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlcutune = "name_configlcutune_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1_v = result[0]{1}; string curlim2_v = result[1]{1}; // result = ConfigurationReader("name_delays",["switch_on_delay","config_lo_delay"],band,lo_freq); int switch_on_delay = iround(result[0]{0}); int config_lo_delay = iround(result[1]{0}); // cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); drain2_v = cresult[0]; //Send command: expect that we have already switched to NOMINAL //We set D2 to best guess and wait some time to stabilize chain temperature HIFI_Configure_LCU_block_spur(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum,switch_on_delay); // //Set heater to their switch-on value HL_heater_block_fm(band,"nominal"); } // WBS stand-by, block block WBS_standby_block_aot HIFI 6703 { string laser = "ON" in ["ON","OFF"]; //laser status: if ON, read from configwbs.config }{ //Set zero ON Hifi_HIFI_switch_zero_WBS_H($BBID,"ON"); Hifi_HIFI_switch_zero_WBS_V($BBID,"ON"); delay(1); //Standby configuration //H-Polarization // {double,string}[] result_d = ConfigurationReader("name_configwbs",["hwh_laser1_s","hwh_laser2_s","hwh_heater","hwh_latchup_s"],"0",0.0); string hwh_laser1_s = result_d[0]{1}; string hwh_laser2_s = result_d[1]{1}; if(laser == "OFF") { hwh_laser1_s = "OFF"; hwh_laser2_s = "OFF"; } int hwh_heater = iround(result_d[2]{0}); string hwh_latchup_s = result_d[3]{1}; // int hwh_att_band4 = 7; int hwh_att_band3 = 7; int hwh_att_band2 = 7; int hwh_att_band1 = 7; int hwh_att_in = 15; // //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); {double,string}[] result = ConfigurationReader("name_delays",["wbs_config_delay"],"0",0.0); int wbs_config_delay = iround(result[0]{0}); //delay(wbs_config_delay); //Wait for configuration to be applied // //V-Polarization // result_d = ConfigurationReader("name_configwbs",["hwv_laser1_s","hwv_laser2_s","hwv_heater","hwv_latchup_s"],"0",0.0); string hwv_laser1_s = result_d[0]{1}; string hwv_laser2_s = result_d[1]{1}; if(laser == "OFF") { hwv_laser1_s = "OFF"; hwv_laser2_s = "OFF"; } int hwv_heater = iround(result_d[2]{0}); string hwv_latchup_s = result_d[3]{1}; // int hwv_att_band4 = 7; int hwv_att_band3 = 7; int hwv_att_band2 = 7; int hwv_att_band1 = 7; int hwv_att_in = 15; // //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); delay(wbs_config_delay); //Wait for configuration to be applied // } ///////////////////////////////////////////////////////////////// // Stability parameters // Interpolate system Allan time and exponent for the selected frequency double[] procedure InterpolateSpecAllan { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency bool subband = false; // 1GHz bandwith reference instead of full IF }{ if(subband) { double[] allan = CalibrationReader("system_Allan_subband",["spec_Allan_time","spec_Allan_exp","spec_binning_exp"],band,lo_freq); } else { allan = CalibrationReader("system_Allan",["spec_Allan_time","spec_Allan_exp","spec_binning_exp"],band,lo_freq); } return allan; } // Drift noise from an OTF sequence // This is still to be scaled by a factor 1.0/(B_fluct*T_A) double procedure OtfDrift { double x = 0.02; // integration time (everything relative to the Allan time) double xr = 0.06; // reference integration time double d1 = 0.3; // time difference between last OFF and point double d2 = 0.3; // time difference between point and next OFF double alpha = 2.5; // drift exponent }{ if(x > 0.0) { // Auxiliary quantities for computation double b1 = alpha - 1.0; double a1 = alpha + 1.0; double l = (d2 + 0.5 * (xr + x)) / (d1 + d2 + xr + x); double ladd = 1.0 - 2.0 * l + 2.0 * l * l; double xi = d1 + d2 + x; // tscan // Now the drift noise variance double y = (-pow(x,b1) - ladd * pow(xr,b1) - l * (1.0 - l) * (pow(2.0 * xr + xi,a1) - 2.0 * pow(xr + xi,a1) + pow(xi,a1)) / (xr * xr) + l * (pow(x + xr + d1,a1) - pow(xr + d1,a1) - pow(x + d1,a1) + pow(d1,a1)) / (xr * x) + (1.0 - l) * (pow(x + xr + d2,a1) - pow(xr + d2,a1) - pow(x + d2,a1) + pow(d2,a1)) / (xr * x)) / (pow(2.0,alpha) - 2.0); } else { // forbid x values <=0 y = 1.0E11 * (1.0 - x); } return y; } ///////////////////////////////////////////////////////////////// // Routines using the generic reader // A possible frequency dependence is hidden behind the reader ///////////////////////////////////////////////////////////////// // Interpolate system temperature for the selected frequency // System temperature is always double sideband system temperature double procedure InterpolateTsys { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency }{ double[] tsys = CalibrationReader("tsys",["tsys_h","tsys_v"],band,lo_freq); double combined = 1.0 / (tsys[0] * tsys[0]) + 1.0 / (tsys[1] * tsys[1]); return 1.0 / sqrt(combined); } //HIFI-COP-1.2-LO_FT obs HifiEng_LO_FT_COP { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(LO_FT_COP_proc_sft(band,prime_or_redundant)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution LO_FT_COP_proc_sft(band,prime_or_redundant); } if(state[0] == 5) { HIFISetHK("normal",true); StopMode_block_ops(); } } } // Get number which is an integer multiple or divisor int procedure IMultiple { int i = 1; // input variable int n = 10; // field size }{ int retval = imax(i,1); if(i > n) { retval = n * (i / n); } else { while(n % retval != 0) { retval = retval - 1; } } return retval; } // LCU6Hb configuration into SAFE mode, procedure procedure LCU6Hb_config_safe_proc_fm { string band = "7b"; // HIFI band double lo_freq = 1800.0 in [1800.0,1910.0]; //LO frequency }{ error("This module is obsolete: use LCU_config_nominal_proc_fm instead"); } // Perform load chop integration at ON position block HIFILoadChopOnIntegration HIFI 6035 { int data_time = 4; // Integration time between two data readouts int n_cycle = 1; // chop cycle number string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double[] rates = [120.0,1.0,2.0]; // Data rates between and during integrations }{ HIFI_Spectr_slow_chop_proc_aot(data_time,n_cycle,band,lo_freq,["chop_cold","chop_M3"],rates); } // Fast-chop procedure HIFI_Spectr_fast_chop_proc_aot { int data_time = 4; // Integration time between two data readouts int n_cycle = 1; // readout cycle number string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz string[] phases = ["chop_M3left","chop_M3right"]; // identifiers for chopper positions int[] parms = [1,0]; // Parameters for chop cycles double[] rates = [120.0,1.0,2.0]; // Data rates between and during integrations }{ //Get appropriate chopper voltages {bool,double,double} chopparms = GetChopVoltages(band,lo_freq,phases[0],phases[1]); bool isPrime = chopparms{0}; // set data rates non_ess_hk_data_rate(rates[2] / 1024.0); data_rate(rates[0] / 1024.0); // Call command if(isPrime) { Hifi_HIFI_P_Spectr_fast_chop($BBID,chopparms{1},chopparms{2},parms[0],parms[1]); } else { Hifi_HIFI_R_Spectr_fast_chop($BBID,chopparms{1},chopparms{2},parms[0],parms[1]); } delay(n_cycle * data_time); // reset data rates non_ess_hk_data_rate(rates[1] / 1024.0); data_rate(0.0); } // HRS partial configuration, block // Configures the LO and attenuators block HRS_config_att_lo_block_fm HIFI 3624 { string band = "1a"; // HIFI band string[] hrs_mode = ["mr","mr"]; //HRS resolution code }{ //Start_block(); // Fetch HRS configuration parameters //=================================== //H-polar string hrs_filename_h = "name_confighrs_" + hrs_mode[0]; {double,string}[] result = ConfigurationReader(hrs_filename_h,["hrh_switch","hrh_1u_att","hrh_1l_att","hrh_2u_att","hrh_2l_att","hrh_3u_att","hrh_3l_att","hrh_4u_att","hrh_4l_att","hrh_up_ol1","hrh_up_ol2","hrh_up_ol3","hrh_up_ol4","hrh_down_ol5","hrh_down_ol6","hrh_down_ol7"],band,0.0); string hrs_polarization_h = result[0]{1}; double hrsH_ATT_U1 = result[1]{0}; double hrsH_ATT_L1 = result[2]{0}; double hrsH_ATT_U2 = result[3]{0}; double hrsH_ATT_L2 = result[4]{0}; double hrsH_ATT_U3 = result[5]{0}; double hrsH_ATT_L3 = result[6]{0}; double hrsH_ATT_U4 = result[7]{0}; double hrsH_ATT_L4 = result[8]{0}; double[] hrsH_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; //V-polar string hrs_filename_v = "name_confighrs_" + hrs_mode[1]; result = ConfigurationReader(hrs_filename_v,["hrv_switch","hrv_1u_att","hrv_1l_att","hrv_2u_att","hrv_2l_att","hrv_3u_att","hrv_3l_att","hrv_4u_att","hrv_4l_att","hrv_up_ol1","hrv_up_ol2","hrv_up_ol3","hrv_up_ol4","hrv_down_ol5","hrv_down_ol6","hrv_down_ol7"],band,0.0); string hrs_polarization_v = result[0]{1}; double hrsV_ATT_U1 = result[1]{0}; double hrsV_ATT_L1 = result[2]{0}; double hrsV_ATT_U2 = result[3]{0}; double hrsV_ATT_L2 = result[4]{0}; double hrsV_ATT_U3 = result[5]{0}; double hrsV_ATT_L3 = result[6]{0}; double hrsV_ATT_U4 = result[7]{0}; double hrsV_ATT_L4 = result[8]{0}; double[] hrsV_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; // result = ConfigurationReader("name_delays",["hrs_config_delay"],band,0.0); int hrs_config_delay = iround(result[0]{0}); //Convert IF frequencies into A and M parameters //Truncate wb or hr keyword: string[] output_hrs_mode = GetHrsMode_proc_fm(hrs_mode); string hrs_mode_h = output_hrs_mode[0]; string hrs_mode_v = output_hrs_mode[1]; // int[] a_m_parameter = ComputeA_M_parameters([hrs_mode_h,hrs_mode_v],hrsH_LO[0],hrsH_LO[1],hrsH_LO[2],hrsH_LO[3],hrsH_LO[4],hrsH_LO[5],hrsH_LO[6],hrsV_LO[0],hrsV_LO[1],hrsV_LO[2],hrsV_LO[3],hrsV_LO[4],hrsV_LO[5],hrsV_LO[6]); //H-polar int hrsH_LO1_M = a_m_parameter[1]; int hrsH_LO1_A = a_m_parameter[0]; int hrsH_LO2_M = a_m_parameter[3]; int hrsH_LO2_A = a_m_parameter[2]; int hrsH_LO3_M = a_m_parameter[5]; int hrsH_LO3_A = a_m_parameter[4]; int hrsH_LO4_M = a_m_parameter[7]; int hrsH_LO4_A = a_m_parameter[6]; int hrsH_LO5_M = a_m_parameter[9]; int hrsH_LO5_A = a_m_parameter[8]; int hrsH_LO6_M = a_m_parameter[11]; int hrsH_LO6_A = a_m_parameter[10]; int hrsH_LO7_M = a_m_parameter[12]; Hifi_HIFI_Config_HRS_H_att_lo($BBID,hrs_polarization_h,hrsH_ATT_U1,hrsH_ATT_L1,hrsH_ATT_U2,hrsH_ATT_L2,hrsH_ATT_U3,hrsH_ATT_L3,hrsH_ATT_U4,hrsH_ATT_L4,hrsH_LO1_M,hrsH_LO1_A,hrsH_LO2_M,hrsH_LO2_A,hrsH_LO3_M,hrsH_LO3_A,hrsH_LO4_M,hrsH_LO4_A,hrsH_LO5_M,hrsH_LO5_A,hrsH_LO6_M,hrsH_LO6_A,hrsH_LO7_M); // //delay(hrs_config_delay); //V-polar int hrsV_LO1_M = a_m_parameter[14]; int hrsV_LO1_A = a_m_parameter[13]; int hrsV_LO2_M = a_m_parameter[16]; int hrsV_LO2_A = a_m_parameter[15]; int hrsV_LO3_M = a_m_parameter[18]; int hrsV_LO3_A = a_m_parameter[17]; int hrsV_LO4_M = a_m_parameter[20]; int hrsV_LO4_A = a_m_parameter[19]; int hrsV_LO5_M = a_m_parameter[22]; int hrsV_LO5_A = a_m_parameter[21]; int hrsV_LO6_M = a_m_parameter[24]; int hrsV_LO6_A = a_m_parameter[23]; int hrsV_LO7_M = a_m_parameter[25]; Hifi_HIFI_Config_HRS_V_att_lo($BBID,hrs_polarization_v,hrsV_ATT_U1,hrsV_ATT_L1,hrsV_ATT_U2,hrsV_ATT_L2,hrsV_ATT_U3,hrsV_ATT_L3,hrsV_ATT_U4,hrsV_ATT_L4,hrsV_LO1_M,hrsV_LO1_A,hrsV_LO2_M,hrsV_LO2_A,hrsV_LO3_M,hrsV_LO3_A,hrsV_LO4_M,hrsV_LO4_A,hrsV_LO5_M,hrsV_LO5_A,hrsV_LO6_M,hrsV_LO6_A,hrsV_LO7_M); // delay(hrs_config_delay); } // Operating the shutter from a procedure procedure Shutter_rotate_proc_fm { string shutter_state = "open" in ["open","closed"]; //Shutter state: open or closed }{ //HifiIltEgse_FPU_set_shutter($BBID,shutter_state); delay(1); } // Get frequency resolution needed to measure standing wave pattern // in frequency switch measurements // // This might actually depend on the frequency throw, but no information // is available. Thus a restructuring of this routine is probable. // double procedure GetFSwitchSWResolution { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency }{ double[] dead = CalibrationReader("fsswresolution",["resolution"],band,lo_freq); return dead[0]; } //HIFI-COP-1.2-UPC_FT procedure UPC_FT_COP_proc_ops { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ mois_comment("Start of HIFI Up-converter Functional Test"); mois_comment("Please check that instrument was switched on with the " + prime_or_redundant + " unit"); //General parameters in use string band = "6a"; double lo_freq = 1568.0; //LO frequency string hbb_heater = "ON"; //hot source on/off string chopper_loop = "CLOSE"; // string chop_startup_prime_red = "chop_startup_cold_prime"; if(prime_or_redundant == "Red") { chop_startup_prime_red = "chop_startup_cold_red"; } {double,string}[] result = ConfigurationReader("name_chopper",[chop_startup_prime_red],"0",0.0); if(chopper_loop == "OPEN") { result = ConfigurationReader("name_chopper",["chop_startup_warm"],"0",0.0); } // mois_step("Init FPU"); Init_MSA_ops(band,chopper_loop,lo_freq,result[0]{0},hbb_heater,prime_or_redundant); mois_tmcheck("Check that parameter HF_DH1_MXBAND and HF_DV1_MXBAND are both 6"); // mois_step("Take WBS spectrum with high biases"); //Use high biases result = ConfigurationReader("name_confilfpu",["bias_high_resistive_h","bias_high_resistive_v"],band,lo_freq); Mixerbias_block_fm(result[0]{0},result[1]{0}); mois_tmcheck("Check that parameters HF_AH1_MXBIAS_V and HF_AV1_MXBIAS_V are set to " + result[0]{0} + " and " + result[1]{0} + " mV respectively"); //Take WBS spectrum via tuning WBS_tune_proc_fm(band); //To check final attenuator settings string backend = "wbs"; int integ_time = 4; Configure_Spectrometer_proc_fm(band,integ_time,["wb1","wb1"],backend); Spectro_total_power_block_fm(band,[integ_time,1],backend); // } //Check consistency between band and frequency inputs //Should be invoked at the beginning of every mode ! bool procedure Check_Band_vs_WarmFreq_proc_fm { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency }{ bool go_ahead_warm = true; //only limited amount of frequencies allowed in config files if(lo_freq >= 1116.0) { //Fetch allowed LO frequencies string tab = "configlcu" + band + ".config"; int nb_freq = table_size(tab); double[] allFreq = dcolumn(tab,"freq"); //Check input frequency is within the list int freq_in_list_count = 0; for(int index = 1 .. nb_freq) { if(lo_freq == allFreq[index - 1]) { freq_in_list_count = 1; } } // if(freq_in_list_count == 0) { error("LO frequency not in list of allowed frequencies for warm operations in band " + band); go_ahead_warm = false; } } return go_ahead_warm; } ///////////////////////////////////////////////////////////////// // Procedure to compute detailed timing for the mode // {int,{int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int},double,double} procedure PositionSwitch_post_timing { {int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int} pre_timing = {12,12,13,13,21,11,1800,32,1,1,0,0,false,false,50,0}; // pre_timing parameter list int[] telescopetimes = [300,180,20,1,21,0]; int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF cycles }{ // Get all values from the pre_timing section int inttime = pre_timing{0}; int pointing = pre_timing{2}; int loadlength = pre_timing{4}; int halfloadlength = pre_timing{5}; int load_spacing = pre_timing{6}; int n_loadinterval = pre_timing{7}; bool final_load = pre_timing{12}; int initlength = pre_timing{14}; int dangling = pre_timing{15}; // dummy parameters int n_seq = pre_timing{8}; int n_load = pre_timing{10}; // Get all values from the telescope section int telinit = telescopetimes[1]; // Initial slew time int slewtime = telescopetimes[2]; // Slew time to OFF int longslew = telescopetimes[4]; // Actual slew time for load slew int pointwaittime = telescopetimes[3]; // Idle time between two phases int tend = telescopetimes[5]; // Final deceleration time // treat pointwaittime like an additional slew dead time in cycles slewtime = slewtime + pointwaittime; longslew = longslew + pointwaittime; // Now we can compute the true scan time int scan_time = 2 * pointing + slewtime; // Check for reasonable scan times if(scan_time > load_spacing + slewtime) { SError("Phase length too long relative to load period."); } // Finally I can compute the true load interval n_loadinterval = imax((load_spacing + slewtime) / scan_time,1); // Compute duration of measurement and average scan length // Compute total dead time in one pointing cycle including load overhead int scan_time_long = 2 * pointing + longslew; int n_long = n_cycles / n_loadinterval; int looplength = (n_cycles - n_long) * scan_time + n_long * scan_time_long; double tscan = double(looplength) / double(n_cycles); // Get pointing dead time, instrument dead time is added later double tdead = tscan - double(2 * inttime); // Determine need for final load measurement double rest = double(n_cycles % n_loadinterval) + 0.5; final_load = rest > 0.5001 * double(n_loadinterval); // Add dangling load time if(final_load) { dangling = loadlength; } int closelength = duration(HIFICloseObs()); dangling = imax(dangling + closelength - tend,0); // Compute total duration, remove pointwaittime for last slew // The initial time is no longer contained in the total time //int totaltime=imax(initlength,telinit); int totaltime = looplength + dangling - pointwaittime + tend; // show gyro-propagation messages GCPMessages(pointing,2 * scan_time_long,tend); // Return all the times needed in the telescope and instrument modules return {totaltime,{inttime,inttime,pointing,pointing,loadlength,halfloadlength,load_spacing,n_loadinterval,n_seq,n_seq,n_load,n_load,final_load,final_load,initlength,dangling},tscan,tdead}; } // Procedure to compute detailed pre timing for the version of the // load chop mode used in LO switch-on {int,int,int,int,int,int} procedure SwitchOnLoadChop_pre_timing { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4 in [1,20]; // data dump interval limited by the data rates bool spectrChop = true; // whether the subsequent AOR is chopped+spectroscopic }{ // Determine parameters of stabilization observation // Get total stabilization time determining the duration of the mode if(spectrChop) { string stabilization = "stabilize_chop"; } else { stabilization = "stabilize_ps"; } double[] tunewait = CalibrationReader("tunetime",[stabilization,"retunelo"],band,lo_freq); int modelength = iceil(tunewait[0]); int retuneinterval = iceil(tunewait[1]); // Normal load-chop-noref pre_timing // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // First perform consistency checks // Check chunk size given by the data rates CheckDataTaking(backendreadoutparms,data_time); int jitterdead = GetMaxTimeJitter(band,lo_freq); // compute load integration time int loadlength = duration(LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms)); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); loadlength = loadlength + readoutdead; // Duration of initial set up int initlength = duration(HIFIInitObs()); // Add time for HK readout int hkduration = duration(HIFISetHK("normal",false)); initlength = initlength + 2 * hkduration; // Get time for actual LO switch-on initlength = initlength + duration(LCU_switchon_proc_aot(band,lo_freq / 1000.0)); // Times for additional actions after LO switch on int addinitlength = loadlength; // Add time for Mixer setup, LO tuning, Deflux addinitlength = addinitlength + duration(Init_Mixing_proc_aot(band,lo_freq / 1000.0)) + duration(Deflux_SingleBand_proc_aot(band,lo_freq / 1000.0)); // Add times for backend tuning string target_name = "normal"; if(wbs1{0} || wbs2{0}) { addinitlength = addinitlength + duration(WBS_attenuators_block(band,lo_freq / 1000.0,target_name,false)); } if(hrs1{0} || hrs2{0}) { addinitlength = addinitlength + duration(HRS_tune_block_aot(band)); } // increase initialization time by additional actions, reduce measurement time initlength = initlength + addinitlength; modelength = modelength - addinitlength; // Second step - LO retuning after 5 minutes if covered int retuneduration = duration(HIFITuneFreq(band,lo_freq,false,"")); if(modelength + addinitlength > retuneinterval) { int modelength1 = imax(retuneinterval - retuneduration - addinitlength,0); int n_cycles1 = imax(modelength1 / (2 * data_time),1); // Get number of cycles needed to cover waiting time modelength = modelength - modelength1 - retuneduration; int n_cycles = imax(modelength / (2 * data_time),1); // Compute parameters for the instrument timing int on_inttime = 2 * (n_cycles + n_cycles1) * data_time + retuneduration + readoutdead; int on_pointing = on_inttime + imax(readoutdead,jitterdead); } else { n_cycles1 = 0; n_cycles = imax(modelength / (2 * data_time),1); on_inttime = 2 * n_cycles * data_time; on_pointing = on_inttime + imax(readoutdead,jitterdead); } // Compute total times int looplength = on_pointing; // dangling load time int dangling = loadlength; int closelength = duration(HIFICloseObs()); dangling = dangling + closelength; // Compute total duration int totaltime = initlength + looplength + dangling; // return resorted data set return {totaltime,on_pointing,initlength,dangling,n_cycles1,n_cycles}; } /////////////////////////////////////// // OBSOLETE: DO NOT USE // Integrate with only backends, block // We take 1 spectrum per phase. block Stability_backend_fastchop_fm HIFI 3418 { }{ Start_block(); error("Stability_backend_fastchop_fm mode is removed. Do not use"); } //HIFI-COP-7-EngInv: Investigation time - placeholder for planning procedure EngInv_COP_proc_ops { int test_duration = 3600; //duration in seconds }{ // delay(test_duration); // } // Diplexer calibration for a given mixer band // uses a list of pre-defined frequencies where to measure // the diplexer scan. Each scan is done at 5 D2 voltage (no LO tuning) procedure Diplexer_calibration_vs_D2_proc_fm { string band = "3" in ["3","4","6","7"]; // HIFI mixer band }{ // //Get the list of frequencies to be used for the scan string tab = "configdipcalib_" + band + ".config"; int total = table_size(tab); double[] freq = []; string[] subband = []; for(int j = 1 .. total) { freq[j] = dlookup(tab,"" + j,"frequency"); subband[j] = slookup(tab,"" + j,"subband"); //Check whether this combination of band+freq is allowed in the current CUS Check_Band_vs_Freq_proc_fm(subband[j],freq[j]); } // //configure FPU Init_MSA_HBB_fm(subband[1],"CLOSE",freq[1],"ON"); //In case of band 6 or 7, use special biases if(band == "6" || band == "7") { {double,string}[] result = ConfigurationReader("name_confilfpu",["bias_dipscan_h","bias_dipscan_v","bias_max_h","bias_max_v"],subband[1],freq[1]); //First go to 4mV Mixerbias_block_fm(result[2]{0},result[3]{0}); //Then to 3mV Mixerbias_block_fm(result[0]{0},result[1]{0}); } // string current_subband = "0"; //Start loop on diplexer scans for(int i = 1 .. total) { //First check whether one needs to switch on another LO band if(subband[i] != current_subband) { LCU_switchon_proc_fm(subband[i]); //Wait an extra delay of 1 min for short term stabilization delay(60); current_subband = subband[i]; } //Diplexer scan parameters double diplexer_current_min_h = -2.24; double diplexer_current_max_h = 2.24; double diplexer_current_step = -0.073; //i.e. approx 4.48/61 int n_steps = 61; double stepTime = 0.1; // //Now loop on various D2 voltage to ensure correct pumping //level during at least one scan. We consider 5 to 7 points between //safe value and BLUE MAX string name_confindex = "name_confindex_a"; if(subband[i] == "1b" || subband[i] == "2b" || subband[i] == "3b" || subband[i] == "4b" || subband[i] == "5b" || subband[i] == "6b" || subband[i] == "7b") { name_confindex = "name_confindex_b"; } result = ConfigurationReader(name_confindex,["freq_nx"],subband[i],freq[i]); int freq_nx = ifloor(result[0]{0}); double[] cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],subband[i],0.0); double drain2_safe = cresult[0]; // double drain2_max = Get_BLUE_LIMIT_D2_proc_fm(subband[i],freq[i]); double drain2_v_start = drain2_safe; // //For bands 6 to 7, start above safe value if(band == "6" || band == "7") { drain2_v_start = drain2_safe + 0.45; //i.e. go to 1.7 //Need to check that drain2_v_start has not got above the blue max //If so, the range to scan is not so big so we stick to the safe value //as minimum drain2 for the scan if(drain2_v_start >= drain2_max) { drain2_v_start = drain2_safe; } } // double drain2_V = drain2_v_start; //Configure FPU at that frequency: except for bands 6 and 7, and except first loop if(band != "6" && band != "7" && i != 1) { Init_MSA_fm(subband[i],"CLOSE",freq[i],"ON"); } // //Start loop on D2: number of Vd2 values depends on band int npoints = 5; if(band == "6" || band == "7") { npoints = 7; } for(int ii = 0 .. npoints - 1) { //Set d2 voltage drain2_V = drain2_v_start + double(ii) / double(npoints - 1) * (drain2_max - drain2_v_start); //message(subband[i]+", "+freq[i]+", "+drain2_V+", "+freq_nx+", "+drain2_max); LCU_config_nominal_w_D2_proc_fm(subband[i],freq[i],drain2_V); //Run scan Scan_diplexer_block_fm(subband[i],diplexer_current_max_h,diplexer_current_max_h,diplexer_current_step,n_steps,stepTime); //Run reverse scan Scan_diplexer_block_fm(subband[i],diplexer_current_min_h,diplexer_current_min_h,-1.0 * diplexer_current_step,n_steps,stepTime); //LCU_CLEAR_ERROR_block_fm(); if(band == "6" || band == "7") { //Additional characterisation of mixer current between 3 and 0.6mV bias for 10 diplexer currents string tab2 = "config_HEB_Imix.config"; double bandnb = GetBandCode(subband[i]); double lofreq_imixcal = dlookup(tab2,"" + iround(bandnb),"frequency"); if(freq[i] == lofreq_imixcal && ii == npoints - 1) { HEB_Imix_calibration_block_fm(subband[i],freq[i]); //Get back to 3mV for further frequencies result = ConfigurationReader("name_confilfpu",["bias_dipscan_h","bias_dipscan_v","bias_max_h","bias_max_v"],subband[1],freq[1]); //First go to 4mV Mixerbias_block_fm(result[2]{0},result[3]{0}); //Then to 3mV Mixerbias_block_fm(result[0]{0},result[1]{0}); } } } // } // //In case of band 6 or 7,go back to nominal values if(band == "6" || band == "7") { result = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],subband[1],freq[1]); //First go to 4mV Mixerbias_block_fm(result[0]{0},result[1]{0}); //Then to nominal result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],subband[1],freq[1]); Mixerbias_block_fm(result[0]{0},result[1]{0}); } // } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // CUS scripts for WBS. // WBS FT scripts are found under fm_FT_WBS.cus // // DT - 17-Feb-06 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // The modes //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //modes: see fm_testmodes.cus ///////////////////////////////////////////////////// //Blocks ///////////////////////////////////////////////////// // Switches comb and zero, block block Switch_zero_comb_block_fm HIFI 3717 { string status = "ON" in ["ON","OFF"]; //Status: ON or OFF }{ Hifi_HIFI_Single_cmd($BBID,"HWH_ZERO_ON"); Hifi_HIFI_Single_cmd($BBID,"HWV_ZERO_ON"); Hifi_HIFI_Single_cmd($BBID,"HWH_COMB_ON"); Hifi_HIFI_Single_cmd($BBID,"HWV_COMB_ON"); delay(2); } ////////////////////////////////////////////////////////////////////// // Generic procedure to call a Configure_spectroscopy command // for total power and slow chop observations procedure ConfigureSpectroscopy { /* Integration time */ int data_time = 4; // Integration time between two data readouts int n_data = 2; // Integration time counter /* Parameters determining the delays - used in calibration reader */ string chopmode = "chop" in ["chop","lchop","fs","hot-cold","tp"]; // Chop mode determining the modulation dead time string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency /* Backend settings */ {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // HRS1/2 {used,resolution,subbands used}, WBS1/2 {used,channel windows} }{ // Get timing parameters {int,int,int,int,int,int,int,int,int,int} timing = ConfigureSpectroscopyParams(data_time,n_data,chopmode,band,lo_freq,backendreadoutparms); int n_wbs_start = timing{0}; int r_hrs = timing{1}; int n_wbs_integr = timing{2}; int n_hrs_integr = timing{3}; int del_hrs = timing{4}; int del_wbs = timing{5}; int t_acc_wbs = timing{6}; int t_acc_hrs = timing{7}; // Transfer mode {int,int,int,int,int[],int[],string} backendconfigure = ConfigSpectroscopyBackends(data_time,backendreadoutparms); int wbs_rshift = backendconfigure{0}; int hrs_rshift = backendconfigure{1}; int hrsh_sel = backendconfigure{2}; int hrsv_sel = backendconfigure{3}; int[] wbsh_par = backendconfigure{4}; int[] wbsv_par = backendconfigure{5}; string packing = backendconfigure{6}; // Now call the command Hifi_HIFI_config_spectroscopy($BBID,n_wbs_start,r_hrs,n_wbs_integr,n_hrs_integr,del_hrs,del_wbs,t_acc_wbs,t_acc_hrs,wbsh_par[0],wbsh_par[1],wbsh_par[2],wbsh_par[3],wbsh_par[4],wbsh_par[5],wbsh_par[6],wbsh_par[7],wbsv_par[0],wbsv_par[1],wbsv_par[2],wbsv_par[3],wbsv_par[4],wbsv_par[5],wbsv_par[6],wbsv_par[7],hrs_rshift,wbs_rshift,hrsh_sel,hrsv_sel,packing); // // No delay for a configuration command } // Switch HIFI to primary mode, mode // This only switches the LO to normal mode mode HifiManCmd_HIFI_standbyII_to_primary { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! string laser_H = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-V laser to be set ON string chopper_loop = "OPEN" in ["OPEN","CLOSE"]; //chopper loop status string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ Mode_status_check_standby_II(laser_H,laser_V,chopper_loop,"up",prime_or_redundant); mois_comment("Set HIFI to Primary mode with " + laser_H + " switched on"); // StartMode_block_ops(); //Switch LO to nominal mois_step("Set LOU to normal mode"); Set_LO_Nominal_block_ops(); // StopMode_block_ops(); Mode_status_check_primary(laser_H,laser_V,chopper_loop); } ////////////////////////////////////////////// // Testmodes for COP specific activities // They are usually concatenation of // existing modules, here gathered for // a simpler execution // // Note that it needs update of lastobsids // // DT - 24-01-08 ////////////////////////////////////////////// //HIFI-FCP-HC1: chopper health check#1 obs HifiEng_Chopper_FT1_COP { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Chopper_FT1_COP_proc_ops(prime_or_redundant)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Chopper_FT1_COP_proc_ops(prime_or_redundant); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } // Interpolate differential total power load chop Allan time and exponent double[] procedure InterpolateTpLChopAllan { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency bool subband = false; // 1GHz bandwith reference instead of full IF }{ // subband is not used yet double[] allan = CalibrationReader("loadchop_Allan",["tp_Allan_time","tp_Allan_exp","tp_binning_exp"],band,lo_freq); return allan; } //HIFI vector scan, block //Check vector scan with some default parameters block Vector_scan_block_fm HIFI 3627 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency }{ //Clear potential failure mode Set_LO_Nominal_proc_fm(); // //Start_block(); //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v_start = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); double drain2_safe = cresult[0]; drain2_v_start = drain2_safe; // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // result = ConfigurationReader(name_configlotune,["step_drain2_v","nsteps","step_time"],band,lo_freq); double step_drain2_v = result[0]{0}; int nsteps = iround(result[1]{0}); double step_time = result[2]{0}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // //Load vector scan //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Load_vector_safe_1a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "1b") { //Band 1b Hifi_HIFI_Load_vector_safe_1b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2a") { //Band 2a Hifi_HIFI_Load_vector_safe_2a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2b") { //Band 2b Hifi_HIFI_Load_vector_safe_2b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3a") { //Band 3a Hifi_HIFI_Load_vector_safe_3a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3b") { //Band 3b Hifi_HIFI_Load_vector_nom_3b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "4a") { //Band 4a Hifi_HIFI_Load_vector_safe_4a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "4b") { //Band 4b Hifi_HIFI_Load_vector_safe_4b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "5a") { //Band 5a Hifi_HIFI_Load_vector_nom_5a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "5b") { //Band 5b Hifi_HIFI_Load_vector_nom_5b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6a") { //Band 6a Hifi_HIFI_Load_vector_nom_6a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6b") { //Band 6b Hifi_HIFI_Load_vector_nom_6b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7a") { //Band 7a Hifi_HIFI_Load_vector_nom_7a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7b") { //Band 7b Hifi_HIFI_Load_vector_nom_7b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } // //delay(1); //Execute vector scan Hifi_HIFI_vector_scan($BBID); double time_needed = double(nsteps) * step_time; delay(iround(time_needed + 2.0 + 0.5)); //0.5s added for completion of load_vector //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } // procedure called to get the WBS into standby procedure HifiIntoStandby_II_Dissipate { }{ //LO 3b is switched on in special index string band_dissipate = "3b"; double lofreq_dissipate = 958.0; double[] cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band_dissipate,lofreq_dissipate); double drain2_v = cresult[0]; LCU_config_nominal_w_D2_proc_fm(band_dissipate,lofreq_dissipate,drain2_v); //Will also switch heaters to 4 V // Put heaters explicitly to 4 V HL_heater_block_aot(band_dissipate,"nominal"); //FPU stand-by: HBB is ON, chopper to rest position Init_MSA_aot("0","CLOSE",0.0,true,"ON"); //HRS stand-by -> is superfluous if from stbyI to stbyII HRS_config_max_att_block_aot("0",["wb","wb"]); //WBS stand-by with laser ON WBS_standby_block_aot("ON"); } //Slow chop between sky and CBB, block block Sky_Cold_fm_COP HIFI 3928 { string band = "1a"; int integ_time = 4; //Total integration time for delay computation string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4,etc string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast }{ //Fetch respective chopper angles {double,string}[] result = ConfigurationReader("name_confilfpu",["chop_M3","chop_cold"],band,0.0); double chop_M3 = result[0]{0}; double chop_cold = result[1]{0}; // //Compute data-rate double[] rates = ILT_datarate_proc_fm(band,backend,"slowchop",integ_time); //Take spectrum // set data rates non_ess_hk_data_rate(rates[2] / 1024.0); data_rate(rates[0] / 1024.0); // HIFI_Spectr_slow_chop_proc_fm(chop_cold,chop_M3); Apply_Slow_Chop_delay(integ_time,band,backend); // reset data rates non_ess_hk_data_rate(rates[1] / 1024.0); data_rate(0.0); } // Functional test with unpumped mixer, procedure // This case assumes backend attenuator setting is done procedure FT_unpumped_w_att_setting { string band = "1a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4,etc int integ_time = 4; //Integration time string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ // //Do not switch-off LO, rather, use the 3b-dissipative mode //LCU_switch_off_block_fm(); string band_dissipate = "3b"; double lofreq_dissipate = 958.0; double[] cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band_dissipate,lofreq_dissipate); double drain2_v = cresult[0]; LCU_config_nominal_w_D2_proc_fm(band_dissipate,lofreq_dissipate,drain2_v); // Put heaters explicitly to 4 V HL_heater_block_aot(band_dissipate,"nominal"); //Tune on high resistive bias //Get biases. No LO freq. given {double,string}[] result_d = ConfigurationReader("name_confilfpu",["bias_high_resistive_h","bias_high_resistive_v"],band,0.0); double bias_h = result_d[0]{0}; double bias_v = result_d[1]{0}; //Before applying these high biases, need to set magnets to 0 Set_Magnet_current_block_fm(0.0,0.0); // Mixerbias_block_fm(bias_h,bias_v); // //Backend tuning if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_config_block_fm(band); WBS_calib_fm(band); WBS_tune_proc_fm(band); } if(backend == "hrs" || backend == "both") { HRS_config_block_fm(band,hrs_mode); HRS_tune_block_fm(band); } // //Reconfigure spectrometers integration after tuning Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); //Measure IF noise IFcalibration(band,integ_time,backend); //Set magnet to zero and get IVcurve: only up to band 5 since band6-7 have no magnets if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { //At that stage, the baises and magnets have been set back to nominal values //IV curve with default parameters IVcurve_raw_fm(band); //Set magnet to zero and get IVcurve: only up to band 5 since band6-7 have no magnets IVcurve_with_zero_magnet_fm(band); //Heater Heater_fm(band); //Now sets back the magnet to nominal value //Set magnet to zero and get IVcurve: only up to band 5 since band6-7 have no magnets IVcurve_with_zero_magnet_fm(band); } //IVcurve after defluxing IVcurve_defluxed_fm(band); } //Chopper health check: step#1 procedure Chopper_FT1_COP_proc_ops { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ //Chopper health check: needs to start in open loop double lo_freq = 0.0; double chopper_voltage = 0.0; Init_MSA_ops("0","OPEN",lo_freq,chopper_voltage,"ON",prime_or_redundant); //Go to 2048 RAW Chopper_openloop_set_block_ops(0,prime_or_redundant); //Go to 2118 RAW Chopper_openloop_set_block_ops(1,prime_or_redundant); //Back to 2048 RAW Chopper_openloop_set_block_ops(0,prime_or_redundant); // //Close the loop string chop_startup_prime_red = "chop_startup_cold_prime"; if(prime_or_redundant == "Red") { chop_startup_prime_red = "chop_startup_cold_red"; } {double,string}[] result = ConfigurationReader("name_chopper",[chop_startup_prime_red],"0",0.0); Init_MSA_ops("0","CLOSE",lo_freq,result[0]{0},"ON",prime_or_redundant); } // HRS polar switch test - alternative scenario proposed by PD, block procedure HRS_polar_switch_alternative_proc_fm { string band = "1a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code }{ //some global settings int integ_time = 4; string backend = "hrs"; //First set bias to 5mV Mixerbias_block_fm(5.0,5.0); //Configure HRS with normal switches HRS_config_w_switch_block_fm(band,hrs_mode,["H","V"]); //tune and take spectrum HRS_tune_block_fm(band); Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); Spectro_total_power_block_fm(band,[integ_time,1],backend); //Set bias to 10 and 2 mV resp Mixerbias_block_fm(10.0,2.0); //tune and take spectrum Spectro_total_power_block_fm(band,[integ_time,1],backend); //Swap switches HRS_config_w_switch_block_fm(band,hrs_mode,["V","H"]); //tune and take spectrum HRS_tune_block_fm(band); Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); Spectro_total_power_block_fm(band,[integ_time,1],backend); } // Automatic magnet tuning, block // Also assumes backends are ready // This is to be used in cold context block Magnet_tuning_block_fm HIFI 3609 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b"]; // HIFI band double lo_freq = 522.0; //LO frequency string backend_code = "HRS" in ["WBS","HRS"]; //The backend to be used for tuning int tune_target_magnet = 40 in [10,85]; //Target WBS illumination percentage during magnet tuning }{ Start_block(); //Set mixer bias to special bias for tuning {double,string}[] result = ConfigurationReader("name_confilmix",["bias4magn_h","bias4magn_v","norm_bias_h","norm_bias_v"],band,lo_freq); //For bands 1,2 and 5, we must substract 0.09mV to this value double bias4magnh = result[0]{0}; double bias4magnv = result[1]{0}; if(band == "1a" || band == "1b" || band == "2a" || band == "2b" || band == "5a" || band == "5b") { bias4magnh = bias4magnh - 0.09; bias4magnv = bias4magnv - 0.09; } Mixerbias(bias4magnh,bias4magnv); double normal_bias_h = result[2]{0}; double normal_bias_v = result[3]{0}; // //First set magnets to maximum because of hysteresis result = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,lo_freq); double magnetcurrentmax_H = result[0]{0}; double magnetcurrentmax_V = result[1]{0}; Set_Magnet_current_proc_fm(magnetcurrentmax_H,magnetcurrentmax_V); // //For band5, wait another 5 sec here if(band == "5a" || band == "5b") { delay(5); } //Fetch magnet tuning parameters //Middle of the scan result = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); double h_mx_mg0 = result[0]{0}; double v_mx_mg0 = result[1]{0}; // result = ConfigurationReader("name_configmagtune",["nMagnet","stepT","mx_mg_span"],band,lo_freq); // //Tuning strategy: scan nMagnet points over -span/2 to +span/2% of nominal value //at the frequency of interest int nMagnet = iround(result[0]{0}); double stepT = result[1]{0}; double mx_mg_span = result[2]{0}; double scan_range = mx_mg_span * max(h_mx_mg0,v_mx_mg0) / 100.0; double mx_mg_step = -1.0 * scan_range / double(nMagnet); //Starting scan values h_mx_mg0 = h_mx_mg0 - mx_mg_step * double(nMagnet) / 2.0; v_mx_mg0 = v_mx_mg0 - mx_mg_step * double(nMagnet) / 2.0; // //Set magnets to starting value to do backend tuning Set_Magnet_current_proc_fm(h_mx_mg0,v_mx_mg0); // //Tune attenuators of backends before magnet tuning ///The following is not yet done. Still take as input parameter //result = ConfigurationReader("name_configwbs",["tune_target_magnet"],band,lo_freq); //int tune_target_magnet = iround(result[0]{0}); // //Perform tuning: check which backend shall be used int magtune_delay = 0; if(backend_code == "WBS") { Hifi_HIFI_Tune_WBS($BBID,tune_target_magnet); //Get delay result = ConfigurationReader("name_delays",["wbs_tune_delay"],band,0.0); delay(iround(result[0]{0})); // Hifi_HIFI_Tune_mxmgc_useWBS($BBID,stepT,nMagnet,h_mx_mg0,v_mx_mg0,mx_mg_step); //Compute delay magtune_delay = iceil(1.0 + 0.94 + double(nMagnet) * (stepT + 1.05)) + 1; //according to OBS 4.4: extra second added } else { Hifi_HIFI_Tune_HRS($BBID); //Get delay result = ConfigurationReader("name_delays",["hrs_tune_delay"],band,0.0); delay(iround(result[0]{0})); // Hifi_HIFI_Tune_mxmgc_useHRS($BBID,stepT,nMagnet,h_mx_mg0,v_mx_mg0,mx_mg_step); magtune_delay = iceil(1.0 + 0.072 + double(nMagnet) * (stepT + 0.132)) + 1; //according to OBS 4.4: extra second added } // delay(magtune_delay); //Set mixer bias back to nominal value at frequency of interest Mixerbias(normal_bias_h,normal_bias_v); // } // // Diplexer scan very fast with IF power, block. // Mixer current as function of diplexer current. // Uses the new OBS TC allowing much faster scan. block Scan_diplexer_IF_block_fm HIFI 3255 { string band = "3a"; // HIFI band double diplexer_current_min_h = -2.24; //minimum diplexer current H double diplexer_current_min_v = -2.24; //minimum diplexer current V double diplexer_current_step = 0.1; //maximum diplexer current V int n_steps = 100; //number of steps double stepTime = 0.1; //Step time in seconds double lo_freq = 807.0; //LO frequency }{ // if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { {double,string}[] result = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,lo_freq); double bias_max_h = result[0]{0}; double bias_max_v = result[1]{0}; // result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); double bias_normal_h = result[0]{0}; double bias_normal_v = result[1]{0}; } //Check how many TCs need to be sent int max_step = 20; int nloop = iceil(double(n_steps) / double(max_step)); //Compute number of step for last iteration int last_n_steps = n_steps - (nloop - 1) * max_step; int dipscan_delay = 0; //Send command for HBB position Chopper_Rotation_proc_fm(band,"chop_M3_ang","chop_hot_ang"); // //Preset to first value and wait 1sec (for possible overshoot): already done before HRS tuning //Set_Diplexer_current_proc_fm(diplexer_current_min_h,diplexer_current_min_v); // double diplexer_current_h = diplexer_current_min_h; double diplexer_current_v = diplexer_current_min_v; // for(int i = 1 .. nloop) { n_steps = max_step; if(i == nloop) { n_steps = last_n_steps; } diplexer_current_h = diplexer_current_min_h + double((i - 1) * max_step) * diplexer_current_step; diplexer_current_v = diplexer_current_min_v + double((i - 1) * max_step) * diplexer_current_step; // Hifi_HIFI_scan_diplexer_if($BBID,n_steps,stepTime,diplexer_current_h,diplexer_current_v,diplexer_current_step); //Compute delay dipscan_delay = iceil(1.0 + 0.042 + double(n_steps) * (stepTime + 0.2)); //According to SPR-903 delay(dipscan_delay + 1); } //In case of HEBs, we may have reached oscillation regime at this stage if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { //Exit from oscillation regime Mixerbias(bias_max_h,bias_max_v); Mixerbias(bias_normal_h,bias_normal_v); } //Send command for CBB position Chopper_Rotation_proc_fm(band,"chop_hot_ang","chop_cold_ang"); // //Preset to first value and wait 1sec (for possible overshoot) Set_Diplexer_current_proc_fm(diplexer_current_min_h,diplexer_current_min_v); // diplexer_current_h = diplexer_current_min_h; diplexer_current_v = diplexer_current_min_v; // for(int j = 1 .. nloop) { n_steps = max_step; diplexer_current_h = diplexer_current_min_h + double((j - 1) * max_step) * diplexer_current_step; diplexer_current_v = diplexer_current_min_v + double((j - 1) * max_step) * diplexer_current_step; if(j == nloop) { n_steps = last_n_steps; } Hifi_HIFI_scan_diplexer_if($BBID,n_steps,stepTime,diplexer_current_h,diplexer_current_v,diplexer_current_step); //Compute delay dipscan_delay = iceil(1.0 + 0.042 + double(n_steps) * (stepTime + 0.2)); //According to SPR-903 delay(dipscan_delay + 1); } //In case of HEBs, we may have reached oscillation regime at this stage if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { //Exit from oscillation regime Mixerbias(bias_max_h,bias_max_v); Mixerbias(bias_normal_h,bias_normal_v); } } // Global fast chop spectroscopy for stability measurement, procedure procedure Fast_chop_spectro_for_Stability_proc_fm { string band = "1a"; // HIFI band int n = 100; //The number of integrations int integ_time = 8; //Total integration time in sec. to be set at end of test string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code double chop1 = 3.4; //First chopper position double chop2 = 4.7; //Second chopper position double chop_phase = 1.0 in [0.2,2.0]; // Chop phase length }{ //First derive backend setting codes as expected by VO's routine //Build up backend parameter tupple: {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = BackendSettings(band,0.0,hrs_mode,backend); // Readout parameters for HRS1,HRS2, WBS1,WBS2 //Compute data_time and n_switch using the wrapper int[] res = ConfigFastChop(integ_time,chop_phase,band,0.0,backendreadoutparms); int data_time = res[0]; int n_int = res[2]; int n_data = n; //For stability measurement, the number of loop is a user input // Now call the spectroscopy setup: it is common to ILT and AOT CUS. // The deadtimes output is not used at ILT level. {{double,double,double},{int,int}} pars = ConfigSpectroscopyFastChop(chop_phase,n_int,n_data,band,0.0,backendreadoutparms); int[] final_res = [res[0],res[1],pars{1}{0},pars{1}{1}]; int n_wbs_start = n_data; int n_wbs1 = final_res[2]; int n_hrs_trans = final_res[3]; //Compute data-rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time / 2); double[] rates = dataparms{1}; // set data rates non_ess_hk_data_rate(rates[2] / 1024.0); data_rate(rates[0] / 1024.0); //Now start the long integration HIFI_Spectr_fast_chop_proc_fm(chop1,chop2,n_wbs1,n_hrs_trans); //Apply delays int total_time = iceil(chop_phase * double(n_wbs_start * n_wbs1)); Apply_Fast_Chop_delay(total_time,n_wbs_start,band,backend); // reset data rates non_ess_hk_data_rate(rates[1] / 1024.0); data_rate(0.0); } // Noise ratio from an asymmetric double difference observation double procedure DoubleDifferenceNoiseRatio { double x = 0.1; // value for integration time relative to Allan time double[] parameters = [1.0,1.0,0.8,0.8,0.05,0.3,2.5,5.0,2.5]; // Parameters: ratio of integration times, ratio of effective resolutions, delay in phase1, in phase 2, between phases relative to Allan time, drift exponents }{ {double,double} noisevalues = DoubleDifferenceNoiseValues(x,parameters); double y = noisevalues{1} / noisevalues{0}; return y; } //////////////////////////////////// // OTF frequency switch observing mode // // Return time and noise levels {int,double,double,double,double,double} obs HifiMappingProcFSwitchOTF { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source double raoff = 0.0; // RA coordinate of the OFF position double decoff = 0.0; // DEC coordinate of the OFF position bool refSelected = true; // Dummy parameter required by HSPOT {double,double} lineDistance = {0.0050,0.0050}; // Distance between subsequent rows int nlines = 1 in [1,240]; // Number of rows in the map double stepsize = 0.0050 in [0.0,0.13333]; // Distance between subsequent points in the OTF line int npoints = 10 in [1,720]; // Number of data dumps per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // chunk size given by the data rates and optimum speed int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 1 in [1,1800]; // Supersamplingfactor int n_switch_off = 3 in [1,3600]; // Number of data dumps for the OFF integration time int n_linesperscan = 1 in [1,32]; // Number of lines between two OFFs int n_cycles = 1 in [1,1200]; // Number of map coverages int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Mapping - OTF Map Frequency Switch Ref",{data_time,data_time_off,0,n_switch_on,n_switch_off,n_linesperscan,0,0,n_cycles,load_interval}); // Auxiliary routine for API parameter correction {double,double,int} mapused = ValidMapSize(band,lo_freq,lineDistance,nlines,stepsize,npoints,2 * data_time * n_switch_on); double line_used = mapused{0}; double scanvelocity = mapused{1}; int npoints_used = mapused{2}; // Call first part of the timing computer {int,int,int,int,int,int,int,int} pre_timing = OTFFSwitch_pre_timing(nlines,npoints_used,band,lo_freq,freq_throw,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,n_switch_on,n_switch_off,n_linesperscan,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {double,double} refPosition = {raoff,decoff}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,double,double,int,int,double,double,int,int,int,int,int} tpar = OTFmap_telescope(naifid,onPosition,lineDistance,nlines,line_used,refPosition,scanvelocity,band,lo_freq,n_linesperscan,n_cycles,pre_timing); // Dummy call to spacecraft command int[] telescopetimes = line_scan_with_off_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23}); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int},double,double} post_timing = OTFmap_post_timing(pre_timing,telescopetimes,data_time,n_linesperscan,n_cycles,load_interval); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = OTFmap_telescope(naifid,onPosition,lineDistance,nlines,line_used,refPosition,scanvelocity,band,lo_freq,n_linesperscan,n_cycles,post_timing{1}); // Call telescope command telescopetimes = line_scan_with_off_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23}); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int n_pp = post_timing{1}{0}; int n_scans = post_timing{1}{1}; int off_inttime = post_timing{1}{2}; int loadlength = post_timing{1}{4}; int n_loadinterval = post_timing{1}{5}; double tscan = post_timing{2}; double tdead = post_timing{3}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { OTFFSwitch_commanding(band,lo_freq,freq_throw,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,npoints_used * n_switch_on,n_switch_off,nlines * n_cycles,n_linesperscan,n_loadinterval,startobs,telescopetimes,loadlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double,double,double} tact = OTFDoubleChop_deadtimes("fs",band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,n_switch_on,n_switch_off,n_linesperscan,n_pp,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = OTFFSwitch_noisecomputer(band,lo_freq,effResolution,oneGHzReference,nlines,data_time,n_switch_on,n_linesperscan,off_inttime,n_cycles,tscan,tact); // Evaluate performance OTFDoubleChop_performance(band,lo_freq,effResolution,noisevalues,timeTaken,nlines,npoints_used,n_switch_on,n_switch_off,n_scans,n_cycles,true,tscan,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } /////////////////////////////////////////////////////////////// //// OBSOLETE MODULES /////////////////////////////////////// ////////////////////////////////////////////////////////////// /////////////OBSOLETE: THIS IS NOT USED ANYMORE////////////////////////// //Procedure checking whether the requested integration //time is compliant with the allowed packet/datarate //in Total power spectroscopy context bool procedure Check_Total_Power_datarate { int n_wbs_start = 1; //Nb of frames int r_hrs = 1; //Nb of HRS readout per WBS readout int n_wbs_integr = 1; //Number of wbs readout packetized per WBS frame int n_hrs_integr = 1; //Number of hrs readout packetized per HRS frame int del_hrs = 5; //Delay before starting HRS integration int del_wbs = 5; //Delay before starting WBS integration int t_acc_wbs = 4005; //Duration of WBS frame int t_acc_hrs = 1950; //Duration of HRS frame int wbsh_offset1 = 0; int wbsh_width1 = 2048; int wbsh_offset2 = 2048; int wbsh_width2 = 2048; int wbsh_offset3 = 4096; int wbsh_width3 = 2048; int wbsh_offset4 = 6144; int wbsh_width4 = 2048; int wbsv_offset1 = 0; int wbsv_width1 = 2048; int wbsv_offset2 = 2048; int wbsv_width2 = 2048; int wbsv_offset3 = 4096; int wbsv_width3 = 2048; int wbsv_offset4 = 6144; int wbsv_width4 = 2048; int hrs_rshift = 0; //HRS bit shift int wbs_rshift = 0; //WBS bit shift int hrsh_sel = 255; //HRS-H band selection int hrsv_sel = 255; //HRS-V band selection string wbs_packing = "24_bits_format"; string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3 string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ error("Procedure Check_Total_Power_datarate is not used anymore."); return false; } // Add two vectors defined as tuples {double,double} procedure AddVectors { {double,double} vector1 = {1.0,1.0}; {double,double} vector2 = {1.0,1.0}; }{ return {vector1{0} + vector2{0},vector1{1} + vector2{1}}; } //HIFI vector scan, procedure //Check vector scan with some default parameters procedure Vector_scan_proc_1a { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 570.0; //LO frequency }{ error("This module is obsolete: use Vector_scan_proc instead"); } // Check of Bragg cell heating using internal loads, block block FT_WBS_BraggCell_HotCold_fm HIFI 3712 { string band = "1a"; // HIFI band string laser_H = "Laser1" in ["Laser1","Laser2"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2"]; //WBS-V laser to be set ON int[] att_h = [7,7,7,7,12]; //User input att. for optimum level H-polar int[] att_v = [7,7,7,7,12]; //User input att. for optimum level H-polar int integ_time = 4; //Total integration time in sec. string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); //Look at hot source: force a 2-step rotation Chopper_Rotation_proc_fm(band,"chop_M3_ang","chop_hot_ang"); // //Test continuum signal response //1. Set WBS attenuators to work at nominal level //for the current input (minimum attenuation without saturation) //It practice the CUS cannot read back the optimum settings from //a tuning...instead we consider they are input //Must be done manually... // {double,string}[] result = ConfigurationReader("name_configwbs",["hwh_laser1_s","hwh_laser2_s","hwh_heater","hwh_latchup_s","hwh_att_band4","hwh_att_band3","hwh_att_band2","hwh_att_band1","hwh_att_in"],band,0.0); string hwh_laser1_s = "OFF"; string hwh_laser2_s = "OFF"; if(laser_H == "Laser1") { hwh_laser1_s = "ON"; } if(laser_H == "Laser2") { hwh_laser2_s = "ON"; } int hwh_heater = iround(result[2]{0}); string hwh_latchup_s = result[3]{1}; int hwh_att_band4 = att_h[3]; //iround(result[4]{0}); int hwh_att_band3 = att_h[2]; //iround(result[5]{0}); int hwh_att_band2 = att_h[1]; //iround(result[6]{0}); int hwh_att_band1 = att_h[0]; //iround(result[7]{0}); int hwh_att_in = att_h[4]; //iround(result[8]{0}); // result = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result[0]{0}); // result = ConfigurationReader("name_configwbs",["hwv_laser1_s","hwv_laser2_s","hwv_heater","hwv_latchup_s","hwv_att_band4","hwv_att_band3","hwv_att_band2","hwv_att_band1","hwv_att_in"],band,0.0); string hwv_laser1_s = "OFF"; string hwv_laser2_s = "OFF"; if(laser_V == "Laser1") { hwv_laser1_s = "ON"; } if(laser_V == "Laser2") { hwv_laser2_s = "ON"; } int hwv_heater = iround(result[2]{0}); string hwv_latchup_s = result[3]{1}; int hwv_att_band4 = att_v[3]; //iround(result[4]{0}); int hwv_att_band3 = att_v[2]; //iround(result[5]{0}); int hwv_att_band2 = att_v[1]; //iround(result[6]{0}); int hwv_att_band1 = att_v[0]; //iround(result[7]{0}); int hwv_att_in = att_v[4]; //iround(result[8]{0}); // //2. Configure spectroscopy and do integration: total of 100s with 4s integration Total_power_spectro_for_Stability_proc_fm(band,25,4,backend,["wb1","wb1"]); // //Look at the cold source Chopper_Rotation_proc_fm(band,"chop_hot_ang","chop_cold_ang"); // //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // delay(wbs_config_delay); //Wait for configuration to be applied // //Integrate with the WBS Total_power_spectro_for_Stability_proc_fm(band,25,4,backend,["wb1","wb1"]); // //Look at the hot source Chopper_Rotation_proc_fm(band,"chop_cold_ang","chop_hot_ang"); // //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // delay(wbs_config_delay); //Wait for configuration to be applied // //Integrate with the WBS Total_power_spectro_for_Stability_proc_fm(band,25,4,backend,["wb1","wb1"]); // //Look at the cold source Chopper_Rotation_proc_fm(band,"chop_hot_ang","chop_cold_ang"); // //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // delay(wbs_config_delay); //Wait for configuration to be applied // //Integrate with the WBS Total_power_spectro_for_Stability_proc_fm(band,25,4,backend,["wb1","wb1"]); // //Settling time of COMB //We have to set attenuators to values different from max. //12,3,3,3,3: info from Oliver Sibertz. This may change for FM //Initial configuration //H-Polarization result = ConfigurationReader("name_configwbs",["hwh_laser1_s","hwh_laser2_s","hwh_heater","hwh_latchup_s","hwh_att_band4_comb","hwh_att_band3_comb","hwh_att_band2_comb","hwh_att_band1_comb","hwh_att_in_comb"],band,0.0); hwh_laser1_s = "OFF"; hwh_laser2_s = "OFF"; if(laser_H == "Laser1") { hwh_laser1_s = "ON"; } if(laser_H == "Laser2") { hwh_laser2_s = "ON"; } hwh_heater = iround(result[2]{0}); hwh_latchup_s = result[3]{1}; hwh_att_band4 = iround(result[4]{0}); hwh_att_band3 = iround(result[5]{0}); hwh_att_band2 = iround(result[6]{0}); hwh_att_band1 = iround(result[7]{0}); hwh_att_in = iround(result[8]{0}); // //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); // delay(wbs_config_delay); //Wait for configuration to be applied // //V-Polarization // result = ConfigurationReader("name_configwbs",["hwv_laser1_s","hwv_laser2_s","hwv_heater","hwv_latchup_s","hwv_att_band4_comb","hwv_att_band3_comb","hwv_att_band2_comb","hwv_att_band1_comb","hwv_att_in_comb"],band,0.0); hwv_laser1_s = "OFF"; hwv_laser2_s = "OFF"; if(laser_V == "Laser1") { hwv_laser1_s = "ON"; } if(laser_V == "Laser2") { hwv_laser2_s = "ON"; } hwv_heater = iround(result[2]{0}); hwv_latchup_s = result[3]{1}; hwv_att_band4 = iround(result[4]{0}); hwv_att_band3 = iround(result[5]{0}); hwv_att_band2 = iround(result[6]{0}); hwv_att_band1 = iround(result[7]{0}); hwv_att_in = iround(result[8]{0}); // //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // delay(wbs_config_delay); //Wait for configuration to be applied // //Set Zero and COMB ON Hifi_HIFI_Single_cmd($BBID,"HWH_ZERO_ON"); Hifi_HIFI_Single_cmd($BBID,"HWV_ZERO_ON"); Hifi_HIFI_Single_cmd($BBID,"HWH_COMB_ON"); Hifi_HIFI_Single_cmd($BBID,"HWV_COMB_ON"); delay(2); // //Integrate with the WBS Total_power_spectro_for_Stability_proc_fm(band,25,4,backend,["wb1","wb1"]); // //Still TBD here: [Perform comb measurements for different Bragg cell heat levels] Hifi_HIFI_Single_cmd($BBID,"HWH_COMB_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWV_COMB_OFF"); delay(1); Hifi_HIFI_Single_cmd($BBID,"HWH_ZERO_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWV_ZERO_OFF"); delay(1); //Configure Spectroscopy //Configure_Spectrometer_proc_fm(band,4,["wb1","wb1"]); } //General DC health check, procedure //All inputs are taken from look-up tables using safe values procedure LCU_DC_health_check_proc_fm { string band = "1a" in ["ALL","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band int operation_delay = 60; //When ALL is selected, Waiting delay between two measurements on a band (e.g. to change connector) }{ //Array of names string[] band_array = ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; double hl_PL_C = 0.0; double hl_M1_V = 0.0; double hl_M2_V = 0.0; double hl_M3_V = 0.0; double hl_Gate1_V = 0.0; double hl_Gate2_V = 0.0; double hl_Drain1_V = 0.0; string hl_Curlim1 = "1.5"; double hl_Drain2_V = 0.0; string hl_Curlim2 = "1.5"; // double[] cresult = CalibrationReader("name_lcu_safe_values",["pl_c","m1_v","m2_v","m3_v","g1_v","g2_v","d1_v","d2_v"],"1a",1.0); //Case of all bands done //Fetch LO parameters string name_configlo = "name_configlo_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; } // string band_loop = "1a"; // if(band == "ALL") { //loop on bands for(int i = 1 .. 14) { //Readout safe values cresult = CalibrationReader("name_lcu_safe_values",["pl_c","m1_v","m2_v","m3_v","g1_v","g2_v","d1_v","d2_v"],band_array[i - 1],double(i)); hl_PL_C = cresult[0]; hl_M1_V = cresult[1]; hl_M2_V = cresult[2]; hl_M3_V = cresult[3]; hl_Gate1_V = cresult[4]; hl_Gate2_V = cresult[5]; hl_Drain1_V = cresult[6]; hl_Drain2_V = cresult[7]; // {double,string}[] result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band_array[i - 1],0.0); hl_Curlim1 = result[0]{1}; hl_Curlim2 = result[1]{1}; // LCU_DC_health_check_block_fm(band_array[i - 1],hl_PL_C,hl_M1_V,hl_M2_V,hl_M3_V,hl_Gate1_V,hl_Gate2_V,hl_Drain1_V,hl_Curlim1,hl_Drain2_V,hl_Curlim2); // delay(operation_delay); } } else { //Only one band measured //Readout safe values cresult = CalibrationReader("name_lcu_safe_values",["pl_c","m1_v","m2_v","m3_v","g1_v","g2_v","d1_v","d2_v"],band,0.0); hl_PL_C = cresult[0]; hl_M1_V = cresult[1]; hl_M2_V = cresult[2]; hl_M3_V = cresult[3]; hl_Gate1_V = cresult[4]; hl_Gate2_V = cresult[5]; hl_Drain1_V = cresult[6]; hl_Drain2_V = cresult[7]; // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,0.0); hl_Curlim1 = result[0]{1}; hl_Curlim2 = result[1]{1}; // LCU_DC_health_check_block_fm(band,hl_PL_C,hl_M1_V,hl_M2_V,hl_M3_V,hl_Gate1_V,hl_Gate2_V,hl_Drain1_V,hl_Curlim1,hl_Drain2_V,hl_Curlim2); // delay(operation_delay); } // } // First part of WBS FM functional test, block // Check temperature modification when setting the heaters block FT_WBS_heater_fm HIFI 3700 { string band = "1a"; // HIFI band }{ //Start_block(); //Time to wait after each heater powering int heater_deadtime = 600; //in sec. //Initial configuration //H-Polarization // string hwh_laser1_s = "OFF"; string hwh_laser2_s = "OFF"; int hwh_heater = 0; //000 string hwh_latchup_s = "Level1"; int hwh_att_band4 = 7; int hwh_att_band3 = 7; int hwh_att_band2 = 7; int hwh_att_band1 = 7; int hwh_att_in = 15; // //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); delay(1); // //V-Polarization // string hwv_laser1_s = "OFF"; string hwv_laser2_s = "OFF"; int hwv_heater = 0; //000 string hwv_latchup_s = "Level1"; int hwv_att_band4 = 7; int hwv_att_band3 = 7; int hwv_att_band2 = 7; int hwv_att_band1 = 7; int hwv_att_in = 15; // //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // delay(1); //Start switching heaters: switch on first heater hwh_heater = 1; //001 hwh_heater = 1; //001 // Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); // Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // delay(heater_deadtime); //Switch on second heater hwh_heater = 3; //011 hwh_heater = 3; //011 // Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); // Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // delay(heater_deadtime); //Switch on second heater hwh_heater = 7; //111 hwh_heater = 7; //111 // Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); // Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // delay(heater_deadtime); } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // CUS scripts for HIFI global operations. // It includes: // - SFT // - FT // - VSPT // - System and IF noise measurements // - Standing wave measurements // - Standing wave + stability // // DT - 23-May-06 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // The modes //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // See fm_testmodes.cus //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // The procedures //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //Fast-readout of mixer currents, block block Fast_Imix_block_fm HIFI 3795 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string polarization = "B" in ["H","V","B"]; //mixer to be sampled: H, V or B. If B, they are done successively int milliSecSample = 3; // interval between samples int samplesBefore = 30 in [0,50]; int samplesAfter = 1000 in [0,1000]; }{ // Start_block(); // if(polarization == "H" || polarization == "B") { Hifi_HIFI_MXJNC_H_scan_fast(milliSecSample,samplesBefore,samplesAfter); // delay calculation int nb_HK = 1; //For this TC, the 2 last HK fields are blanked out int millisecondsUsed = 1000 + 10 + milliSecSample * nb_HK * (samplesBefore + samplesAfter); delay(iceil(0.0010 * double(millisecondsUsed)) + 1); } // if(polarization == "V" || polarization == "B") { Hifi_HIFI_MXJNC_V_scan_fast(milliSecSample,samplesBefore,samplesAfter); // delay calculation nb_HK = 1; //For this TC, the 2 last HK fields are blanked out millisecondsUsed = 1000 + 10 + milliSecSample * nb_HK * (samplesBefore + samplesAfter); delay(iceil(0.0010 * double(millisecondsUsed)) + 1); } } //HIFI LO tuning for FSW cases, block //Settings for both frequencies need to be common //and are passed through lo_freq_setting //Target current is read from look-up table block LO_tuning_FSW_block_fm HIFI 3676 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency at which to set LSU double lo_freq_setting = 501.0; //LO frequency at which to take the settings bool fswstorage = true; // whether FSW register shall be stored }{ //Clear potential failure mode if(fswstorage) { Set_LO_Nominal_proc_fm(); } else { delay(1); //to keep timing in OD29/OD30 } //Start_block(); {double,string}[] result = ConfigurationReader("name_confpolar4lotune",[band],band,lo_freq); string mixer_polarization = result[0]{1}; // //Get target mixer current result = ConfigurationReader("name_confilmix",["target_mx_c_h","target_mx_c_v"],band,lo_freq); double target_current = result[0]{0}; if(mixer_polarization == "V") { target_current = result[1]{0}; } if(mixer_polarization == "B") { target_current = 0.5 * (result[1]{0} + result[0]{0}); } // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; name_configlcutune = "name_configlcutune_b"; } // result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq_setting); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // result = ConfigurationReader(name_configlotune,["step_drain2_v","nsteps","step_time"],band,lo_freq); double step_drain2_v = result[0]{0}; int nsteps = iround(result[1]{0}); double step_time = result[2]{0}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // //Adjust scans cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); double drain2_safe = cresult[0]; // double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); // //For all bands, scan will be done with decreasing drain2 voltages //The best guess is taken from look-up table double tune_range = 0.1; result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lo_freq); double middle_d2 = result[0]{0}; double drain2_v_start = min(middle_d2 * (1.0 + tune_range / 2.0),drain2_bluemax); double drain2_v_end = (1.0 - tune_range / 2.0) / (1.0 + tune_range / 2.0) * drain2_v_start; step_drain2_v = (drain2_v_end - drain2_v_start) / double(nsteps - 1); // result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); // //Send command HIFI_Configure_LCU_proc_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,macro_checksum,config_lo_delay); // //delay(5); //to settle at this value // //Load vector scan //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Load_vector_safe_1a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "1b") { //Band 1b Hifi_HIFI_Load_vector_safe_1b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2a") { //Band 2a Hifi_HIFI_Load_vector_safe_2a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2b") { //Band 2b Hifi_HIFI_Load_vector_safe_2b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3a") { //Band 3a Hifi_HIFI_Load_vector_safe_3a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3b") { //Band 3b Hifi_HIFI_Load_vector_nom_3b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "4a") { //Band 4a Hifi_HIFI_Load_vector_safe_4a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "4b") { //Band 4b Hifi_HIFI_Load_vector_safe_4b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "5a") { //Band 5a Hifi_HIFI_Load_vector_nom_5a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "5b") { //Band 5b Hifi_HIFI_Load_vector_nom_5b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6a") { //Band 6a Hifi_HIFI_Load_vector_nom_6a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6b") { //Band 6b Hifi_HIFI_Load_vector_nom_6b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7a") { //Band 7a Hifi_HIFI_Load_vector_nom_7a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7b") { //Band 7b Hifi_HIFI_Load_vector_nom_7b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } // delay(1); // //Execute tuning: check which mixer is to be used if(mixer_polarization == "V") { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCV($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCV($BBID,target_current); } } else { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCH($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCH($BBID,target_current); } } // double time_needed = double(nsteps) * step_time; delay(iround(time_needed + 2.0 + 0.5)); //0.5s added for completion of load_vector // //Store settings into available register HIFI_HL_store_tm_proc_fm(); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } // Diplexer scan, very fast with IF power, procedure // Uses the fast OBS TC procedure Diplexer_scan_IF_proc { string band = "3a" in ["0","3a","3b","4a","4b","6a","6b","7a","7b"]; // HIFI band double diplexer_current_min_h = -2.24; //starting diplexer current H double diplexer_current_min_v = -2.24; //starting diplexer current V double diplexer_current_step = 2.24; //Common diplexer current step int n_steps = 100; //number of steps double stepTime = 0.1; //Step time in seconds: GRANULARITY IS 0.1sec!!!! double lo_freq = 807.0; //LO frequency }{ // //In case of band 6 or 7, use special biases if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { {double,string}[] result = ConfigurationReader("name_confilfpu",["bias_dipscan_h","bias_dipscan_v","bias_max_h","bias_max_v"],band,lo_freq); //First go to 4mV Mixerbias_block_fm(result[2]{0},result[3]{0}); //Then to 3mV Mixerbias_block_fm(result[0]{0},result[1]{0}); } // //Fetch diplexer settings double[] result_dip = Get_Diplexer_setting(band,lo_freq); double diplex_H = result_dip[0]; double diplex_V = result_dip[1]; // //Set diplexers to the starting value to tune HRS Set_Diplexer_current_block_fm(diplexer_current_min_h,diplexer_current_min_v); // HRS_tune_block_fm(band); // //Perform scan Scan_diplexer_IF_block_fm(band,diplexer_current_min_h,diplexer_current_min_h,diplexer_current_step,n_steps,stepTime,lo_freq); // //Get back to optimal settings Set_Diplexer_current_block_fm(diplex_H,diplex_V); // //In case of band 6 or 7,go back to nominal values if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { result = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,lo_freq); //First go to 4mV Mixerbias_block_fm(result[0]{0},result[1]{0}); //Then to nominal result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); Mixerbias_block_fm(result[0]{0},result[1]{0}); } // } //Upload of LCU memory patches //Prime/Redundant is handled with the CUS table //Required as separate flight procedure as total number of command parameters //is limited to 999 mode HifiManCmd_upload_LCU_patches_flight_ops { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! string section = "P" in ["P","R"]; }{ mois_comment("This procedure MUST be performed before the table upload series"); mois_comment("Start LCU memory patch upload"); mois_comment("Verify that the expected checksum has been provided by the HIFI representative within the associated TPF"); mois_tmcheck("Verify that parameter HL_Mode_S is set to standby."); StartMode_block_ops(); mois_step("Perform memory patch upload"); LcuMemoryPatchUpload_ops(section); StopMode_block_ops(); } {string,double,double}[] procedure HifiPointModeFastDBSSequencerInit { string modeName = "dbs"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 10 in [4,80]; // data dump interval int n_int_on = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_switch_on = 1 in [1,1800]; // number of data transfer cycles per pointing int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Get the drift parameters to compute the drift noise {double,double} phaselengths = DBSPhaseLengths(band,lo_freq,effResolution,continuumDetection,oneGHzReference); // Compute derived quantities // Top down approach here int main_phase = iceil(phaselengths{0}); int data_time_guess = 40; int n_switch_on_guess = main_phase / data_time_guess; if(n_switch_on_guess < 2) { n_switch_on_guess = 2; data_time_guess = main_phase / n_switch_on_guess; } // Check with data rate {int,double[]} dataparms = DataTaking(backendreadoutparms,8); int datalimit = 2 * dataparms{0}; if(data_time_guess < datalimit) { data_time_guess = datalimit; n_switch_on_guess = 1; } int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } // Chop phase length double phase_min = min(max(phaselengths{1},0.15),1.5); int n_int_on_guess = ifloor(double(data_time_guess) / (2.0 * phase_min)); int n_int_on_range = -n_int_on_guess / 2; if(n_int_on_range == 0) { n_int_on_range = 1; } // Add pointing requirements condition: >=10s {int,int} new_data_time = MatchMinPointing(data_time_guess,data_time_range,n_switch_on_guess); data_time_guess = new_data_time{0}; data_time_range = new_data_time{1}; // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"n_int_on",double(n_int_on_guess),double(n_int_on_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)}]; return retvalues; } ////////////////////////////////////////////////////////// // New building blocks // Slow chop integration at source position OFF-ON-ON-OFF... block HIFIHalfChopOnIntegration HIFI 6051 { int data_time = 4; // Integration time between two data readouts int n_cycle = 1; // chop cycle number string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double[] rates = [120.0,1.0,2.0]; // Data rates between and during integrations }{ HIFI_Spectr_slow_chop_proc_aot(data_time,n_cycle,band,lo_freq,["chop_M3","chop_M3right"],rates); } // First part of FPSS FM functional test, block // Check that IF amplification is effective block FT_FPU_check_IF_fm HIFI 3800 { string band = "1a"; int integ_time = 4; //Integation time in seconds string context = "warm" in ["warm","cold"]; //Test context: warm or cold string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); //At that stage all IF are ON. Take a spectrum HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // // //Switch OFF FIF //Get parameters {double,string}[] result_h = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,0.0); if(context == "warm") { result_h = ConfigurationReaderWarm("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,0.0); } // int band_nb = iround(result_h[0]{0}); int diplex_h_ctrl_mode = 0; int diplex_v_ctrl_mode = 0; // double volt_H_FIF_1 = 0.075; double curr_H_FIF_1 = 0.5; double volt_H_FIF_2 = 0.075; double curr_H_FIF_2 = 0.5; // double volt_H_SIF_1 = result_h[5]{0}; double curr_H_SIF_1 = result_h[6]{0}; double volt_H_SIF_2 = result_h[7]{0}; double curr_H_SIF_2 = result_h[8]{0}; double volt_H_SIF_3 = result_h[9]{0}; double curr_H_SIF_3 = result_h[10]{0}; // {double,string}[] result_v = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,0.0); if(context == "warm") { result_v = ConfigurationReaderWarm("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,0.0); } // // double volt_V_FIF_1 = 0.075; double curr_V_FIF_1 = 0.5; double volt_V_FIF_2 = 0.075; double curr_V_FIF_2 = 0.5; // double volt_V_SIF_1 = result_v[4]{0}; double curr_V_SIF_1 = result_v[5]{0}; double volt_V_SIF_2 = result_v[6]{0}; double curr_V_SIF_2 = result_v[7]{0}; double volt_V_SIF_3 = result_v[8]{0}; double curr_V_SIF_3 = result_v[9]{0}; // string chop_sine_s = "ON"; string chop_loop = "CLOSE"; {double,string}[] result = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,0.0); if(context == "warm") { result = ConfigurationReaderWarm("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,0.0); } // int chop_G1 = iround(result[0]{0}); int chop_G2 = iround(result[1]{0}); int chop_Z1 = iround(result[2]{0}); int chop_Z2 = iround(result[3]{0}); int chop_P2 = iround(result[4]{0}); // // // double calibcurrent = result[7]{0}; // double bias_H = 0.0; double magnetcurrent_H = 0.0; double diplex_H = 0.0; double bias_V = 0.0; double magnetcurrent_V = 0.0; double diplex_V = 0.0; double chopper = 0.0; // // chopper = Check_Chopper_Prime_Redundant(chopper); HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result = ConfigurationReader("name_delays",["config_fpu_delay"],band,0.0); int config_fpu_delay = iround(result[0]{0}); delay(config_fpu_delay); // HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // // //Switch OFF SIF // volt_H_SIF_1 = 0.075; curr_H_SIF_1 = 0.5; volt_H_SIF_2 = 0.075; curr_H_SIF_2 = 0.5; volt_H_SIF_3 = 0.075; curr_H_SIF_3 = 0.5; // volt_V_SIF_1 = 0.075; curr_V_SIF_1 = 0.5; volt_V_SIF_2 = 0.075; curr_V_SIF_2 = 0.5; volt_V_SIF_3 = 0.075; curr_V_SIF_3 = 0.5; // chopper = Check_Chopper_Prime_Redundant(chopper); HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // delay(config_fpu_delay); // HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // // } {int,double,double,double,double,double} obs HifiPointModeLoadChop { string modeName = "load"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rates int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 2 in [1,900]; // number of half load-sky-sky-load cycles on ON int n_switch_off = 2 in [1,900]; // number of half load-sky-sky-load cycles on OFF int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF calibration cycles int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode OpenMessages("HIFI Single Point - Load Chop Ref",{data_time,data_time_off,0,n_switch_on,n_switch_off,0,0,0,n_cycles,load_interval}); // position switch // Call first part of the timing computer {int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int} pre_timing_ps = LoadChop_pre_timing(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,n_switch_on,n_switch_off,n_cycles,load_interval,docommands); // Prepare telescope command {double,double} onPosition = {ra,dec}; {double,double} refPosition = {raoff,decoff}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,int,int,int,int,int,int} tpar_ps = PositionSwitch_telescope(naifid,onPosition,refPosition,band,lo_freq,pre_timing_ps,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = nodding_pointing(false,tpar_ps{0},tpar_ps{1},tpar_ps{2},tpar_ps{3},tpar_ps{4},tpar_ps{5},tpar_ps{6},tpar_ps{7},tpar_ps{8},tpar_ps{9},tpar_ps{10},tpar_ps{11},tpar_ps{12},tpar_ps{13},tpar_ps{14},tpar_ps{15},tpar_ps{16},tpar_ps{17},tpar_ps{18},true); // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int},int,bool,double,double} post_timing_ps = DoubleChop_post_timing(pre_timing_ps,telescopetimes,n_cycles); // Now the actual observation starts // Prepare telescope command tpar_ps = PositionSwitch_telescope(naifid,onPosition,refPosition,band,lo_freq,post_timing_ps{1},n_cycles); // Call telescope command telescopetimes = nodding_pointing(true,tpar_ps{0},tpar_ps{1},tpar_ps{2},tpar_ps{3},tpar_ps{4},tpar_ps{5},tpar_ps{6},tpar_ps{7},tpar_ps{8},tpar_ps{9},tpar_ps{10},tpar_ps{11},tpar_ps{12},tpar_ps{13},tpar_ps{14},tpar_ps{15},tpar_ps{16},tpar_ps{17},tpar_ps{18},true); // Consistency check int totaltime = post_timing_ps{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following ////////////////////////////////////////////////////////////////////// int on_inttime = post_timing_ps{1}{0}; int off_inttime = post_timing_ps{1}{1}; int on_pointing = post_timing_ps{1}{2}; int off_pointing = post_timing_ps{1}{3}; int loadlength = post_timing_ps{1}{4}; int n_loadinterval = post_timing_ps{1}{7}; int n_per_on = post_timing_ps{1}{8}; int n_per_off = post_timing_ps{1}{9}; int n_load_on = post_timing_ps{1}{10}; int n_load_off = post_timing_ps{1}{11}; bool end_load_on = post_timing_ps{1}{12}; bool end_load_off = post_timing_ps{1}{13}; int initshiftlength = post_timing_ps{2}; bool final_load = post_timing_ps{3}; double tscan = post_timing_ps{4}; double tdead = post_timing_ps{5}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands ////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { LoadChop_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,n_per_on,n_per_off,n_loadinterval,n_load_on,n_load_off,end_load_on,end_load_off,final_load,startobs,telescopetimes,loadlength,initshiftlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double,double,double} tact = DoubleChop_deadtimes("lchop",band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,n_per_on,n_per_off,n_load_on,n_load_off,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = LoadChop_noisecomputer(band,lo_freq,effResolution,oneGHzReference,on_inttime,off_inttime,n_cycles,tscan,tact); // Evaluate performance DoubleChop_performance(band,lo_freq,effResolution,noisevalues,timeTaken,n_cycles,n_per_on * (n_load_on + 1),n_per_off * (n_load_off + 1),false,tscan,on_pointing,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // Horizontal transitions between open loop and closed loop contexts // Can be either direction - This will only switch the chopper loop // between open and closed. mode HifiManCmd_HIFI_OL_from_to_CL { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! string chopper_loop = "OPEN" in ["OPEN","CLOSE"]; //chopper loop status to be set string instrument_mode = "StandbyI" in ["StandbyI","StandbyII","Primary"]; //Instrument mode applying to the switch string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ //Preliminary check depending on the mode if(instrument_mode == "StandbyI") { mois_tmcheck("Check that parameters HWH_Laser1_S, HWH_Laser2_S, HWV_Laser1_S and HWV_Laser2_S are all OFF"); } if(instrument_mode == "StandbyII") { //Nothing is made about the lasers. mois_tmcheck("Check that parameter HL_MODE_S is standby"); mois_tmcheck("Check that parameter HL_Channel_S is Off"); } if(instrument_mode == "Primary") { mois_tmcheck("Check that parameter HL_MODE_S is normal"); mois_tmcheck("Check that parameter HL_Channel_S is Off"); } // string chopper_start_loop = "CLOSE"; if(chopper_loop == "CLOSE") { chopper_start_loop = "OPEN"; } mois_tmcheck("Check that parameter HF_DPR_CHLOOP_S is set to " + chopper_start_loop); //Standby should always correspond to band0, lofreq=0 string band = "0"; double lo_freq = 0.0; mois_comment("Set HIFI chopper loop to " + chopper_loop + " in " + instrument_mode + " mode."); StartMode_block_ops(); //Chopper loop status change mois_step("Switch chopper loop"); string chop_startup_prime_red = "chop_startup_cold_prime"; if(prime_or_redundant == "Red") { chop_startup_prime_red = "chop_startup_cold_red"; } {double,string}[] result = ConfigurationReader("name_chopper",[chop_startup_prime_red],band,lo_freq); if(chopper_loop == "OPEN") { result = ConfigurationReader("name_chopper",["chop_startup_warm"],"0",0.0); } //HBB heater status depends on mode string hbb_status = "ON"; if(instrument_mode == "StandbyI") { hbb_status = "ON"; } Init_MSA_ops("0",chopper_loop,0.0,result[0]{0},hbb_status,prime_or_redundant); // StopMode_block_ops(); mois_tmcheck("Check that parameter HF_DPR_CHLOOP_S is set to " + chopper_loop); mois_tmcheck("Check that parameter HF_DPR_CH_ROT is set to " + result[0]{0}); } // Change the LO frequency to a new setting, keep backend settings procedure HIFITuneFreq { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; //LO frequency bool newsetting = true; // whether LSU/LOU parameters are new string target_name = "sscan_normal"; // Name of target level }{ // //LO power tuning: could use either H or V polar {double,string}[] result = ConfigurationReader("name_confpolar4lotune",[band],band,lo_freq); double x = result[0]{0}; string tuningbackend = "H"; if(iround(x) == 2) { tuningbackend = "V"; } else { tuningbackend = "H"; } //LO frequency tuning, and store in FSW register LO_tuning_block_aot(band,lo_freq / 1000.0,lo_freq / 1000.0,tuningbackend,newsetting,newsetting,false); //Spectrometer attenuator tuning - on the sky or cold load if(target_name != "") { WBS_attenuators_block(band,lo_freq / 1000.0,target_name,true); } } //Set LCU back to standby status without setting any particular LO band, block //LCU is only set to standby if the band has been switched off block LCU_standby_block_ops HIFI 7629 { }{ // {double,string}[] result = ConfigurationReader("name_delays",["stdby_delay"],"0",0.0); int stdby_delay = iround(result[0]{0}); // //Set in standby mode Hifi_HIFI_HL_Standby($BBID); delay(stdby_delay); //Will be done at end of procedure during instrument mode status check //mois_tmcheck("Check that parameter HL_MODE_S is standby"); } // Initialisation of FPU, block with both MSA in use // It is for cold context ! // Note that is will use old magnet settings (prior to SCR-2372) block Init_MSA_ops HIFI 7200 { string band = "1a"; // HIFI band string chop_loop = "CLOSE"; double lo_freq = 500.0; //LO frequency double chopper = 0.0; //prime or redundant chopper voltage string hbb_heater = "ON" in ["ON","OFF"]; //hot source on/off string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ //Get parameters {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,lo_freq); int band_nb = iround(result_d[0]{0}); double diplex_H = 0.0; double diplex_V = 0.0; int diplex_h_ctrl_mode = 0; int diplex_v_ctrl_mode = 0; // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,lo_freq); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // string chop_sine_s = "ON"; // string chop_loop = "CLOSE" ; result_d = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,lo_freq); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // double calibcurrent = result_d[7]{0}; if(hbb_heater == "ON") { result_d = ConfigurationReader("name_confilfpu",["calibrator_current_on"],band,0.0); calibcurrent = result_d[0]{0}; } // // //Get biases result_d = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); double bias_H = result_d[0]{0}; double bias_V = result_d[1]{0}; //For bands 6 and 7, first set to 4mV if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { result_d = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,lo_freq); bias_H = result_d[0]{0}; bias_V = result_d[1]{0}; } // //Get magnets: not applicable to bands 6 and 7 double magnetcurrent_H = 0.0; double magnetcurrent_V = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,lo_freq); magnetcurrent_H = result_d[0]{0}; magnetcurrent_V = result_d[1]{0}; } //Diplexer is interpolated from a table for Bands 3, 4, 6 and 7 if(band_nb <= 2 || band_nb == 5) { diplex_H = 0.0; //For bands 1, 2 and 5 diplex_V = 0.0; diplex_h_ctrl_mode = 0; diplex_v_ctrl_mode = 0; } else { //Get diplexer currents result_d = ConfigurationReader("name_confilfpu",["diplex_h_ctrl_mode","diplex_v_ctrl_mode"],band,lo_freq); diplex_h_ctrl_mode = iround(result_d[0]{0}); diplex_v_ctrl_mode = iround(result_d[1]{0}); double[] result_dip = Get_Diplexer_setting(band,lo_freq); diplex_H = result_dip[0]; diplex_V = result_dip[1]; } // //For this configuration we won't convert prime chopper voltage into redundant voltage //Just checking we are in range. //chopper = Check_Chopper_Prime_Redundant(chopper); chopper = Check_Chopper_Range_COP(chopper,prime_or_redundant); // //Switch on upconverter, assuming chopper and mixers are also ON Hifi_HIFI_Configure_FCU_Power($BBID,"ON","ON","ON","ON","ON"); // if(prime_or_redundant == "Prime") { Hifi_HIFI_P_Configure_FCU($BBID,band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); } else { Hifi_HIFI_R_Configure_FCU($BBID,band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); } // result_d = ConfigurationReader("name_delays",["config_fpu_delay"],band,lo_freq); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // //In case of band 6 or 7, bias have been set to 6mV. Now set to nominal if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { {double,string}[] result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); Mixerbias(result[0]{0},result[1]{0}); } // //Magnet are so far at maximum value. Now set to nominal //For Init_MSA_ops, we use a table gathering the old settings - prior to SCR-2372 if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { string tabmgn = "config_mix_FT.config"; double norm_magn_h = dlookup(tabmgn,"" + band_nb,"norm_magn_h"); double norm_magn_v = dlookup(tabmgn,"" + band_nb,"norm_magn_v"); Hifi_HIFI_CH1_MX_MG_C($BBID,norm_magn_h); Hifi_HIFI_CV1_MX_MG_C($BBID,norm_magn_v); delay(1); } // Hifi_HIFI_non_periodic_hk_FCU(); } int block HIFI_Calibrate_hot_cold HIFI 6005 { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency int data_time = 4; // time between subsequent data readouts int n_data = 2; // Integration time counter {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // Readout parameters for HRS1,HRS2, WBS1,WBS2 bool staycal = false; // whether we should stay at the hot load at the end }{ // data rate and read-out time {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int readout = dataparms{0}; // send the configure spectroscopy command to configure the measurement // returned dead times not needed here ConfigureSpectroscopy(data_time,n_data,"hot-cold",band,lo_freq,backendreadoutparms); HIFI_Spectr_slow_chop_proc_aot(data_time,n_data / 2,band,lo_freq,["chop_hot","chop_cold"],dataparms{1}); if(!staycal) { // Emit NOOP command to have the chopper rotation in second bus slot Hifi_HIFI_noop(); // Move chopper back to the sky RotateChopper(band,lo_freq,"chop_M3"); } // delay required at the end int sdelay = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); // have clean bus timing for next spectroscopy block delay(sdelay); return readout; } // get backend bandwidth coverage (HRS only) double procedure GetBackendBandwidth { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency int res_mode = 0; // coding for the backend resolution mode }{ if(res_mode < 0 || res_mode > 3) { double[] resol = CalibrationReader("backendresolution",["wbs_bandwidth"],band,lo_freq); } if(res_mode == 0) { resol = CalibrationReader("backendresolution",["hrs_high_bandwidth"],band,lo_freq); } if(res_mode == 1) { resol = CalibrationReader("backendresolution",["hrs_normal_bandwidth"],band,lo_freq); } if(res_mode == 2) { resol = CalibrationReader("backendresolution",["hrs_low_bandwidth"],band,lo_freq); } if(res_mode == 3) { resol = CalibrationReader("backendresolution",["hrs_wide_bandwidth"],band,lo_freq); } return resol[0]; } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the peakup mode procedure Peakup_commanding { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // chunk size int n_int = 1; // number of readouts double eff_resolution = 1.0; // Minimum goal resolution in MHz double stepsize = 0.0050; // Distance between subsequent points in the raster line int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,10,10,29,0]; // Timing of the observation from telescope int loadlength = 21; // Load duration }{ // Auxiliary variables bool isWbs = wbs1{0} || wbs2{0}; // Whether to use WBS bool isH = wbs1{0} || hrs1{0}; // Whether to use H polarization // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Different numbering in telescope command and peakup // Numbering starts from -Z,-Y, and proceeds first towards +Z int[] pointtable = [1,2,3,6,5,4,7,8,9]; // Get all values from the telescope section int tinitslew = telescopetimes[1]; // Initial slew time //////////////////////////////////////////////////////////////////////// // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] rates = dataparms{1}; int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 1) { // Initialization HIFIInitObs(); TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal"); HIFISetHK("normal",false); // First load measurement LoadMeasurement(band,lo_freq,eff_resolution,data_time,backendreadoutparms); HifiPeakupConfigure(data_time,n_int,isH,band,lo_freq,stepsize,backendreadoutparms); } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 3) { int pointnumber = pointtable[state[2] - 1]; // In raster - actual measurement HIFIPeakupIntegration(data_time,n_int,isWbs,isH,pointnumber,band,lo_freq,rates); } // Final state if(state[0] == 5) { delay(readoutdead); // Perform AOCS correction HifiPeakupCorrection(); HIFICloseObs(); } } } ///////////////////////////////////////////////////////////////// // Procedure to call ConfigSpectroscopy with a single command int[] procedure ConfigSlowChop { int observing_time = 8; // Integration time string chopmode = "chop" in ["chop","lchop","fs","hot-cold","tp","chopcal"]; // Chop mode determining the modulation dead time string band = "1a"; // HIFI band double lo_freq = 522000.0; // LO frequency /* Backend settings */ {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // HRS1 {used,resolution,subbands used}, HRS2 , WBS1 {used, channel windows}, WBS2 }{ // split integration time int data_time = 0; int n_switch = 0; // // guarantee that a full chop cycle is performed in chopped observations if(chopmode == "tp") { int divisor = 1; } else { divisor = 2; } // Try 16 bit mode int dpmax = 5; {int,double[]} dataparms = DataTaking(backendreadoutparms,dpmax); int dpmin = dataparms{0}; int nstep = dpmax - dpmin; // Check read out times for(int istep = 0 .. nstep) { int idiv = dpmax - istep; if(observing_time % (divisor * idiv) == 0) { data_time = idiv; n_switch = observing_time / idiv; } } if(data_time == 0) { debug_print("The integration time of " + observing_time + "s cannot be split " + "into short integrations - trying 24 bit mode."); // Try 24 bit mode dpmax = 10; dataparms = DataTaking(backendreadoutparms,dpmax); dpmin = dataparms{0}; nstep = dpmax - dpmin; // Check read out times for(int istep1 = 0 .. nstep) { idiv = dpmax - istep1; if(observing_time % (divisor * idiv) == 0) { data_time = idiv; n_switch = observing_time / idiv; } } } if(data_time == 0) { error("The integration time of " + observing_time + "s cannot be split " + "into equal integrations <= 10s."); } // return [data_time,n_switch]; } // Get load temperatures {double,double} procedure LoadTemperatures { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency }{ // Get temperatures double[] temp = CalibrationReader("loadtemp",["hot_temperature","cold_temperature"],band,lo_freq); double t_hot = temp[0]; double t_cold = temp[1]; // Get coupling specific for each band temp = CalibrationReader("loadcoupling",["hot_coupling","cold_coupling"],band,lo_freq); double c_hot = temp[0]; double c_cold = temp[1]; // Translate into radiation temperatures double hoverk = 4.7992E-5; double j_hot = hoverk * lo_freq / (exp(hoverk * lo_freq / t_hot) - 1.0); double j_cold = hoverk * lo_freq / (exp(hoverk * lo_freq / t_cold) - 1.0); // Coupling double j_hot_eff = j_hot * c_hot + j_cold * (1.0 - c_hot); double j_cold_eff = j_cold * c_cold + j_hot * (1.0 - c_cold); return {j_hot_eff,j_cold_eff}; } //Set LCU6Lb back to standby status, procedure procedure LCU6Lb_standby_proc_fm { string band = "6b"; // HIFI band double lo_freq = 1600.0 in [1575.0,1700.0]; //LO frequency }{ error("This module is obsolete: use LCU_standby_proc_fm instead"); } // ======================================================= block Virtual_Machine_Test_block_fm HIFI 3650 { string band = "1a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int integ_time = 4; //Total integration time in sec. string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); //Configure HRS HRS_config_att_lo_fm(band,hrs_mode); HRS_config_resol_fm(band,hrs_mode); // Take total power spectrum //========================== HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // delay to ensure total power finished // } // Take fast chop spectra, block block Spectro_fast_chop_block_fm HIFI 3608 { string band = "1a"; // HIFI band double chop_phase = 1.0 in [0.2,2.0]; // Chop phase length double[] chop_angle = [-1.0,+1.0]; //The two angles to chop between int[] timing_parms = [1,2,1]; //n_wbs_start, n_wbs1 and n_hrs_trans string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); // int n_wbs_start = timing_parms[0]; int n_wbs1 = timing_parms[1]; int n_hrs_trans = timing_parms[2]; // //Compute data-rate int total_time = iceil(chop_phase * double(n_wbs_start * n_wbs1)); double[] rates = ILT_datarate_proc_fm(band,backend,"fastchop",total_time); //Take spectrum // set data rates non_ess_hk_data_rate(rates[2] / 1024.0); data_rate(rates[0] / 1024.0); // HIFI_Spectr_fast_chop_proc_fm(chop_angle[0],chop_angle[1],n_wbs1,n_hrs_trans); //This probably needs to be adapted Apply_Fast_Chop_delay(total_time,n_wbs_start,band,backend); // reset data rates non_ess_hk_data_rate(rates[1] / 1024.0); data_rate(0.0); } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the OTF observing mode procedure OTFLoadChopNoRef_commanding { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // chunk size given by the data rates and optimum speed int n_perline = 10; // Number of frequency switch cycles per line int n_linesperscan = 1; // Number of lines between two load holds int nlines_tot = 10; // Total number of lines to go bool end_load_on = false; // Need for load after each pointing phase int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,2,2,40,10,20,0]; // Timing of the observation from telescope int loadlength = 50; // Load duration }{ // Auxiliary variables // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time //////////////////////////////////////////////////////////////////////// // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // // Clustering is currently not implemented in MPS - switched off here int clustered = 0; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] rates = dataparms{1}; int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; bool runintostate = false; while(state[0] >= 0) { if(runintostate) { state = next_state_no_check(); } else { state = next_state(); } if(state[0] == 1) { // Initialization if(clustered != 1) { HIFIInitObs(); TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal"); } delay(tinitslew - (time() - startobs) - loadlength - hkduration); HIFISetHK("normal",false); // First load measurement LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); runintostate = false; } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 8) { // OTF integration // Check whether this is the first line if((state[2] + n_linesperscan - 1) % n_linesperscan == 0) { HIFIConfigureLoadChopIntegration(data_time,n_perline,band,lo_freq,backendreadoutparms); } HIFILoadChopOnIntegration(data_time,n_perline,band,lo_freq,rates); runintostate = false; } if(state[0] == 6) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); if(state[2] * state[3] == nlines_tot) { runintostate = true; } else { runintostate = false; } } if(state[0] == 5) { // apply only if I do not come from a load-hold if(!runintostate) { delay(readoutdead); if(end_load_on) { // Perform final load measurement LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } } runintostate = false; HIFICloseObs(); } } } // Initialisation of FPU, block with both MSA in use // It is for cold context ! block Init_MSA_aot HIFI 6200 { string band = "4a"; // HIFI band string chop_loop = "CLOSE"; double lo_freq = 978.2; //LO frequency bool power_fcu = true; //whether needs full FPU configuration (true) or just freq-dependent adjustement (false) string hbb_heater = "ON" in ["ON","OFF"]; //hot source on/off }{ //Store rest frequency double rest_lofreq = lo_freq; //LO frequency uncorrected from VelCorr // Perform radial velocity correction lo_freq = VelCorrFreq(rest_lofreq); //Get parameters {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,lo_freq); int band_nb = iround(result_d[0]{0}); double diplex_H = 0.0; double diplex_V = 0.0; int diplex_h_ctrl_mode = 0; int diplex_v_ctrl_mode = 0; // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,lo_freq); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // string chop_sine_s = "ON"; // string chop_loop = "CLOSE" ; result_d = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,lo_freq); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // double calibcurrent = result_d[7]{0}; if(hbb_heater == "ON") { result_d = ConfigurationReader("name_confilfpu",["calibrator_current_on"],band,lo_freq); calibcurrent = result_d[0]{0}; } // // //Get biases result_d = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); double bias_H = result_d[0]{0}; double bias_V = result_d[1]{0}; //For bands 6 and 7, first set to 4mV if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { result_d = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,lo_freq); bias_H = result_d[0]{0}; bias_V = result_d[1]{0}; } // //Get magnets: not applicable to bands 6 and 7 double magnetcurrent_H = 0.0; double magnetcurrent_V = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,lo_freq); magnetcurrent_H = result_d[0]{0}; magnetcurrent_V = result_d[1]{0}; } //Diplexer is interpolated from a table for Bands 3, 4, 6L and 6H if(band_nb <= 2 || band_nb == 5) { diplex_H = 0.0; //For bands 1, 2 and 5 diplex_V = 0.0; diplex_h_ctrl_mode = 0; diplex_v_ctrl_mode = 0; } else { //Get diplexer currents result_d = ConfigurationReader("name_confilfpu",["diplex_h_ctrl_mode","diplex_v_ctrl_mode"],band,lo_freq); diplex_h_ctrl_mode = iround(result_d[0]{0}); diplex_v_ctrl_mode = iround(result_d[1]{0}); double[] result_dip = Get_Diplexer_setting(band,lo_freq); diplex_H = result_dip[0]; diplex_V = result_dip[1]; } // result_d = ConfigurationReader("name_chopper",["chop_startup_cold"],band,lo_freq); if(chop_loop == "OPEN") { result_d = ConfigurationReader("name_chopper",["chop_startup_warm"],band,0.0); } double chopper = result_d[0]{0}; //For this configuration we won't convert prime chopper voltage into redundant voltage //Just checking we are in range: not necessary anymore with MIB134 //chopper = Check_Chopper_Range(chopper); // //Check whether we need to go through a complete FPU configuration from scratch //Standard Init of FPU if(power_fcu) { //Switch on upconverter, assuming chopper and mixers are also ON Hifi_HIFI_Configure_FCU_Power($BBID,"ON","ON","ON","ON","ON"); // HIFI_Configure_FCU_proc_aot(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result_d = ConfigurationReader("name_delays",["config_fpu_delay"],band,rest_lofreq); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // //Magnet are so far at maximum value. Now set to nominal if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); Hifi_HIFI_CH1_MX_MG_C($BBID,result_d[0]{0}); Hifi_HIFI_CV1_MX_MG_C($BBID,result_d[1]{0}); delay(1); } //In case of band 6 or 7, bias have been set to 6mV. Now set to nominal if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { result_d = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); Mixerbias(result_d[0]{0},result_d[1]{0}); } //Reduced FPU configuration } else { //In case of HEB, we have so far the max bias as values if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { result_d = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); bias_H = result_d[0]{0}; bias_V = result_d[1]{0}; } Hifi_HIFI_noop(); Hifi_HIFI_Config_mxbias_dpact($BBID,bias_H,bias_V,diplex_H,diplex_V); delay(1); } // // Removed to reduce No of TC // Hifi_HIFI_non_periodic_hk_FCU (); } //HIFI LO tuning, block //Target current is read from look-up table block LO_tuning_HEB_block_fm HIFI 3677 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency string mixer_polarization = "H" in ["H","V","B"]; //The polarization to be used for the tuning double target_current = 1.0; //Target mixer current }{ //Clear potential failure mode Set_LO_Nominal_proc_fm(); // //Start_block(); {double,string}[] result = ConfigurationReader("name_confpolar4lotune",[band],band,lo_freq); //string mixer_polarization = result[0]{1}; // //Get target mixer current result = ConfigurationReader("name_confilmix",["target_mx_c_h","target_mx_c_v"],band,lo_freq); //double target_current = result[0]{0}; if(mixer_polarization == "V") { //target_current = result[1]{0}; } if(mixer_polarization == "B") { //target_current = 0.5*(result[1]{0}+result[0]{0}); } // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; name_configlcutune = "name_configlcutune_b"; } // result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // result = ConfigurationReader(name_configlotune,["step_drain2_v","nsteps","step_time"],band,lo_freq); double step_drain2_v = result[0]{0}; int nsteps = iround(result[1]{0}); double step_time = result[2]{0}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // //Adjust scan cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); double drain2_safe = cresult[0]; // double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); // //For all bands, scan will be done with decreasing drain2 voltages //The best guess is taken from look-up table double tune_range = 0.1; result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lo_freq); double middle_d2 = result[0]{0}; double drain2_v_start = min(middle_d2 * (1.0 + tune_range / 2.0),drain2_bluemax); double drain2_v_end = (1.0 - tune_range / 2.0) / (1.0 + tune_range / 2.0) * drain2_v_start; step_drain2_v = (drain2_v_end - drain2_v_start) / double(nsteps - 1); // result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); // //Send command HIFI_Configure_LCU_proc_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,macro_checksum,config_lo_delay); // //delay(5); //to settle at this value // //Load vector scan //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Load_vector_safe_1a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "1b") { //Band 1b Hifi_HIFI_Load_vector_safe_1b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2a") { //Band 2a Hifi_HIFI_Load_vector_safe_2a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2b") { //Band 2b Hifi_HIFI_Load_vector_safe_2b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3a") { //Band 3a Hifi_HIFI_Load_vector_safe_3a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3b") { //Band 3b Hifi_HIFI_Load_vector_nom_3b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "4a") { //Band 4a Hifi_HIFI_Load_vector_safe_4a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "4b") { //Band 4b Hifi_HIFI_Load_vector_safe_4b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "5a") { //Band 5a Hifi_HIFI_Load_vector_nom_5a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "5b") { //Band 5b Hifi_HIFI_Load_vector_nom_5b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6a") { //Band 6a Hifi_HIFI_Load_vector_nom_6a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6b") { //Band 6b Hifi_HIFI_Load_vector_nom_6b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7a") { //Band 7a Hifi_HIFI_Load_vector_nom_7a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7b") { //Band 7b Hifi_HIFI_Load_vector_nom_7b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } // delay(1); // //Execute tuning: check which mixer is to be used if(mixer_polarization == "V") { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCV($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCV($BBID,target_current); } } else { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCH($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCH($BBID,target_current); } } // double time_needed = double(nsteps) * step_time; delay(iround(time_needed + 2.0 + 0.5)); //0.5s added for completion of load_vector // //Store settings into available register HIFI_HL_store_tm_only_proc_fm(); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } // Standby of FPU with internal source off, block block Band0_fm HIFI 3299 { string band = "0"; string chop_loop = "CLOSE"; // Chopper Loop status }{ Start_block(); // {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h","diplex_h_ctrl_mode"],band,0.0); int band_nb = iround(result_d[0]{0}); // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // int diplex_h_ctrl_mode = iround(result_d[10]{0}); // result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v","diplex_v_ctrl_mode"],band,0.0); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // int diplex_v_ctrl_mode = iround(result_d[10]{0}); // string chop_sine_s = "ON"; // result_d = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,0.0); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // double calibcurrent = result_d[7]{0}; //To get standby with source on, use Band0_hbb_on result_d = ConfigurationReader("name_confilfpu",["bias_standby_h","diplexer_standby_h","bias_standby_v","diplexer_standby_v","chop_M3right"],band,0.0); // double bias_H = result_d[0]{0}; double diplex_H = result_d[1]{0}; double bias_V = result_d[2]{0}; double diplex_V = result_d[3]{0}; // double chopper = result_d[4]{0}; // //Retrieve magnets Magnet are so far at maximum value. Now set to nominal double magnetcurrent_H = result_d[1]{0}; double magnetcurrent_V = result_d[4]{0}; // if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilfpu",["magnet_standby_h","magnet_standby_v"],band,0.0); magnetcurrent_H = result_d[0]{0}; magnetcurrent_V = result_d[1]{0}; } // result_d = ConfigurationReader("name_chopper",["chop_startup_cold"],band,0.0); if(chop_loop == "OPEN") { result_d = ConfigurationReader("name_chopper",["chop_startup_warm"],band,0.0); } double chopper = result_d[0]{0}; //For this configuration we won't convert prime chopper voltage into redundant voltage //Just checking we are in range. //chopper = Check_Chopper_Prime_Redundant(chopper); chopper = Check_Chopper_Range(chopper); // //Switch on upconverter, assuming chopper and mixers are also ON Hifi_HIFI_Configure_FCU_Power($BBID,"ON","ON","ON","ON","ON"); // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result_d = ConfigurationReaderWarm("name_delays",["config_fpu_delay"],band,0.0); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // } //////////////////////////////////// // OTF frequency switch observing mode without baseline calibration // {string,double,double}[] procedure HifiMappingProcFSwitchOTFNoRefSequencerInit { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source {double,double} lineDistance = {0.0050,0.0050}; // Distance between subsequent rows int nlines = 1 in [1,240]; // Number of rows in the map double stepsize = 0.0050 in [0.0,0.13333]; // Distance between subsequent points in the OTF line int npoints = 10 in [1,720]; // Number of data dumps per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // chunk size given by the data rates and optimum speed int n_switch_on = 1 in [1,1800]; // Supersamplingfactor int n_cycles = 1 in [1,1200]; // Number of map coverages int load_interval = 1800 in [10,7200]; // load period defines number of lines between two loads bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode // inherit from load-chop mode {string,double,double}[] retvalues = HifiMappingProcLoadChopOTFNoRefSequencerInit(naifid,ra,dec,lineDistance,nlines,stepsize,npoints,band,lo_freq,effResolution,oneGHzReference,hrs1,hrs2,wbs1,wbs2,data_time,n_switch_on,n_cycles,load_interval,docommands); return retvalues; } // Get approximate initialization times int procedure GetRoughInitLength { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency bool fsw = false; // tuning for frequency switch? }{ if(fsw) { double[] idur = CalibrationReader("tunetime",["TuneHifiFsw"],band,lo_freq); } else { idur = CalibrationReader("tunetime",["TuneHifi"],band,lo_freq); } int initlength = iceil(idur[0]) + 2; return initlength; } // LCU5a configuration into SAFE mode, procedure procedure LCU5a_config_safe_proc_fm { string band = "5a"; // HIFI band double lo_freq = 1150.0 in [1127.0,1178.0]; //LO frequency }{ error("This module is obsolete: use LCU_config_nominal_proc_fm instead"); } //////////////////////////////////// // Radial veocity correction double procedure VelCorrFreq { double lo_freq = 978200.0; // LO frequency in MHz }{ double clight = 299999.6; // light velocity in km/s // classic correction - non-relativistic // to keep time estimates constant all shifts above a reasonable // limit are ignored - all lines will still fall into the spectrometers double velmax = 30.7; double appliedvel = max(min($RADVEL,velmax),-velmax); // $RADVEL in classic definition with positive for redshifted double lo_corr = lo_freq - appliedvel * lo_freq / clight; return lo_corr; } // LCU2b configuration into SAFE mode, procedure procedure LCU2b_config_safe_proc_fm { string band = "2b"; // HIFI band double lo_freq = 750.0 in [724.0,793.0]; //LO frequency }{ error("This module is obsolete: use LCU_config_nominal_proc_fm instead"); } ///////////////////////////////////////////////////////// // WBS configuration with maximum attenuation, procedure // Laser can be chosen procedure WBS_config_proc_max_att_w_laser_fm { string band = "1a"; // HIFI band string laser_H = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-V laser to be set ON }{ //H-Polarization // {double,string}[] result_d = ConfigurationReader("name_configwbs",["hwh_laser1_s","hwh_laser2_s","hwh_heater","hwh_latchup_s"],band,0.0); string hwh_laser1_s = "OFF"; string hwh_laser2_s = "OFF"; if(laser_H == "Laser1") { hwh_laser1_s = "ON"; } if(laser_H == "Laser2") { hwh_laser2_s = "ON"; } int hwh_heater = iround(result_d[2]{0}); string hwh_latchup_s = result_d[3]{1}; int hwh_att_band4 = 7; int hwh_att_band3 = 7; int hwh_att_band2 = 7; int hwh_att_band1 = 7; int hwh_att_in = 15; // result_d = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result_d[0]{0}); //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); //delay(wbs_config_delay); //V-Polarization //Get configuration parameters // result_d = ConfigurationReader("name_configwbs",["hwv_laser1_s","hwv_laser2_s","hwv_heater","hwv_latchup_s"],band,0.0); string hwv_laser1_s = "OFF"; string hwv_laser2_s = "OFF"; if(laser_V == "Laser1") { hwv_laser1_s = "ON"; } if(laser_V == "Laser2") { hwv_laser2_s = "ON"; } int hwv_heater = iround(result_d[2]{0}); string hwv_latchup_s = result_d[3]{1}; int hwv_att_band4 = 7; int hwv_att_band3 = 7; int hwv_att_band2 = 7; int hwv_att_band1 = 7; int hwv_att_in = 15; //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // //Wait delay to allow all setting to be configured delay(wbs_config_delay); } // New implementation of the WBS zero and comb measurement // // Returns dangling transmission time // int block WBS_Zero_FCal HIFI 6014 { string band = "4a"; // HIFI band (needed to estimate stabilization) double lo_freq = 978200.0; // LO frequency }{ // Get delays {double,string}[] result = ConfigurationReader("name_delays",["wbs_new_comb_delay"],band,lo_freq); int wbs_comb_delay = iround(result[0]{0}); int delay1 = 2; int delay2 = 3; int delay3 = wbs_comb_delay - delay1 - delay2; // Get attenuators for comb measurement {double,string}[] result_d = ConfigurationReader("name_configwbs",["hwh_att_band4_comb","hwh_att_band3_comb","hwh_att_band2_comb","hwh_att_band1_comb","hwh_att_in_comb"],band,0.0); int hwh_att_band4 = iround(result_d[0]{0}); int hwh_att_band3 = iround(result_d[1]{0}); int hwh_att_band2 = iround(result_d[2]{0}); int hwh_att_band1 = iround(result_d[3]{0}); int hwh_att_in = iround(result_d[4]{0}); // Data rate computation // The HIFI command is restricted to always read out both full WBS {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} fullreadoutparms = FrequencyCalibrationParms(true,true,false,false); // First part - zero // data rate {int,double[]} fdataparms = DataTaking(fullreadoutparms,delay1); // set data rates non_ess_hk_data_rate(fdataparms{1}[2] / 1024.0); data_rate(fdataparms{1}[0] / 1024.0); // Insert a Noop because previous command could have been issued in second bus slot Hifi_HIFI_noop(); // Call command Hifi_HIFI_WBS_Calibrate($BBID,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); delay(delay1); // data rates for other steps fullreadoutparms = FrequencyCalibrationParms(false,true,true,true); // set data rates fdataparms = DataTaking(fullreadoutparms,delay2); non_ess_hk_data_rate(fdataparms{1}[2] / 1024.0); data_rate(fdataparms{1}[0] / 1024.0); delay(delay2); fullreadoutparms = FrequencyCalibrationParms(true,true,true,true); // set data rates fdataparms = DataTaking(fullreadoutparms,delay3); non_ess_hk_data_rate(fdataparms{1}[2] / 1024.0); data_rate(fdataparms{1}[0] / 1024.0); delay(delay3); // read-out time int readout = fdataparms{0}; // reset data rates non_ess_hk_data_rate(fdataparms{1}[1] / 1024.0); data_rate(0.0); // // additional delay for packet transmission before next zero depends // on zero duration - needs to be introduced on higher level return readout; } // Procedure to perform the WBS tuning including the counting // of the science data, must be called within a building block procedure Tune_WBS_aot { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band int tune_target = 80; // Tuning target level }{ //Get delay {double,string}[] result_d = ConfigurationReader("name_delays",["wbs_tune_delay"],band,0.0); int wbs_tune_delay = iround(result_d[0]{0}); // data frame transmission time (always 3 spectra) int data_time = wbs_tune_delay / 3; int rest_delay = wbs_tune_delay - 3 * data_time; wbs_tune_delay = wbs_tune_delay - rest_delay; // Compute data rates // The HIFI command reads out both full WBS {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} fullreadoutparms = FrequencyCalibrationParms(true,true,false,false); {int,double[]} fdataparms = AllDataRates(fullreadoutparms,data_time,false); // set data rates (IF power packets are ignored here) data_rate(fdataparms{1}[0] / 1024.0); // Call tuning command Hifi_HIFI_Tune_WBS($BBID,tune_target); delay(wbs_tune_delay); // reset data rates data_rate(0.0); delay(rest_delay); } // LCU5a configuration and tuning, procedure procedure LCU5a_config_tune_proc_fm { string band = "5a"; // HIFI band double lo_freq = 1150.0 in [1127.0,1178.0]; //LO frequency double drain_2_factor = 100.0; //Percentage factor of the targetted drain voltage }{ error("This module is obsolete: use LO_tuning_block_fm instead"); } //TM to control FDIR on LOU temp block Disable_LO_FDIR_temperatures_block_mois HIFI 3852 { }{ // BBID needs to be set manually as the main TC command has no BBID argument Hifi_HIFI_Set_OBS_ID($BBID,$OBSID); delay(1); // Hifi_HIFI_LOU_T_check_off(); delay(1); // } ////////////////////////////////////////////////////////////////////// // Procedure to display performance parameters of the observing mode procedure SScanDoubleChop_performance { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz int nfreq = 4; // Number of frequency points per IF bool dsb = true; // Both sidebands covered {double,double} eff_resolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz {double,double,double,double,double} noisevalues = {1.0,1.0,1.0,1.0,0.0}; // Noise values from noisecomputer int totaltime = 200; // Total observing time int grouplen = 1; // Number of frequency steps per nodding phase int n_cycles = 1; // Number of ON-OFF cycles int freqsteps = 4; // Total number of frequencies double avnumchop_on = 1.0; // Average number of ON chop cycles per frequency double avnumchop_off = 1.0; // Average number of OFF chop cycles per frequency bool fs = false; // whether frequency switch used double tscan = 60.0; // Total average duration of one cycle {double,double,double,double,double} tact = {10.0,4.9,4.9,0.05,0.05}; // Field of actual dead and integration times }{ double inttimeperonphase = tact{1}; // Actual integration time in ON phase double inttimeperoffphase = tact{2}; // Actual integration time in OFF phase // Get performance of ideal instrument for comparison {int,double,double,double,double,double} idealvalues = IdealInstrument(band,lo_freq,eff_resolution,totaltime); // Use DSB noise for long spctral scans if(dsb) { double idealnoiselsb = idealvalues{1} * idealvalues{1}; double idealnoiseusb = idealvalues{3} * idealvalues{3}; double idealnoise = idealnoiselsb * idealnoiseusb / (idealnoiselsb + idealnoiseusb); } else { idealnoise = idealvalues{1} * idealvalues{1}; } double obsnoise = noisevalues{0} * noisevalues{0}; // rescale for range coverage double accumulation = double(freqsteps) / double(nfreq); idealnoise = idealnoise * accumulation; double efficiency = idealnoise / obsnoise; // Compute the actual integration time double maxsteps = double(freqsteps * n_cycles); double posinttime = 2.0 * maxsteps * avnumchop_on * inttimeperonphase; double posofftime = 2.0 * maxsteps / double(grouplen) * avnumchop_off * inttimeperoffphase; int instrumenttime = iceil(maxsteps * tscan); // Check total integration time double timeefficiency = (posinttime + posofftime) / double(totaltime); // Noise contribution double relnoise = noisevalues{4} / (1.0 + noisevalues{4}); // General messages PerformanceMessages(band,lo_freq,totaltime,posinttime,posofftime,timeefficiency,efficiency,relnoise,fs); } //TM check when switched off procedure Mode_status_check_switched_off { }{ mois_comment("Checking instrument status in switched off mode"); mois_tmcheck("Check that the HK parameter HI_FCU_S, HI_WBSH_S, HI_WBSV_S, HI_HRSH_S, HI_HRSV_S and HI_LCU_S are all OFF."); } ///////////////////////////////////////////////////////////////////////////// // Auxiliary procedures ///////////////////////////////////////////////////////////////////////////// // Function returning generic HRS mode string[] procedure GetHrsMode_proc_fm { string[] input_hrs_mode = ["wb","wb"]; // HRS resolution mode }{ string[] output_hrs_mode = ["wb","wb"]; //Test all possible resolution modes //H-polar if(input_hrs_mode[0] == "hr" || input_hrs_mode[0] == "hr_high" || input_hrs_mode[0] == "hr_low") { output_hrs_mode[0] = "hr"; } if(input_hrs_mode[0] == "mr") { output_hrs_mode[0] = "mr"; } if(input_hrs_mode[0] == "lr") { output_hrs_mode[0] = "lr"; } //V-polar if(input_hrs_mode[1] == "hr" || input_hrs_mode[1] == "hr_high" || input_hrs_mode[1] == "hr_low") { output_hrs_mode[1] = "hr"; } if(input_hrs_mode[1] == "mr") { output_hrs_mode[1] = "mr"; } if(input_hrs_mode[1] == "lr") { output_hrs_mode[1] = "lr"; } // return output_hrs_mode; } //General script to clear error flags and set to nominal, block block LCU_CLEAR_ERROR_block_fm HIFI 3666 { }{ // //Start_block(); //Clear error flags Hifi_HIFI_LCU_Single($BBID,"HL_CLR_ERR"); //Switch back to nominal Hifi_HIFI_HL_Normal($BBID); {double,string}[] result = ConfigurationReader("name_delays",["set_to_nominal_delay"],"0",0.0); int set_to_nominal_delay = iround(result[0]{0}); delay(set_to_nominal_delay); // } //////////////////////////////////// // Fast chop DBS cross observing mode - special version for Jupiter // // Return time and noise levels {int,double,double,double,double,double} obs HifiMappingProcJupiterFastDBSCross { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source double stepsize = 0.0050 in [5.5556E-4,0.13333]; // Distance between subsequent points in the two raster lines int npoints = 10 in [2,100]; // Number of points per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 10 in [4,80]; // data dump interval int n_int_on = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_switch_on = 1 in [1,1800]; // number of data transfer cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Engineering - Jupiter - DBS Cross Map fastChop",{data_time,0,n_int_on,n_switch_on,0,0,n_pointsperscan,0,n_cycles,load_interval}); // Call first part of the timing computer // Two changes relative to the normal DBS raster // 1) The longer load duration is enforced by zero resolution {double,double} loadResolution = {0.0,effResolution{1}}; // 2) I assume that the tuning duration does not depend on the tuning level // so that the normal pre_timing can be reused. {int,int,int,int,int,int,int,int,int,int,int,int,int} pre_timing = FastDBSRaster_pre_timing(2,npoints,band,lo_freq,loadResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_switch_on,n_pointsperscan,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,bool,double,double,double,double[],double[],int[],double,double,int,int,int,int,int,int} tpar = DBSCross_telescope(naifid,onPosition,stepsize,npoints,band,lo_freq,"",pre_timing,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = custom_map_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21}); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,int},bool,double,double} post_timing = DBSCross_post_timing(pre_timing,telescopetimes,npoints,n_switch_on,n_cycles,load_interval,true); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = DBSCross_telescope(naifid,onPosition,stepsize,npoints,band,lo_freq,"",post_timing{1},n_cycles); telescopetimes = custom_map_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21}); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{3}; int n_load = post_timing{1}{6}; int n_loadinterval = post_timing{1}{7}; int n_seq = post_timing{1}{8}; int scansize = post_timing{1}{10}; int initlength = post_timing{1}{11}; int dangling = post_timing{1}{12}; bool final_load = post_timing{2}; double tscan = post_timing{3}; double tdead = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { JupiterFastDBSRaster_commanding(band,lo_freq,loadResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_seq,n_cycles,scansize,n_loadinterval,n_load,final_load,startobs,telescopetimes,loadlength,true); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double} tact = FastDBSRaster_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_seq,n_load,scansize,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = DBS_noisecomputer(band,lo_freq,effResolution,continuumDetection,oneGHzReference,n_cycles,tscan,tact); // Evaluate performance DBSRaster_performance(band,lo_freq,effResolution,noisevalues,timeTaken,2,npoints,n_cycles,n_seq * n_int_on * imax(n_load,1),tact); // Correct for double counting of central point // The central point is returned only double multiplier = sqrt(0.5); noisevalues{0} = noisevalues{0} * multiplier; noisevalues{1} = noisevalues{1} * multiplier; noisevalues{2} = noisevalues{2} * multiplier; noisevalues{3} = noisevalues{3} * multiplier; noisevalues{4} = noisevalues{4} / multiplier; // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // FPU Standby with HBB On, block block Band0warm_hbb_on_fm HIFI 3295 { string band = "0"; // HIFI band string chop_loop = "CLOSE"; // Chopper Loop status }{ Start_block(); //Get parameters {double,string}[] result_d = ConfigurationReaderWarm("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,0.0); int band_nb = iround(result_d[0]{0}); // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // result_d = ConfigurationReaderWarm("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,0.0); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // string chop_sine_s = "ON"; // string chop_loop = "CLOSE" ; result_d = ConfigurationReaderWarm("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current_on"],band,0.0); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // double calibcurrent = result_d[7]{0}; // result_d = ConfigurationReaderWarm("name_confilfpu",["bias_standby_h","diplexer_standby_h","bias_standby_v","diplexer_standby_v","diplex_h_ctrl_mode","diplex_v_ctrl_mode","chop_M3right"],band,0.0); // double bias_H = result_d[0]{0}; double diplex_H = result_d[1]{0}; double bias_V = result_d[2]{0}; double diplex_V = result_d[3]{0}; int diplex_h_ctrl_mode = iround(result_d[4]{0}); int diplex_v_ctrl_mode = iround(result_d[5]{0}); // //Retrieve magnets Magnet are so far at maximum value. Now set to nominal double magnetcurrent_H = result_d[1]{0}; double magnetcurrent_V = result_d[4]{0}; // if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReaderWarm("name_confilfpu",["magnet_standby_h","magnet_standby_v"],band,0.0); magnetcurrent_H = result_d[0]{0}; magnetcurrent_V = result_d[1]{0}; } // // result_d = ConfigurationReader("name_chopper",["chop_startup_warm"],band,0.0); double chopper = result_d[0]{0}; //For this configuration we won't convert prime chopper voltage into redundant voltage //Just checking we are in range. //chopper = Check_Chopper_Prime_Redundant(chopper); chopper = Check_Chopper_Range(chopper); // //Switch on upconverter, assuming chopper and mixers are also ON Hifi_HIFI_Configure_FCU_Power($BBID,"ON","ON","ON","ON","ON"); // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result_d = ConfigurationReader("name_delays",["config_fpu_delay"],band,0.0); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // } //HIFI-COP-1.2-UPC_FT //NOT USED ANY LONGER - IF_FT REPLACED IT obs HifiEng_UPC_FT_COP { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(UPC_FT_COP_proc_ops(prime_or_redundant)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution UPC_FT_COP_proc_ops(prime_or_redundant); } if(state[0] == 5) { HIFISetHK("normal",true); StopMode_block_ops(); } } } ////////////////////////////////////////////////////////////////// // Procedure to compute detailed pre timing for the version of the // load chop mode with baseline measurement // {int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int} procedure LoadChop_pre_timing { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4 in [1,20]; // data dump interval limited by the data rates int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_chop_on = 2 in [1,900]; // number of half load-sky-sky-load cycles on ON int n_chop_off = 2 in [1,900]; // number of half load-sky-sky-load cycles on OFF int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF calibration cycles int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // First check validity of frequencies CheckLOFrequencies(band,lo_freq,lo_freq); // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // First perform consistency checks // Check chunk size given by the data rates CheckDataTaking(backendreadoutparms,data_time); CheckDataTaking(backendreadoutparms,data_time_off); int jitterdead = GetMaxTimeJitter(band,lo_freq); // Compute parameters for the instrument timing int on_inttime = 2 * n_chop_on * data_time; int off_inttime = 2 * n_chop_off * data_time_off; // compute load integration time int loadlength = duration(LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms)); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); loadlength = loadlength + readoutdead; // For double phases I can use the added jitterdead in both phases for load int halfloadlength = (loadlength - jitterdead + 1) / 2; // Compare load interval and position switch interval int load_spacing = CheckedLoadSpacing(load_interval - loadlength,8); int n_load_on = on_inttime / load_spacing; int n_load_off = off_inttime / load_spacing; // This determines the order of the loops if(load_spacing > 2 * on_inttime) { int n_per_on = n_chop_on; bool end_load_on = false; int on_pointing = on_inttime + jitterdead; } else { n_per_on = n_chop_on / (n_load_on + 1); if(n_per_on < 1) { SError("Chop phase length on source too long relative to load period."); } end_load_on = true; on_inttime = 2 * n_per_on * (n_load_on + 1) * data_time; on_pointing = on_inttime + halfloadlength + n_load_on * loadlength + jitterdead; } if(load_spacing > 2 * off_inttime) { int n_per_off = n_chop_off; bool end_load_off = false; int off_pointing = off_inttime + jitterdead; } else { n_per_off = n_chop_off / (n_load_off + 1); if(n_per_off < 1) { SError("Chop phase length on OFF position too long relative to load period."); } end_load_off = true; off_inttime = 2 * n_per_off * (n_load_off + 1) * data_time_off; off_pointing = off_inttime + halfloadlength + n_load_off * loadlength + jitterdead; } // Duration of initial set up // determine exact duration only in case of full commanding if(docommands) { int initlength = duration(HIFIInitObs()); initlength = initlength + duration(TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal")); // Add time for HK readout int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); initlength = initlength + hkduration; } else { initlength = GetRoughInitLength(band,lo_freq,false); } initlength = initlength + loadlength; // Compute the overall cycle length // First estimate of the load interval int n_loadinterval = imax(load_interval / (on_pointing + off_pointing),1); // Exception handling for very uneven phases if(end_load_on || end_load_off) { n_loadinterval = 1; } // dangling time given by readout dead time int dangling = readoutdead; // Return all the times needed for telescope call and post_timing processing return {on_inttime,off_inttime,on_pointing,off_pointing,loadlength,jitterdead,load_spacing,n_loadinterval,n_per_on,n_per_off,n_load_on,n_load_off,end_load_on,end_load_off,initlength,dangling}; } //////////////////////////////////////// // Standing wave analysis, procedure // This is like a radiometry: 4 spectra // retune version procedure Standing_wave_retune_fm_COP { string band = "1a"; // HIFI band int integ_time = 4; //Total integration time in sec. string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast double[] lo_freq_input = [500.0,500.15,0.02]; //Start, end and step lo_freq for the LO scan string los_code = "sc" in ["sc","sh","ss"]; //The line-of-sight code: sc (sky-CBB), sh (sky-HBB), ss (sky-sky) int nb_retune = 5; //frequency at which we retune }{ // Initial LO tuning at centre frequency of scan (NDW) // Not applicable here double lo_freq_ref = (lo_freq_input[0] + lo_freq_input[1]) / 2.0; //LO_tuning_block_fm(band, lo_freq_ref); double lo_freq = lo_freq_input[0]; // //WBS calibration and backend tuning if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band); WBS_tune_stndwave_proc_fm(band); } if(backend == "hrs" || backend == "both") { HRS_config_block_fm(band,hrs_mode); HRS_tune_block_fm(band); } // //Loop on LO frequencies. It is assumed that the LO is tuned at the middle frequency of the scan // int retune = 0; while(lo_freq <= lo_freq_input[1]) { // //We will retune at the running frequency every settings (starting with the first) retune = iround((lo_freq - lo_freq_input[0]) / lo_freq_input[2]) % nb_retune; if(retune == 0) { LO_tuning_block_fm(band,lo_freq); } else { //Set synthesizer to new LO freq. LCU_config_nominal_noretune_block_fm(band,lo_freq,lo_freq_ref); } // if(los_code == "sc") { //Pair towards sky-CBB Sky_Cold_fm_COP(band,integ_time,hrs_mode,backend); } if(los_code == "sh") { //Pair towards sky-HBB Sky_Hot_fm_COP(band,integ_time,hrs_mode,backend); } if(los_code == "ss") { //Pair towards sky-sky Sky_Sky_fm_COP(band,integ_time,hrs_mode,backend); } //Increase lo_freq lo_freq = lo_freq + lo_freq_input[2]; } } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the OTF observing mode procedure OTFFSwitchNoRef_commanding { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // chunk size given by the data rates and optimum speed int n_perline = 10; // Number of frequency switch cycles per line int n_linesperscan = 1; // Number of lines between two load holds int nlines_tot = 10; // Total number of lines to go bool end_load_on = false; // Need for load after each pointing phase int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,2,2,40,10,20,0]; // Timing of the observation from telescope int loadlength = 50; // Load duration }{ // Auxiliary variables // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time //////////////////////////////////////////////////////////////////////// // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // // Clustering is currently not implemented in MPS - switched off here int clustered = 0; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] rates = dataparms{1}; int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; bool runintostate = false; while(state[0] >= 0) { if(runintostate) { state = next_state_no_check(); } else { state = next_state(); } if(state[0] == 1) { // Initialization if(clustered != 1) { HIFIInitObs(); TuneHIFIFsw(band,lo_freq,freq_throw,hrs1,hrs2,wbs1{0},wbs2{0},"normal"); } delay(tinitslew - (time() - startobs) - loadlength - hkduration); HIFISetHK("normal",false); // First load measurement DoubleLoadMeasurement(band,lo_freq,freq_throw,eff_resolution{0},data_time,backendreadoutparms); runintostate = false; } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 8) { // OTF integration // Check whether this is the first line if((state[2] + n_linesperscan - 1) % n_linesperscan == 0) { HIFIConfigureFSwitchIntegration(data_time,n_perline,band,lo_freq,backendreadoutparms); } HIFIFSwitchOnIntegration(data_time,n_perline,band,lo_freq,rates); runintostate = false; } if(state[0] == 6) { delay(readoutdead); DoubleLoadMeasurement(band,lo_freq,freq_throw,eff_resolution{0},data_time,backendreadoutparms); if(state[2] * state[3] == nlines_tot) { runintostate = true; } else { runintostate = false; } } if(state[0] == 5) { // apply only if I do not come from a load-hold if(!runintostate) { delay(readoutdead); if(end_load_on) { // Perform final load measurement DoubleLoadMeasurement(band,lo_freq,freq_throw,eff_resolution{0},data_time,backendreadoutparms); } } runintostate = false; HIFICloseObs(); } } } // BLOCK : Functional Test No 2 (HRS Correlation modes Test) block HRS_functional_test_No_2_Corr_block_fm HIFI 3623 { string band = "1a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int integ_time = 4; //Total integration time in sec. string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); int repeats = 5; //Fill in block parameter names for each mode - consequence of SPR-0198 string[] hrs_blocks_corr_ultra = ["corr_ultra","corr_ultra","corr_ultra","corr_ultra","corr_ultra","corr_ultra","corr_ultra","corr_ultra"]; string[] hrs_blocks_corr_wide = ["corr_wide","corr_wide","corr_wide","corr_wide","corr_wide","corr_wide","corr_wide","corr_wide"]; string[] hrs_blocks_corr_low = ["corr_hilonom","low","corr_low","low_nominal","corr_low_nom","low","corr_low","high_nominal_low"]; string[] hrs_blocks_corr_nom = ["corr_hilonom","high_nominal","high_nominal","low_nominal","corr_low_nom","high_nominal","high_nominal","high_nominal_low"]; string[] hrs_blocks_corr_high = ["corr_hilonom","high_nominal","high_nominal","high","high","high_nominal","high_nominal","high_nominal_low"]; // Configure spectroscopy Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); // // Loops on the different configurations of the HRS //====================================== //Calls the 5 modes to be checked //Corr_ultra Hifi_HIFI_Config_HRS_H_blocks($BBID,hrs_blocks_corr_ultra[0],hrs_blocks_corr_ultra[1],hrs_blocks_corr_ultra[2],hrs_blocks_corr_ultra[3],hrs_blocks_corr_ultra[4],hrs_blocks_corr_ultra[5],hrs_blocks_corr_ultra[6],hrs_blocks_corr_ultra[7]); //delay(1); Hifi_HIFI_Config_HRS_V_blocks($BBID,hrs_blocks_corr_ultra[0],hrs_blocks_corr_ultra[1],hrs_blocks_corr_ultra[2],hrs_blocks_corr_ultra[3],hrs_blocks_corr_ultra[4],hrs_blocks_corr_ultra[5],hrs_blocks_corr_ultra[6],hrs_blocks_corr_ultra[7]); delay(1); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // //Corr_wide Hifi_HIFI_Config_HRS_H_blocks($BBID,hrs_blocks_corr_wide[0],hrs_blocks_corr_wide[1],hrs_blocks_corr_wide[2],hrs_blocks_corr_wide[3],hrs_blocks_corr_wide[4],hrs_blocks_corr_wide[5],hrs_blocks_corr_wide[6],hrs_blocks_corr_wide[7]); //delay(1); Hifi_HIFI_Config_HRS_V_blocks($BBID,hrs_blocks_corr_wide[0],hrs_blocks_corr_wide[1],hrs_blocks_corr_wide[2],hrs_blocks_corr_wide[3],hrs_blocks_corr_wide[4],hrs_blocks_corr_wide[5],hrs_blocks_corr_wide[6],hrs_blocks_corr_wide[7]); delay(1); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // //Corr_low Hifi_HIFI_Config_HRS_H_blocks($BBID,hrs_blocks_corr_low[0],hrs_blocks_corr_low[1],hrs_blocks_corr_low[2],hrs_blocks_corr_low[3],hrs_blocks_corr_low[4],hrs_blocks_corr_low[5],hrs_blocks_corr_low[6],hrs_blocks_corr_low[7]); //delay(1); Hifi_HIFI_Config_HRS_V_blocks($BBID,hrs_blocks_corr_low[0],hrs_blocks_corr_low[1],hrs_blocks_corr_low[2],hrs_blocks_corr_low[3],hrs_blocks_corr_low[4],hrs_blocks_corr_low[5],hrs_blocks_corr_low[6],hrs_blocks_corr_low[7]); delay(1); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // //Corr_nominal Hifi_HIFI_Config_HRS_H_blocks($BBID,hrs_blocks_corr_nom[0],hrs_blocks_corr_nom[1],hrs_blocks_corr_nom[2],hrs_blocks_corr_nom[3],hrs_blocks_corr_nom[4],hrs_blocks_corr_nom[5],hrs_blocks_corr_nom[6],hrs_blocks_corr_nom[7]); //delay(1); Hifi_HIFI_Config_HRS_V_blocks($BBID,hrs_blocks_corr_nom[0],hrs_blocks_corr_nom[1],hrs_blocks_corr_nom[2],hrs_blocks_corr_nom[3],hrs_blocks_corr_nom[4],hrs_blocks_corr_nom[5],hrs_blocks_corr_nom[6],hrs_blocks_corr_nom[7]); delay(1); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // //Corr_high Hifi_HIFI_Config_HRS_H_blocks($BBID,hrs_blocks_corr_high[0],hrs_blocks_corr_high[1],hrs_blocks_corr_high[2],hrs_blocks_corr_high[3],hrs_blocks_corr_high[4],hrs_blocks_corr_high[5],hrs_blocks_corr_high[6],hrs_blocks_corr_high[7]); //delay(1); Hifi_HIFI_Config_HRS_V_blocks($BBID,hrs_blocks_corr_high[0],hrs_blocks_corr_high[1],hrs_blocks_corr_high[2],hrs_blocks_corr_high[3],hrs_blocks_corr_high[4],hrs_blocks_corr_high[5],hrs_blocks_corr_high[6],hrs_blocks_corr_high[7]); delay(1); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // //} } // Diplexer calibration for a given mixer band with hotcold measurements // Measures hot and cold series at diplexer settings between two minima of // mixer coupling procedure Diplexer_calibration_hotcold_proc_fm { string band = "3a" in ["3a","3b","4a","4b","6a","6b","7a","7b"]; // HIFI LO band double lo_freq = 807.0; //LO frequency }{ // Check_Band_vs_Freq_proc_fm(band,lo_freq); // double if_freq = 6.0; if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { if_freq = 3.6; {double,string}[] result = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,lo_freq); double bias_max_h = result[0]{0}; double bias_max_v = result[1]{0}; result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); double bias_normal_h = result[0]{0}; double bias_normal_v = result[1]{0}; } //Fetch diplexer settings for the scan: we may jump over a period of the tooth //So we need to assess the slope to have a symetrical scan. //Previous minima double[] result_dip = Get_Diplexer_setting(band,lo_freq - if_freq / 2.0); double diplex_H_prev = result_dip[0]; double diplex_V_prev = result_dip[1]; //Optimum value result_dip = Get_Diplexer_setting(band,lo_freq); double diplex_H_opt = result_dip[0]; double diplex_V_opt = result_dip[1]; //Next minima result_dip = Get_Diplexer_setting(band,lo_freq + if_freq / 2.0); double diplex_H_next = result_dip[0]; double diplex_V_next = result_dip[1]; //Get effective span double diplex_H_max = max(diplex_H_prev,diplex_H_next); double diplex_V_max = max(diplex_V_prev,diplex_V_next); double diplex_H_min = min(diplex_H_prev,diplex_H_next); double diplex_V_min = min(diplex_V_prev,diplex_V_next); // double diplex_H_span = 2.0 * (diplex_H_opt - diplex_H_min); double diplex_H_start = diplex_H_min; double diplex_H_end = min(diplex_H_min + diplex_H_span,2.24); double diplex_V_span = 2.0 * (diplex_V_opt - diplex_V_min); double diplex_V_start = diplex_V_min; double diplex_V_end = min(diplex_V_min + diplex_V_span,2.24); // if(diplex_H_opt < diplex_H_next) { diplex_H_span = 2.0 * (diplex_H_prev - diplex_H_opt); diplex_H_end = diplex_H_prev; diplex_H_start = max(diplex_H_end - diplex_H_span,-2.24); } if(diplex_V_opt < diplex_V_next) { diplex_V_span = 2.0 * (diplex_V_prev - diplex_V_opt); diplex_V_end = diplex_V_prev; diplex_V_start = max(diplex_V_end - diplex_V_span,-2.24); } if(diplex_H_opt > diplex_H_prev) { diplex_H_span = 2.0 * (diplex_H_opt - diplex_H_next); diplex_H_start = diplex_H_next; diplex_H_end = min(diplex_H_start + diplex_H_span,2.24); } if(diplex_V_opt > diplex_V_prev) { diplex_V_span = 2.0 * (diplex_V_opt - diplex_V_next); diplex_V_start = diplex_V_next; diplex_V_end = min(diplex_V_start + diplex_V_span,2.24); } // //Re-compute adjusted spans: they know ensure scans within the [-2.24,+2.24] mA range diplex_H_span = diplex_H_end - diplex_H_start; diplex_V_span = diplex_V_end - diplex_V_start; //Hard-coded values: int n_steps = 20; double stepTime = 0.1; //Step time in seconds: GRANULARITY IS 0.1sec!!!! double diplexer_current_step = -1.0 * min(diplex_H_span,diplex_V_span) / double(n_steps - 1); // //Set FPU at operational frequency Init_MSA_HBB_fm(band,"CLOSE",lo_freq,"ON"); Chopper_Rotation_block_fm(band,"chop_M3_ang","chop_hot_ang"); //Perform LO tuning at optimum diplexer settings and a target of 0.035mV LO_tuning_w_targetC_block_fm(0.035,band,lo_freq,"H"); //Set diplexers to the starting value to tune HRS Set_Diplexer_current_block_fm(diplex_H_end,diplex_V_end); // //Configure HRS: use hard-coded configuration: wb1 for SIS, wb8 for HEB string[] hrs_mode = ["wb1","wb1"]; if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { hrs_mode = ["wb8","wb8"]; } // //Configure spectroscopy for slowchop hotcold int integ_time = 2; string backend = "hrs"; int[] res = Configure_Spectrometer_hc_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); int total_time = res[0] * res[1]; // HRS_config_block_fm(band,hrs_mode); HRS_tune_block_fm(band); // //In case of band 6 or 7, use special procedure if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { //Exit from oscillation regime Mixerbias_block_fm(bias_max_h,bias_max_v); Mixerbias_block_fm(bias_normal_h,bias_normal_v); //Get back to optimum diplexers result_dip = Get_Diplexer_setting(band,lo_freq); Set_Diplexer_current_block_fm(result_dip[0],result_dip[1]); //Take hotcold spectrum Hot_cold(band,hrs_mode,backend,total_time,"slowchop",20,1); //Do first half scan: start value needs to be above the middle double diplex_H_first = result_dip[0] + abs(diplexer_current_step) / 2.0; double diplex_V_first = result_dip[1] + abs(diplexer_current_step) / 2.0; Scan_diplexer_IF_block_fm(band,diplex_H_first,diplex_V_first,diplexer_current_step,11,stepTime,lo_freq); //Get back to optimum diplexers result_dip = Get_Diplexer_setting(band,lo_freq); Set_Diplexer_current_block_fm(result_dip[0],result_dip[1]); //Take hotcold spectrum Hot_cold(band,hrs_mode,backend,total_time,"slowchop",20,1); //Do second half scan: start value needs to be below the middle double diplex_H_second = result_dip[0] - abs(diplexer_current_step) / 2.0; double diplex_V_second = result_dip[1] - abs(diplexer_current_step) / 2.0; Scan_diplexer_IF_block_fm(band,diplex_H_second,diplex_V_second,-1.0 * diplexer_current_step,11,stepTime,lo_freq); } else { //Perform scan Scan_diplexer_IF_block_fm(band,diplex_H_end,diplex_V_end,diplexer_current_step,n_steps,stepTime,lo_freq); // } //Get back to optimal settings result_dip = Get_Diplexer_setting(band,lo_freq); Set_Diplexer_current_block_fm(result_dip[0],result_dip[1]); if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { //Take hotcold spectrum ? Hot_cold(band,hrs_mode,backend,total_time,"slowchop",20,1); } // } // Procedure to compute all parameters needed in a Configure_spectroscopy {int,int,int,int,int,int,int,int,int,int,int,int,int} procedure FastConfigureSpectroscopyParams { /* Integration time */ int data_time = 10 in [4,128]; // data dump interval int n_int = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_data = 2; // Integration time counter /* Parameters determining the delays - used in calibration reader */ string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency /* Backend settings */ bool wbs_used = true; // whether at least one WBS is used }{ // Get fixed parameters from configuration and calibration files // WBS delta time given by switch dead time double res = GetSkyChopDeadTime(band,lo_freq); int del_wbs = iceil(res * 1000.0); // Additional delays in the readout loops - given in OBS user manual {double,string}[] result = ConfigurationReader("name_delays",["add_hrs","add_wbs","add_jitter","wbs_readout","wbs_chunksize","tacc_add","max_hrs_phase","wbs_init","scos_jitter"],band,lo_freq); int add_hrs = iround(result[0]{0}); int add_wbs = iround(result[1]{0}); int add_jitter = iround(result[2]{0}); int wbs_readout = iround(result[3]{0}); int wbs_chunksize = iround(result[4]{0}); int tacc_add = iround(result[5]{0}); int max_hrs_phase = iround(result[6]{0}); int wbs_init = iround(result[7]{0}) + iround(result[8]{0}); // In fast chop del_hrs can be zero, but see SCR 854 int del_hrs = add_jitter; // WBS // Fixed parameter - we never split a transfer int n_wbs_integr = 1; int n_wbs1 = 2 * n_int; int n_wbs_start = n_data; // HRS is integrated up as long as the WBS int n_hrs_integr = n_int; // Split data_time into chop phases // Dead time per read out (not clear whether add_wbs applies here) int tdead_data = 2 * (wbs_readout + add_jitter) + add_wbs - add_jitter; // Initial dead time - distribute over all readouts int tdead_init = (wbs_init + n_data - 1) / n_data; int chop_phase = (1000 * data_time - tdead_data - tdead_init) / (2 * n_int); // dead time has to be an integer multiple of the 10ms chunk time int tdead_chop = del_wbs + add_jitter; int nchunk = (tdead_chop - 1) / wbs_chunksize + 1; int tcorr = nchunk * wbs_chunksize - tdead_chop; del_wbs = del_wbs + tcorr; tdead_chop = tdead_chop + tcorr; // Accumulation time int t_acc_wbs = chop_phase - tdead_chop; // discretize in 10ms chunks nchunk = (t_acc_wbs - tacc_add) / wbs_chunksize; t_acc_wbs = nchunk * wbs_chunksize + tacc_add; // HRS // Fixed parameter here int r_hrs = 1; int t_acc_hrs = t_acc_wbs - add_jitter - del_hrs - add_hrs; if(t_acc_hrs > max_hrs_phase) { SError("Chop phase length too long for HRS. Increase chop frequency."); } // How many HRS integrations possible during WBS readout int t_hrs_per = t_acc_hrs + del_wbs + add_hrs; int n_hrs_trans = wbs_readout / t_hrs_per; // This currently does not work - SCR 854: skipped n_hrs_trans = 0; // Actual integration time and dead time per readout // If WBS is used count only the WBS time if(wbs_used) { tdead_chop = tdead_chop + tacc_add; int tint_act = nchunk * wbs_chunksize * n_wbs1 * n_data; } else { tdead_chop = tdead_chop + r_hrs * add_hrs; tdead_data = tdead_data + add_jitter - 2 * (n_hrs_trans * t_hrs_per - add_jitter); tint_act = t_acc_hrs * r_hrs * (n_wbs1 + 2 * n_hrs_trans) * n_data; } // Return all config_spectroscopy timing parameters return {n_wbs_start,r_hrs,n_wbs_integr,n_hrs_integr,del_hrs,del_wbs,t_acc_wbs,t_acc_hrs,n_wbs1,n_hrs_trans,tdead_chop,tdead_data,tint_act}; } // FPU Standby - CSA can be controlled - for use is chopper integrity checks. // Ensures that chopper will be commanded to zero-position // regardless of prime or redundant use. block Band0_chopper_at_zero_block_aot HIFI 6296 { string band = "0"; // HIFI band string chop_loop = "CLOSE"; // Chopper Loop status string hbb_heater = "ON" in ["ON","OFF"]; //hot source on/off }{ IError("Band0_chopper_at_zero_block_aot is deprecated. Use Init_MSA_aot instead."); } // Flexible WBS attenuator tuning block with variable target // Both polarizations are treated block WBS_attenuators_block HIFI 6613 { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978.2; //LO frequency string target_name = "normal"; // Name of target level bool oncold = false; // Whether we are on cold intead of HBB }{ // Get tuning goal double[] cresult = CalibrationReader("attenuator_levels",[target_name],band,lo_freq); double target_value = cresult[0]; // Correct value in case of cold LOS instead of HBB if(oncold) { // Get involved temperatures double tsys = InterpolateTsys(band,1000.0 * lo_freq); {double,double} tloads = LoadTemperatures(band,1000.0 * lo_freq); double hotlevel = tsys + tloads{0}; double coldlevel = tsys + tloads{1}; target_value = target_value * coldlevel / hotlevel; } else { RotateChopper(band,lo_freq,"chop_hot"); delay(1); } int tune_target = iround(100.0 * target_value); // Perform tuning Tune_WBS_aot(band,tune_target); } ///////////////////////////////////////////////////////////////// // Spectral scan in frequency switch without OFF calibration // {string,double,double}[] procedure HifiSScanProcFSwitchNoRefSequencerInit { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz int redundancy = 4 in [1,12]; // Frequency scan redundancy double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} effResolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz bool wbs1Used = true; // whether WBS1 is used bool wbs2Used = true; // whether WBS2 is used /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_cycles = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles per frequency and pointing int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode // nherit from load-chop mode {string,double,double}[] retvalues = HifiSScanProcLoadChopNoRefSequencerInit(naifid,ra,dec,band,lo_freq,lo_freq_up,redundancy,effResolution,wbs1Used,wbs2Used,data_time,n_cycles,n_freq_point,load_interval,docommands); return retvalues; } //HIFI-COP-1.2-HRS_FT obs HifiEng_HRS_FT_COP { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(HRS_FT_COP_proc_ops(prime_or_redundant)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution HRS_FT_COP_proc_ops(prime_or_redundant); } if(state[0] == 5) { HIFISetHK("normal",true); StopMode_block_ops(); } } } //Chopper health check: step#3 procedure Chopper_FT3_COP_proc_ops { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ //Get chopper ON in closed-loop with voltage at rest position string chop_startup_prime_red = "chop_startup_cold_prime"; if(prime_or_redundant == "Red") { chop_startup_prime_red = "chop_startup_cold_red"; } {double,string}[] result = ConfigurationReader("name_chopper",[chop_startup_prime_red],"0",0.0); Init_MSA_ops("0","CLOSE",0.0,result[0]{0},"ON",prime_or_redundant); Chopper_closed_loop_parameter_check_block_ops(prime_or_redundant); } ////////////////////////////////////////////////////////////////////////// // Procedure to compute detailed timing of OTF observing mode {int,{int,int,int,int,int,int,int,int},double,double} procedure OTFmap_post_timing { {int,int,int,int,int,int,int,int} pre_timing = {10,1,12,13,21,10,50,0}; // pre_timing parameter list int[] telescopetimes = [300,180,2,2,40,10,20,21,0]; int data_time = 4; // chunk size given by the data rates and optimum speed int n_linesperscan = 1; // Number of lines between two OFFs int n_cover = 1; // Number of map coverages int load_interval = 1800; // load period = f(band,lo_freq,eff_resolution{1}) }{ // Get all values from the pre_timing section int n_pp = pre_timing{0}; int n_scans = pre_timing{1}; int off_inttime = pre_timing{2}; int off_pointing = pre_timing{3}; int loadlength = pre_timing{4}; int n_loadinterval = pre_timing{5}; int initlength = pre_timing{6}; int dangling = pre_timing{7}; // Get all values from the telescope section int telinit = telescopetimes[1]; // Initial slew time int slewtime = telescopetimes[6]; // Slew time to OFF int longslew = telescopetimes[7]; // Actual slew time for load slew int tturn = telescopetimes[5]; // Turn around between lines int tline = telescopetimes[4]; // Time in line int tend = telescopetimes[8]; // Final deceleration time // The telescope slew can be a bit further than requested int line_inttime = n_pp * data_time; int line_time = line_inttime; if(tline != line_time) { if(tline < line_time) { CError("OTF scan length returned by telescope too short for instrument."); } else { line_time = tline; } } // Now compute the real scan time and the real load interval int scan_time = n_linesperscan * line_time + (n_linesperscan - 1) * tturn + 2 * slewtime + off_pointing; // Check for reasonable scan times if(scan_time > load_interval) { IError("Scan duration too long for required load period. " + "Reduce the map size or increase the step size."); } // Finally I can compute the actual load interval int load_spacing = CheckedLoadSpacing(load_interval - loadlength + slewtime,scan_time); n_loadinterval = load_spacing / scan_time; n_loadinterval = imin(n_loadinterval,32); // Make sure that load slews occur at the same position in each coverage n_loadinterval = IMultiple(n_loadinterval,n_scans); // Compute duration of measurement int tdead = imax(loadlength,slewtime); int normal_scan_time = n_linesperscan * line_time + (n_linesperscan - 1) * tturn + 2 * slewtime + off_pointing; int load_scan_time = n_linesperscan * line_time + (n_linesperscan - 1) * tturn + slewtime + tdead + off_pointing; int n_tot = n_scans * n_cover; int n_load = n_tot / n_loadinterval; int maptime = (n_tot - n_load) * normal_scan_time + n_load * load_scan_time; // The initial time is no longer contained in the total time // int totaltime=imax(initlength,telinit); int closelength = duration(HIFICloseObs()); dangling = imax(dangling + closelength - tend,0); int totaltime = maptime + off_pointing + dangling + tend; // Average dead and scan time for drift estimate double tscan = double(maptime) / double(n_tot); // Get pointing dead time, instrument dead time is added later double avdead = tscan - double(n_linesperscan * line_inttime + off_inttime); // show gyro-propagation messages GCPMessages(off_pointing,load_scan_time,tend); // Return all the times needed in the observing mode modules return {totaltime,{n_pp,n_scans,off_inttime,off_pointing,loadlength,n_loadinterval,initlength,dangling},tscan,avdead}; } // Global total power spectroscopy for stability measurement, procedure procedure Total_power_spectro_for_Stability_proc_fm { string band = "1a"; // HIFI band int n = 100; //The number of integrations int integ_time = 4; //Total integration time in sec. to be set at end of test string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code }{ //First derive backend setting codes as expected by VO's routine //Build up backend parameter tupple: {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = BackendSettings(band,0.0,hrs_mode,backend); // Readout parameters for HRS1,HRS2, WBS1,WBS2 //Compute data_time and n_switch using the wrapper int[] res = ConfigSlowChop(integ_time,"tp",band,0.0,backendreadoutparms); int data_time = res[0]; int n_switch = n * res[1]; //For stability measurement, the number of loop is a user input // Now call the spectroscopy setup: it is common to ILT and AOT CUS. // The deadtimes output is not used at ILT level. {double,double} dtimes = ConfigSpectroscopySlowChop(data_time,n_switch,"tp",band,0.0,backendreadoutparms,true); //Now start the long integration HIFI_Spectr_total_power_proc_fm(band,backend,data_time * n_switch); } {string,double,double}[] procedure HifiPointModeFSwitchSequencerInit { string modeName = "fs"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rates int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles on ON int n_switch_off = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles on OFF int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF calibration cycles int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode // limit on data rate {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // limits from noise section {double,double,double,double} phaselengths = FSwitchPhaseLengths(band,lo_freq,effResolution,oneGHzReference); // Compute derived quantities int data_time_guess = imin(imax(iceil(phaselengths{1}),datalimit),20); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } int n_switch_on_guess = imax(iceil(phaselengths{0} / (2.0 * double(data_time_guess))),1); int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } // OFF phase int data_time_off_guess = imin(imax(iceil(phaselengths{2}),datalimit),20); int data_time_off_range = datalimit - data_time_off_guess; if(data_time_off_range == 0) { data_time_off_range = 1; } int n_switch_off_guess = imax(iceil(double(data_time_guess * n_switch_on_guess) / (double(data_time_off_guess) * sqrt(phaselengths{3} / effResolution{1}))),1); int n_switch_off_range = 1 - n_switch_off_guess; if(n_switch_off_range == 0) { n_switch_off_range = 1; } // Add pointing requirements condition: >=10s {int,int} new_data_time = MatchMinPointing(data_time_guess,data_time_range,2 * n_switch_on_guess); data_time_guess = new_data_time{0}; data_time_range = new_data_time{1}; new_data_time = MatchMinPointing(data_time_off_guess,data_time_off_range,2 * n_switch_off_guess); data_time_off_guess = new_data_time{0}; data_time_off_range = new_data_time{1}; // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"data_time_off",double(data_time_off_guess),double(data_time_off_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)},{"n_switch_off",double(n_switch_off_guess),double(n_switch_off_range)}]; return retvalues; } //HIFI investigation of diplexer with M1, mode //Perform diplexer scans at a series of M1 values //Frequencies and M1 values to use are pre-tabulated obs HifiEng_diplexerscan_M1_COP { string band = "7b" in ["3b","5a","5b","7a","7b"]; // HIFI band int testblock = 1 in [0,3]; //Test block }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Diplexerscan_M1_proc_fm_COP(band,testblock)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Diplexerscan_M1_proc_fm_COP(band,testblock); } if(state[0] == 5) { HIFISetHK("normal",true); StopMode_block_ops(); } } } ///////////////////////////////////////////////////////////////// // Procedure to compute total dead times for the mode // {double,double,double,double,double} procedure DoubleChop_deadtimes { string chopmode = "chop" in ["chop","lchop","fs"]; // chop mode string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // data dump interval on ON int data_time_off = 4; // data dump interval on OFF int n_chop_on = 3; // number of chop cycles in one integration on ON int n_chop_off = 3; // number of chop cycles in one integration on OFF int n_load_on = 0; // number of integrations on ON -1 int n_load_off = 0; // number of integrations on OFF -1 double tdead = 10.0; // Dead time from telescope }{ ////////////////////////////////////////////////////////////////////// // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Get values for ON integration {double,double} tinst = GetInstDeadSlowChop(data_time,2 * n_chop_on,chopmode,band,lo_freq,backendreadoutparms); // dead time double tdeadint = double(data_time * 2 * n_chop_on) - tinst{0}; // subtract dead times in switches // keep dead times between A-A and B-B in total dead time tdeadint = tdeadint - double(n_chop_on) * tinst{1}; // add to total dead time double tdead_tot = tdead + double(n_load_on + 1) * tdeadint; double tswitch_on = tinst{1}; double tphaseint_on = tinst{0} / double(2 * n_chop_on); // OFF integration tinst = GetInstDeadSlowChop(data_time_off,2 * n_chop_off,chopmode,band,lo_freq,backendreadoutparms); // dead time tdeadint = double(data_time_off * 2 * n_chop_off) - tinst{0}; // subtract dead times in switches tdeadint = tdeadint - double(n_chop_off) * tinst{1}; // add to total dead time tdead_tot = tdead_tot + double(n_load_off + 1) * tdeadint; double tswitch_off = tinst{1}; double tphaseint_off = tinst{0} / double(2 * n_chop_off); // Return total dead time and the dead times in the two chops return {tdead_tot,tphaseint_on,tphaseint_off,tswitch_on,tswitch_off}; } //Set HIFI to primary mode, mode //In practice, it sets LOU in nominal mode with no channel selected obs HifiEngSetIntoPrimary { }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(HifiIntoPrimary()); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // switch to nominal settings HifiIntoPrimary(); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } ////////////////////////////////////////////////////////////////////// // Procedure to display performance parameters of the observing mode procedure OTFDoubleChop_performance { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {double,double,double,double,double} noisevalues = {1.0,1.0,1.0,1.0,0.0}; // Noise values from noisecomputer int totaltime = 200; // Total observing time int nlines = 20; // Number of lines in the map int npoints = 20; // Number of points in the map int n_switch_on = 1; // Supersamplingfactor int n_switch_off = 3; // Number of data dumps for the OFF integration time int n_scans = 2; // Number of OTF scans to cover the map int n_cycles = 1; // Number of map coverages bool fs = false; // whether frequency switch used double tscan = 60.0; // Total average duration of one scan {double,double,double,double,double} tact = {10.0,4.9,4.9,0.05,0.05}; // Field of actual dead and integration times }{ double inttimeperonphase = tact{1}; // Actual integration time in ON phase double inttimeperoffphase = tact{2}; // Actual integration time in OFF phase // Get performance of ideal instrument for comparison {int,double,double,double,double,double} idealvalues = IdealInstrument(band,lo_freq,eff_resolution,totaltime); double idealnoise = idealvalues{1} * idealvalues{1}; double obsnoise = noisevalues{0} * noisevalues{0}; // rescale for map coverage idealnoise = idealnoise * double(npoints * nlines); double efficiency = idealnoise / obsnoise; // Compute the actual integration time double posinttime = double(n_cycles * nlines * npoints * 2 * n_switch_on) * inttimeperonphase; double posofftime = double((n_cycles * n_scans + 1) * 2 * n_switch_off) * inttimeperoffphase; int instrumenttime = iceil(double(n_cycles * n_scans) * tscan + double(2 * n_switch_off) * inttimeperoffphase); // Check total integration time double timeefficiency = (posinttime + posofftime) / double(totaltime); // Noise contribution double relnoise = noisevalues{4} / (1.0 + noisevalues{4}); // Non-standard messages message("

"); message("The observed map consists of " + nlines + " OTF lines, each covering " + npoints + " readout points.
"); // General messages PerformanceMessages(band,lo_freq,totaltime,posinttime,posofftime,timeefficiency,efficiency,relnoise,fs); } mode HifiManCmd_HIFI_Simulate_PU { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! }{ mois_comment("Performing simulation of HIFI Peak-up packet report arrival"); mois_tmcheck("The instrument can be in Standby I, Standby II or Primary modes in closed loop or open loop contexts for this test"); // StartMode_block_ops(); // //Simulate generation of PU report packet Simulate_PU_block_ops(); StopMode_block_ops(); } // LCU configuration into NOMINAL mode for FSW, procedure // It allows to set LSU frequency to lo_freq, but effectively // using the chain settings of lo_freq_setting // Uses best guess D2 voltage from confgilcu table procedure LCU_config_nominal_FSW_proc_fm { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency at which to set LSU double lo_freq_setting = 501.0; //LO frequency at which to take the settings }{ //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlcutune = "name_configlcutune_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq_setting); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1_v = result[0]{1}; string curlim2_v = result[1]{1}; // result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); //Fetch best guess, and clip to blue max double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lo_freq); drain2_v = min(result[0]{0},drain2_bluemax); //Send command: expect that we have already switched to NOMINAL //We set D2 to best guess and wait some time to stabilize chain temperature HIFI_Configure_LCU_block_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum,config_lo_delay); // } ///////////////////////////////////////////////////////////////// // Procedure to compute total dead times for the mode // {double,double,double} procedure SingleChop_deadtimes { string chopmode = "chop" in ["chop","lchop","fs"]; // chop mode string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // data dump interval int n_chop = 3; // number of chop cycles in one integration }{ ////////////////////////////////////////////////////////////////////// // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Get values for ON integration {double,double} tinst = GetInstDeadSlowChop(data_time,2 * n_chop,chopmode,band,lo_freq,backendreadoutparms); // only dead times in switches count as dead time; double tdead = double(data_time * 2 * n_chop) - tinst{0}; // subtract dead times in switches // keep dead times between A-A and B-B in total dead time tdead = tdead - double(n_chop) * tinst{1}; // add to total dead time double tswitch = tinst{1}; double tphaseint = tinst{0} / double(2 * n_chop); // Return total dead time and the dead times in the two chops return {tdead,tphaseint,tswitch}; } //HIFI-COP-2.1-IF-FBk1 procedure IF_FBk_COP_proc_ops { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency string[] hrs_mode = ["wb1","wb1"]; int integ_time = 600; string backend = "both"; }{ //Do not switch-off LO, rather, use the 3b-dissipative mode //LCU_switch_off_block_fm(); string band_dissipate = "3b"; double lofreq_dissipate = 958.0; double[] cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band_dissipate,lofreq_dissipate); double drain2_v = cresult[0]; LCU_config_nominal_w_D2_proc_fm(band_dissipate,lofreq_dissipate,drain2_v); // Put heaters explicitly to 4 V HL_heater_block_aot(band_dissipate,"nominal"); // string[] chop1 = ["chop_M3","chop_M3","chop_M3","chop_M3","chop_cold"]; string[] chop2 = ["chop_M3","chop_cold","chop_M3","chop_hot","chop_hot"]; {double,string}[] result_d = ConfigurationReader("name_confilfpu",[chop1[0],chop2[0]],band,0.0); int[] res = [0,0]; // Init_MSA_fm(band,"CLOSE",lo_freq,"ON"); //Set magnets to 0 Set_Magnet_current_block_fm(0.0,0.0); //Use high biases result_d = ConfigurationReader("name_confilfpu",["bias_high_resistive_h","bias_high_resistive_v"],band,lo_freq); Mixerbias_block_fm(result_d[0]{0},result_d[1]{0}); WBS_calib_fm(band); WBS_tune_proc_fm(band); HRS_config_block_fm(band,hrs_mode); HRS_tune_block_fm(band); //Reference measurement result_d = ConfigurationReader("name_confilfpu",[chop1[0],chop2[0]],band,0.0); res = Configure_Spectrometer_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); Spectro_slow_chop_block_fm(band,[result_d[0]{0},result_d[1]{0}],res,backend); // //For trend monitoring repeat, we want to do only index 1 for(int i = 1 .. 1) { // for(int i = 1 .. 4) { // result_d = ConfigurationReader("name_confilfpu",[chop1[i],chop2[i]],band,0.0); if(i == 2) { result_d[1]{0} = result_d[1]{0} - 0.5; } Spectro_slow_chop_block_fm(band,[result_d[0]{0},result_d[1]{0}],[integ_time * 2,1],backend); } // //Bias to nominal {double,string}[] result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); Mixerbias(result[0]{0},result[1]{0}); //Magnets back to nominal, via max result = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,lo_freq); Set_Magnet_current_proc_fm(result[0]{0},result[1]{0}); result = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); Set_Magnet_current_proc_fm(result[0]{0},result[1]{0}); } ///////////////////////////////////////////////////////////////// // Procedure to compute detailed timing for a // Spectral Scan DBS observing mode // // We currently assume that each nodding motion is related to an // instrument calibration. This may be an efficiency limitation if // more calibration measurements are needed. Then the loop sequence // should be changed. // // This implementation assumes that the whole scan can be performed // with a single pointing command. If the system temperature varies // too much so that it cannot be compensated by a slight change of // the redundancy, the scan has to be split into several calls of this // mode. // {{int,int,int,int,int,int,int,int,int,bool,int,int,int},{int,double,double[],int[][],bool,double[],int,bool}} procedure FastSScanDBS_pre_timing { string band = "4a"; // HIFI band double lo_freq_low = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz int redundancy = 4; // Frequency scan redundancy {double,double} eff_resolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 10 in [4,80]; // data dump interval int n_int = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_data = 1 in [1,1800]; // number of data transfer cycles per pointing int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int n_cycles = 1 in [1,600]; // Number of half OFF-ON-ON-OFF cycles at one frequency int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Create composite readout structure for backends {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // First check the group length // The default frequency group length is given by n_freq_point. // It is derived in the sequencer using // GetFNoCalibLength(band,ref_freq); // For n_cycles>1 it has to be unity, everything else is rejected // We rely on the sequencer to determine the best group length if(n_cycles > 1 && n_freq_point > 1) { SError("Only frequency group length 1 allowed for cycle numbers > 1."); } // Get frequency grid characteristic parameters {int,double,double[],int[][],int,bool} fqparms = MakeFreqGrid(band,lo_freq_low,lo_freq_up,redundancy,0.0,n_freq_point); double reffreq = fqparms{1}; double[] freqgrid = fqparms{2}; int[][] grouporder = fqparms{3}; // Process tuning level grid double[][] levelgrid = GetSScanLevelGrid(band,wbs1,wbs2,freqgrid,fqparms{0},grouporder); {bool,double[]} targets = TargetLevels(band,reffreq,levelgrid); bool retuning = targets{0}; double[] targetgrid = targets{1}; string reftarget = ""; if(retuning) { reftarget = "sscan_normal"; } {int,double,double[],int[][],bool,double[],int,bool} spectralparms = {fqparms{0},reffreq,freqgrid,grouporder,retuning,targetgrid,fqparms{4},fqparms{5}}; ////////////////////////////////////////////////////////////////////// // Get timing within the normal DBS observations // Fixed timings in the fast-chop mode int readouttime = data_time; int jitterdead = GetMaxTimeJitter(band,reffreq); // Integration time per frequency and pointing int inttime = readouttime * n_data; // Check chopper frequency CheckFastChopFrequency(band,reffreq,data_time,n_int,n_data); // Compute load integration time int load_datatime = GetStdLoadReadout(band,reffreq); int loadlength = duration(SScanLoadMeasurement(band,reffreq,reffreq,true,eff_resolution{0},load_datatime,backendreadoutparms)); int readoutdead = FastChopReadoutDelay(band,reffreq,backendreadoutparms); loadlength = loadlength + readoutdead; // The load interval int load_spacing = CheckedLoadSpacing(load_interval - loadlength,8); // Duration of initial set up // Staying at the same frequency makes no sense here. // First frequency point double runningfreq = freqgrid[grouporder[0][0]]; // determine exact duration only in case of full commanding if(docommands) { int initlength = duration(HIFIInitObs()); initlength = initlength + duration(TuneHIFI(band,runningfreq,hrs1,hrs2,wbs1{0},wbs2{0},"sscan_normal")); // Add time for HK readout int hkduration = HkReadoutTime(band,reffreq,backendreadoutparms,true); initlength = initlength + hkduration; } else { initlength = GetRoughInitLength(band,runningfreq,false); } initlength = initlength + loadlength; // Tuning delays, big tune step has to be devisable by 2 int bigtunestep = duration(HIFIRetuneFreq(band,reffreq,reftarget)); // Correct for variation within the band int tunediff = ComputeLOTimeDifference(band,lo_freq_low,lo_freq_up,reffreq); bigtunestep = bigtunestep + tunediff; if(n_freq_point > 1) { int smallstep = duration(HIFIChangeFreq(band,reffreq)); } else { smallstep = bigtunestep; } // For double phases I can use the added jitterdead in both phases for tune int halftunestep = (bigtunestep - jitterdead + 1) / 2; // Check load_interval allowance int scan_time = 2 * inttime + bigtunestep; if(scan_time > load_spacing) { SError("Load interval of " + load_interval + "s is exceeded by nodding " + "period of " + scan_time + " s."); } // Rough estimate of the pointing time to issue a representative // telescope command if(n_cycles > 1) { // How often do I have to perform a load slew int n_loadinterval = imax(load_interval / scan_time,1); // fit with n_cycles n_loadinterval = imin(n_loadinterval,n_cycles); n_loadinterval = IMultiple(n_loadinterval,n_cycles); // Pointing time int pointing = inttime + jitterdead; } else { n_loadinterval = 1; pointing = n_freq_point * inttime + (n_freq_point - 1) * smallstep + halftunestep + jitterdead; } int n_bchop = n_data; // recompute load length during slews in case of short integrations // This regime must be maintained in the post_timing if(n_loadinterval <= 1) { loadlength = duration(SScanLoadMeasurement(band,reffreq,reffreq,false,eff_resolution{0},load_datatime,backendreadoutparms)); loadlength = loadlength + readoutdead; } // No dangling needed in this mode - we stop halftunelength before telescope int dangling = 0; bool end_load = false; // Return all the times needed for telescope call and post_timing processing return {{inttime,pointing,readouttime,loadlength,jitterdead,load_spacing,bigtunestep,n_loadinterval,n_bchop,end_load,smallstep,initlength,dangling},spectralparms}; } // Give sequence of frequency steps in a spectral scan mode within one group int[][] procedure GetFrequencyGroupSteps { int groupsize = 3; // Number of frequencies in a group }{ // Compute limits int center = groupsize / 2; // First side stepping int[] firstside = []; int counter = 0; int i1 = center - 1; while(i1 >= 0) { firstside[counter] = i1; i1 = i1 - 1; counter = counter + 1; } i1 = groupsize - 1; while(i1 >= center) { firstside[counter] = i1; i1 = i1 - 1; counter = counter + 1; } // Second side stepping int[] secondside = []; counter = 0; i1 = center; while(i1 >= 0) { secondside[counter] = i1; i1 = i1 - 1; counter = counter + 1; } i1 = groupsize - 1; while(i1 > center) { secondside[counter] = i1; i1 = i1 - 1; counter = counter + 1; } int[][] fullseq = [firstside,secondside]; return fullseq; } ////////////////////////////////////////////////////////////////////////// // Procedure to compute detailed timing of OTF load-chop observing mode {int,int,int,int,bool,int,int} procedure OTFLoadChopNoRef_pre_timing { int nlines = 1; // Number of rows in the map int npoints = 10; // Number of data dumps per row string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4 in [1,20]; // chunk size given by the data rates and optimum speed int n_chop_on = 2 in [1,3600]; // number of half nu1-nu2-nu2-nu1 cycles per point int n_cycles = 1 in [1,1200]; // Number of map coverages int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // First check validity of frequencies CheckLOFrequencies(band,lo_freq,lo_freq); // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // First perform consistency checks // Check chunk size given by the data rates CheckDataTaking(backendreadoutparms,data_time); // jitter treatment is already taken into account by ValidMapSize // Compute parameters for the instrument timing int lineint = npoints * n_chop_on * 2 * data_time; int nlines_tot = nlines * n_cycles; // compute load integration time int loadlength = duration(LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms)); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); loadlength = loadlength + readoutdead; // Compute the scan size from the load interval int load_spacing = CheckedLoadSpacing(load_interval - loadlength,npoints * 8); // Here, we do not know the turn around-time yet. Ignored until post_timing int n_loadinterval = load_spacing / lineint; if(n_loadinterval < 1) { SError("Scan duration too long for load period. " + "Reduce the number of chop cycles."); } // Make sure that load slews occur at the same position in each coverage CheckReasonableLineNumber(nlines,true); n_loadinterval = IMultiple(n_loadinterval,nlines); // If no load required parameter has to be 0 if(n_loadinterval > nlines_tot) { // Determine need for final load measurement double rest = double(nlines_tot % n_loadinterval) + 0.5; bool end_load_on = rest > 0.5001 * double(n_loadinterval); } else { if(n_loadinterval > nlines) { n_loadinterval = nlines; } // In all these cases a final load will be made anyway in regular pattern end_load_on = false; } // Duration of initial set up // determine exact duration only in case of full commanding if(docommands) { int initlength = duration(HIFIInitObs()); initlength = initlength + duration(TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal")); // Add time for HK readout int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); initlength = initlength + hkduration; } else { initlength = GetRoughInitLength(band,lo_freq,true); } initlength = initlength + loadlength; // Dangling load measurement not counted here, only dangling readout int dangling = readoutdead; // Return all the times needed in the observing mode modules // The holdlength parameter is abused for lineint here return {loadlength,load_spacing,n_loadinterval,lineint,end_load_on,initlength,dangling}; } //LO parameter scan with HotCold measurement //for Band 1a procedure LCU1a_power_scan_with_Tsys { string band = "1a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4 double lo_freq = 500.0 in [488.0,552.0]; //LO frequency double param_min = 1.0; //Min. of scanned parameter double param_max = 2.0; //Max. of scanned parameter double step_size = 0.1; //Step size string param_name = "D2"; //Code of scanned parameter: M1,M2,G1,G2,D1,D2. int integ_time = 4; //Total integration time in sec. }{ error("This module is obsolete: use LCU_power_scan_with_Tsys instead"); } {string,double,double}[] procedure HifiSScanModeFSwitchNoRefSequencerInit { string modeName = "fs-freq"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_cycles = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles per frequency and pointing int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode // nherit from load-chop mode {string,double,double}[] retvalues = HifiSScanProcLoadChopNoRefSequencerInit(naifid,ra,dec,band,lo_freq,lo_freq_up,redundancy,effResolution,wbs1Used,wbs2Used,data_time,n_cycles,n_freq_point,load_interval,docommands); return retvalues; } // Noise ratio from a two-phase observation // double procedure TwoPhaseNoiseRatio { double x = 0.1; // value for integration time relative to Allan time double[] parameters = [0.3,2.5]; // Parameters: delay relative to Allan time, drift exponent }{ // Assign parameters double d = parameters[0]; double alpha = parameters[1]; // get radiometric and drift noise double yn = TwoPhaseRadioNoise(x); double yd = TwoPhaseDrift(x,d,alpha); // Compute ratio double y = yd / yn; return y; } // Set the whole instrument from standby I to standby II mode // This only switches on the WBS lasers mode HifiManCmd_HIFI_standbyI_to_standbyII { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! string laser_H = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-V laser to be set ON string chopper_loop = "OPEN" in ["OPEN","CLOSE"]; //chopper loop status string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ Mode_status_check_standby_I(chopper_loop,"up",prime_or_redundant); mois_comment("Set HIFI to standby mode II with " + laser_H + " switched on and chopper loop " + chopper_loop); StartMode_block_ops(); //WBS stand-by with lasers ON mois_step("Switch WBS-H and WBS-V lasers ON"); WBS_standby_block_ops("0",laser_H,laser_V); // StopMode_block_ops(); Mode_status_check_standby_II(laser_H,laser_V,chopper_loop,"up",prime_or_redundant); } // LCU configuration into NOMINAL mode with ALL inputs, procedure procedure LCU_config_nominal_ALL_proc_fm { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency double m1_v = 7.0; // HL_M1_V double m2_v = 7.0; // HL_M2_V double m3_v = 0.0; // HL_M3_V double gate1_v = -0.5; // HL_Gate1_V double gate2_v = -0.1; // HL_Gate2_V double drain1_v = 2.0; // Drain1 voltage in V double drain2_v = 1.4; //Drain2 voltage in V }{ //Clear potential failure mode Set_LO_Nominal_block_fm(); // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; int d2_step = iround(result[1]{0}); // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1_v = result[0]{1}; string curlim2_v = result[1]{1}; // result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); // //Send command: expect that we have already switched to NOMINAL //Contrary to QM, the channel is automatically switched ON HIFI_Configure_LCU_ALL_block_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum,config_lo_delay); // } //////////////////////////////////////////////////////////////////////// // Noise contributions from an asymmetric double difference observation // This is still to be scaled by a factor T_cycle/(B_fluct*T_obs) {double,double} procedure DoubleDifferenceNoiseValues { double x = 0.1; // value for integration time relative to Allan time double[] parameters = [1.0,1.0,0.8,0.8,0.05,0.3,2.5,5.0,2.5]; // Parameters: ratio of integration times, ratio of effective resolutions, delay in phase1, in phase 2, between phases relative to Allan time, drift exponents }{ // Assign parameters double xrat = parameters[0]; // ratio of integration times within B/A phases double resrat = parameters[1]; // ratio of effective resolutions B/A phases double tpa = parameters[2]; // total length of A pointing phase double tpb = parameters[3]; // total length of B pointing phase double dpos = parameters[4]; // dead time within A pointing relative to system Allan double d = parameters[5]; // position switch dead time relative to differential Allan double alpha = parameters[6]; // drift exponent of system Allan double dallanrat = parameters[7]; // ratio of differential to system Allan time double dalpha = parameters[8]; // drift exponent of differential Allan // Noise from first phase double yn = TwoPhaseRadioNoise(x); double yd = TwoPhaseDrift(x,dpos,alpha); // Normalize relative to total length of pointing phase double ysumn = yn * (2.0 * x + dpos) / tpa; double ysumd = yd * (2.0 * x + dpos) / tpa; // Noise from second phase // Rescale time scales double allan_scale = pow(1.0 / resrat,1.0 / alpha); // rescale Allan yn = TwoPhaseRadioNoise(x * xrat / allan_scale); yd = TwoPhaseDrift(x * xrat / allan_scale,dpos / allan_scale,alpha); // Noise scaled with resolution // Normalize relative to total length of pointing phase ysumn = ysumn + yn / (resrat * allan_scale) * (2.0 * x * xrat + dpos) / tpb; ysumd = ysumd + yd / (resrat * allan_scale) * (2.0 * x * xrat + dpos) / tpb; // Drift between phases yd = AsymmetricDrift(tpa / dallanrat,tpb / dallanrat,d / dallanrat,dalpha); // Compensate for different Allan time scaling yd = yd / dallanrat; ysumd = ysumd + yd; return {ysumn,ysumd}; } // Detector heater control block Heater_warm_fm HIFI 3241 { string band = "1a"; }{ Start_block(); //Get name of FPU configuration file {double,string}[] result_d = ConfigurationReaderWarm("name_confilfpu",["normal_heater_time_h","normal_heater_time_v","heater_delay_h","heater_delay_v","magnet_current_max_h","magnet_current_max_v"],band,0.0); double normal_heater_time_h = result_d[0]{0}; //SCR-1385: set to 2sec double normal_heater_time_v = result_d[1]{0}; //SCR-1385: set to 2sec int heater_delay_h = iround(result_d[2]{0}); int heater_delay_v = iround(result_d[3]{0}); //Magnets need to be switched to 0 prior to the deflux Hifi_HIFI_CH1_MX_MG_C($BBID,0.0); Hifi_HIFI_CV1_MX_MG_C($BBID,0.0); delay(1); //Start to send the pulse: command not yet available so we use single_cmd //Comment Hifi_HIFI_Set_SIS_heaters($BBID,normal_heater_time_h,normal_heater_time_v); // delay(1); Hifi_HIFI_HF_CH1_DHTR_C($BBID,normal_heater_time_h); delay(iceil(normal_heater_time_h / 1000.0) + 1); //Extra delay for cooling down temperature delay(heater_delay_h); Hifi_HIFI_HF_CV1_DHTR_C($BBID,normal_heater_time_v); delay(iceil(normal_heater_time_v / 1000.0) + 1); //Extra delay for cooling down temperature delay(heater_delay_v); // //Nominal values //Need a representative frequency: take keyfreq double[] result = CalibrationReader("name_keyfreq",["keyfreq"],band,0.0); double lo_freq = result[0]; // result_d = ConfigurationReaderWarm("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); double magnetcurrent_H = result_d[0]{0}; double magnetcurrent_V = result_d[1]{0}; Hifi_HIFI_CH1_MX_MG_C($BBID,magnetcurrent_H); Hifi_HIFI_CV1_MX_MG_C($BBID,magnetcurrent_V); delay(1); } ////////////////////////////////////////////////////////////////////////// // Procedure to compute detailed timing of DBS-raster observing mode {int,int,int,int,int,int,int,int,int,int,int,int,int} procedure DBSRaster_pre_timing { int nlines_tot = 1 in [1,100]; // Number of rows in the map int npoints = 10 in [2,100]; // Number of points per row string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_chop = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // First check validity of frequencies CheckLOFrequencies(band,lo_freq,lo_freq); // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // First perform consistency checks // Check chunk size given by the data rates CheckDataTaking(backendreadoutparms,data_time); // Is the map size an integer multiple of the scan size? CheckReasonableLineNumber(nlines_tot * npoints,false); int scansize = n_pointsperscan; if(scansize > nlines_tot * npoints) { SError("Scan size exceeds the total map size."); } if(nlines_tot * npoints % scansize != 0) { SError("Map size is no integer multiple of the scan size."); } int n_scans = nlines_tot * npoints / scansize; // Compute parameters for the instrument timing int jitterdead = GetMaxTimeJitter(band,lo_freq); int inttime = 2 * n_chop * data_time; int readouttime = data_time; // compute load integration time int loadlength = duration(LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms)); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); loadlength = loadlength + readoutdead; // Duration of initial set up // determine exact duration only in case of full commanding if(docommands) { int initlength = duration(HIFIInitObs()); initlength = initlength + duration(TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal")); // Add time for HK readout int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); initlength = initlength + hkduration; } else { initlength = GetRoughInitLength(band,lo_freq,false); } initlength = initlength + loadlength; // compute the load interval in case of short scan_time int scan_time = inttime * scansize; int n_loadinterval = imax(load_interval / (2 * scan_time),1); // Special treatment for nodding_raster due to limitations in API // Split into loads per point or per multiple points if(scansize == 1 && n_loadinterval > n_cycles) { n_loadinterval = n_cycles * (n_loadinterval / n_cycles); } n_loadinterval = imin(n_loadinterval,n_cycles * n_scans); // Compare load interval and nodding interval // This determines the order of the loops int load_spacing = CheckedLoadSpacing(load_interval - loadlength,8); // load measurements within a single point integration int n_load = inttime / load_spacing; if(n_load >= 1 && scansize > 1) { SError("Number of points in one scan too large for load period."); } // Rough estimate of the pointing time - this is corrected // after the evaluation of the telescope command if(load_spacing > 2 * scan_time) { int n_seq = n_chop; int pointing = inttime + jitterdead; } else { // It is possible that a single point is short enough, but a scan // too long. Then everything is reduced to a single point. scansize = 1; n_scans = nlines_tot * npoints; n_seq = n_chop / (n_load + 1); inttime = 2 * n_seq * (n_load + 1) * data_time; pointing = inttime + (n_load + 1) * loadlength + jitterdead; } // dangling time given by readout dead time int dangling = readoutdead; int holdlength = jitterdead; // Return all the times needed for telescope call and post_timing processing return {inttime,pointing,readouttime,loadlength,holdlength,load_spacing,n_load,n_loadinterval,n_seq,n_scans,scansize,initlength,dangling}; } /////////////////////////////////////////////////////////////////////////// // Building blocks // // Initialize all peakup settings block HifiPeakupConfigure HIFI 6820 { int data_time = 4; // Integration time between two data readouts int n_cycle = 1; // chop cycle number bool isH = true; // backend to use - polarization string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double stepsize = 0.0050; // Distance between subsequent points {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // HRS1/2 {used,resolution,subbands used}, WBS1/2 {used, channel windows} }{ // Translate stepsize into 1/100 arcsec int scale = iround(stepsize * 360000.0); // Determine offsets if(isH) { double[] x = CalibrationReader("peakup",["offset_y_H","offset_z_H"],band,lo_freq); int offset_y = iround(x[0]); int offset_z = iround(x[1]); } else { x = CalibrationReader("peakup",["offset_y_V","offset_z_V"],band,lo_freq); offset_y = iround(x[0]); offset_z = iround(x[1]); } // Command offsets Hifi_HIFI_configure_peakup_r1($BBID,scale,scale,offset_y,offset_z); // Call procedure for slow-chop spectroscopy configuration ConfigureSpectroscopy(data_time,2 * n_cycle,"chop",band,lo_freq,backendreadoutparms); delay(1); } // WBS configuration with laser choice, block // Both polarizations are treated block WBS_config_w_laser_block_fm HIFI 3637 { string band = "1a"; // HIFI band string laser_H = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-V laser to be set ON }{ //Start_block(); //H-Polarization // {double,string}[] result_d = ConfigurationReader("name_configwbs",["hwh_laser1_s","hwh_laser2_s","hwh_heater","hwh_latchup_s","hwh_att_band4","hwh_att_band3","hwh_att_band2","hwh_att_band1","hwh_att_in"],band,0.0); string hwh_laser1_s = "OFF"; string hwh_laser2_s = "OFF"; if(laser_H == "Laser1") { hwh_laser1_s = "ON"; } if(laser_H == "Laser2") { hwh_laser2_s = "ON"; } int hwh_heater = iround(result_d[2]{0}); string hwh_latchup_s = result_d[3]{1}; int hwh_att_band4 = iround(result_d[4]{0}); int hwh_att_band3 = iround(result_d[5]{0}); int hwh_att_band2 = iround(result_d[6]{0}); int hwh_att_band1 = iround(result_d[7]{0}); int hwh_att_in = iround(result_d[8]{0}); // result_d = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result_d[0]{0}); // //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); // //delay(wbs_config_delay); //Wait for configuration to be applied // //V-Polarization // result_d = ConfigurationReader("name_configwbs",["hwv_laser1_s","hwv_laser2_s","hwv_heater","hwv_latchup_s","hwv_att_band4","hwv_att_band3","hwv_att_band2","hwv_att_band1","hwv_att_in"],band,0.0); string hwv_laser1_s = "OFF"; string hwv_laser2_s = "OFF"; if(laser_V == "Laser1") { hwv_laser1_s = "ON"; } if(laser_V == "Laser2") { hwv_laser2_s = "ON"; } int hwv_heater = iround(result_d[2]{0}); string hwv_latchup_s = result_d[3]{1}; int hwv_att_band4 = iround(result_d[4]{0}); int hwv_att_band3 = iround(result_d[5]{0}); int hwv_att_band2 = iround(result_d[6]{0}); int hwv_att_band1 = iround(result_d[7]{0}); int hwv_att_in = iround(result_d[8]{0}); // //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // delay(wbs_config_delay); //Wait for configuration to be applied // } // LCU1b configuration into SAFE mode, procedure procedure LCU1b_config_safe_proc_fm { string band = "1b"; // HIFI band double lo_freq = 600.0 in [566.0,633.0]; //LO frequency }{ error("This module is obsolete: use LCU_config_nominal_proc_fm instead"); } // Needs the chopper in open-loop mode !! block Chopper_openloop_scan_warm_block_fm HIFI 3794 { int scan_portion = 1 in [1,3]; //indicates which part of scans is to be done }{ //Start_block (); //Hard-coded RAW values for end stops and rest position int low = 1298; //This is slightly further the low end-stop int high = 2548; //This is slightly further the high end-stop int zero = 2048; //This is the zero position int step = 50; // int chopper_pos = zero; //Scan from zero to end-stop high while(chopper_pos <= high) { if(scan_portion == 1) { HIFI_CPR_Chopper_Rot_RAW_proc_fm(chopper_pos); //Rotate chopper Hifi_HIFI_non_periodic_hk_FCU(); //To get sent value delay(2); } chopper_pos = chopper_pos + step; } //Scan from end-stop high to end-stop low chopper_pos = high - step; while(chopper_pos >= low) { if(scan_portion == 2) { HIFI_CPR_Chopper_Rot_RAW_proc_fm(chopper_pos); //Rotate chopper Hifi_HIFI_non_periodic_hk_FCU(); //To get sent value delay(2); } chopper_pos = chopper_pos - step; } //Scan from end-stop low to zero chopper_pos = low + step; while(chopper_pos <= zero) { if(scan_portion == 3) { HIFI_CPR_Chopper_Rot_RAW_proc_fm(chopper_pos); //Rotate chopper Hifi_HIFI_non_periodic_hk_FCU(); //To get sent value delay(2); } chopper_pos = chopper_pos + step; } } //HIFI-COP-1.2-LO_FT for routine: uses single TM page TC obs HifiEng_LO_FT_Routine { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(LO_FT_COP_proc_ops(band,prime_or_redundant)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution LO_FT_COP_proc_ops(band,prime_or_redundant); } if(state[0] == 5) { HIFISetHK("normal",true); StopMode_block_ops(); } } } // Chop between internal and external cold loads, block // We take 1 spectrum per phase. block Stability_freqswitch_fm HIFI 3433 { string band = "1a"; // HIFI band int n = 100; //The number of integration pairs int integ_time = 4; //Total (co-added) integration time of a phase in sec. string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ Start_block(); // //We implement a special frequency switch spectroscopy for stability Freqswitch_spectro_for_Stability_proc_fm(band,n,integ_time * 2,backend,hrs_mode); } // Get maximum frequency switch step length double procedure GetMaxFreqThrow { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency }{ double[] throwlen = CalibrationReader("fsthrows",["maxfreqthrow"],band,lo_freq); return throwlen[0]; } //////////////////////////////////// // Fast chop DBS raster observing mode // {string,double,double}[] procedure HifiMappingProcFastDBSRasterSequencerInit { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source {double,double} lineDistance = {0.0050,0.0050}; // Distance between subsequent rows int nlines = 1 in [1,100]; // Number of rows in the map double stepsize = 0.0050 in [5.5556E-4,0.13333]; // Distance between subsequent points in the raster line int npoints = 10 in [2,100]; // Number of points per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 10 in [4,80]; // data dump interval int n_int_on = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_switch_on = 1 in [1,1800]; // number of data transfer cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Get the drift parameters to compute the drift noise {double,double} phaselengths = DBSPhaseLengths(band,lo_freq,effResolution,continuumDetection,oneGHzReference); // Compute derived quantities // Top down approach here int main_phase = iceil(phaselengths{0}); // Arbitrary selection of data_time int data_time_guess = 20; // Combine points for n_switch=1 int n_pointsperscan_guess = imin(imax(main_phase / data_time_guess,1),npoints * nlines); int n_pointsperscan_range = 1 - n_pointsperscan_guess; if(n_pointsperscan_range == 0) { n_pointsperscan_range = 1; } // remaining part for n_switch int n_switch_on_guess = main_phase / (n_pointsperscan_guess * data_time_guess) + 1; data_time_guess = main_phase / (n_pointsperscan_guess * n_switch_on_guess); // Check with data rate {int,double[]} dataparms = DataTaking(backendreadoutparms,8); int datalimit = 2 * dataparms{0}; if(data_time_guess < datalimit) { data_time_guess = datalimit; n_switch_on_guess = 1; } int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } // Chop phase length double phase_min = min(max(phaselengths{1},0.15),1.5); int n_int_on_guess = ifloor(double(data_time_guess) / (2.0 * phase_min)); int n_int_on_range = -n_int_on_guess / 2; if(n_int_on_range == 0) { n_int_on_range = 1; } // Add pointing requirements condition: >=10s {int,int} new_data_time = MatchMinPointing(data_time_guess,data_time_range,n_switch_on_guess); data_time_guess = new_data_time{0}; data_time_range = new_data_time{1}; // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"n_int_on",double(n_int_on_guess),double(n_int_on_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)},{"n_pointsperscan",double(n_pointsperscan_guess),double(n_pointsperscan_range)}]; return retvalues; } // Slow chop integration at OFF position ON-OFF-OFF-ON... block HIFIHalfChopOffIntegration HIFI 6052 { int data_time = 4; // Integration time between two data readouts int n_cycle = 1; // chop cycle number string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double[] rates = [120.0,1.0,2.0]; // Data rates between and during integrations }{ HIFI_Spectr_slow_chop_proc_aot(data_time,n_cycle,band,lo_freq,["chop_M3","chop_M3right"],rates); } // HRS complete configuration, block // Both polarizations are treated block HRS_config_w_switch_block_fm HIFI 3713 { string band = "1a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code string[] switch = ["H","V"]; //HRS resolution code }{ //Start_block(); // Fetch HRS configuration parameters //=================================== //H-polar string hrs_filename_h = "name_confighrs_" + hrs_mode[0]; {double,string}[] result = ConfigurationReader(hrs_filename_h,["hrh_switch","hrh_1u_att","hrh_1l_att","hrh_2u_att","hrh_2l_att","hrh_3u_att","hrh_3l_att","hrh_4u_att","hrh_4l_att","hrh_up_ol1","hrh_up_ol2","hrh_up_ol3","hrh_up_ol4","hrh_down_ol5","hrh_down_ol6","hrh_down_ol7"],band,0.0); string hrs_polarization_h = switch[0]; double hrsH_ATT_U1 = result[1]{0}; double hrsH_ATT_L1 = result[2]{0}; double hrsH_ATT_U2 = result[3]{0}; double hrsH_ATT_L2 = result[4]{0}; double hrsH_ATT_U3 = result[5]{0}; double hrsH_ATT_L3 = result[6]{0}; double hrsH_ATT_U4 = result[7]{0}; double hrsH_ATT_L4 = result[8]{0}; double[] hrsH_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; //V-polar string hrs_filename_v = "name_confighrs_" + hrs_mode[1]; result = ConfigurationReader(hrs_filename_v,["hrv_switch","hrv_1u_att","hrv_1l_att","hrv_2u_att","hrv_2l_att","hrv_3u_att","hrv_3l_att","hrv_4u_att","hrv_4l_att","hrv_up_ol1","hrv_up_ol2","hrv_up_ol3","hrv_up_ol4","hrv_down_ol5","hrv_down_ol6","hrv_down_ol7"],band,0.0); string hrs_polarization_v = switch[1]; double hrsV_ATT_U1 = result[1]{0}; double hrsV_ATT_L1 = result[2]{0}; double hrsV_ATT_U2 = result[3]{0}; double hrsV_ATT_L2 = result[4]{0}; double hrsV_ATT_U3 = result[5]{0}; double hrsV_ATT_L3 = result[6]{0}; double hrsV_ATT_U4 = result[7]{0}; double hrsV_ATT_L4 = result[8]{0}; double[] hrsV_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; // result = ConfigurationReader("name_delays",["hrs_config_delay"],band,0.0); int hrs_config_delay = iround(result[0]{0}); //Convert IF frequencies into A and M parameters //Truncate wb keyword: string[] output_hrs_mode = GetHrsMode_proc_fm(hrs_mode); string hrs_mode_h = output_hrs_mode[0]; string hrs_mode_v = output_hrs_mode[1]; // int[] a_m_parameter = ComputeA_M_parameters([hrs_mode_h,hrs_mode_v],hrsH_LO[0],hrsH_LO[1],hrsH_LO[2],hrsH_LO[3],hrsH_LO[4],hrsH_LO[5],hrsH_LO[6],hrsV_LO[0],hrsV_LO[1],hrsV_LO[2],hrsV_LO[3],hrsV_LO[4],hrsV_LO[5],hrsV_LO[6]); //H-polar int hrsH_LO1_M = a_m_parameter[1]; int hrsH_LO1_A = a_m_parameter[0]; int hrsH_LO2_M = a_m_parameter[3]; int hrsH_LO2_A = a_m_parameter[2]; int hrsH_LO3_M = a_m_parameter[5]; int hrsH_LO3_A = a_m_parameter[4]; int hrsH_LO4_M = a_m_parameter[7]; int hrsH_LO4_A = a_m_parameter[6]; int hrsH_LO5_M = a_m_parameter[9]; int hrsH_LO5_A = a_m_parameter[8]; int hrsH_LO6_M = a_m_parameter[11]; int hrsH_LO6_A = a_m_parameter[10]; int hrsH_LO7_M = a_m_parameter[12]; Hifi_HIFI_Config_HRS_H_att_lo($BBID,hrs_polarization_h,hrsH_ATT_U1,hrsH_ATT_L1,hrsH_ATT_U2,hrsH_ATT_L2,hrsH_ATT_U3,hrsH_ATT_L3,hrsH_ATT_U4,hrsH_ATT_L4,hrsH_LO1_M,hrsH_LO1_A,hrsH_LO2_M,hrsH_LO2_A,hrsH_LO3_M,hrsH_LO3_A,hrsH_LO4_M,hrsH_LO4_A,hrsH_LO5_M,hrsH_LO5_A,hrsH_LO6_M,hrsH_LO6_A,hrsH_LO7_M); // //delay(hrs_config_delay); //V-polar int hrsV_LO1_M = a_m_parameter[14]; int hrsV_LO1_A = a_m_parameter[13]; int hrsV_LO2_M = a_m_parameter[16]; int hrsV_LO2_A = a_m_parameter[15]; int hrsV_LO3_M = a_m_parameter[18]; int hrsV_LO3_A = a_m_parameter[17]; int hrsV_LO4_M = a_m_parameter[20]; int hrsV_LO4_A = a_m_parameter[19]; int hrsV_LO5_M = a_m_parameter[22]; int hrsV_LO5_A = a_m_parameter[21]; int hrsV_LO6_M = a_m_parameter[24]; int hrsV_LO6_A = a_m_parameter[23]; int hrsV_LO7_M = a_m_parameter[25]; Hifi_HIFI_Config_HRS_V_att_lo($BBID,hrs_polarization_v,hrsV_ATT_U1,hrsV_ATT_L1,hrsV_ATT_U2,hrsV_ATT_L2,hrsV_ATT_U3,hrsV_ATT_L3,hrsV_ATT_U4,hrsV_ATT_L4,hrsV_LO1_M,hrsV_LO1_A,hrsV_LO2_M,hrsV_LO2_A,hrsV_LO3_M,hrsV_LO3_A,hrsV_LO4_M,hrsV_LO4_A,hrsV_LO5_M,hrsV_LO5_A,hrsV_LO6_M,hrsV_LO6_A,hrsV_LO7_M); // delay(hrs_config_delay); //////////////////////////////////////////////////////////////////// //Now Configure blocks //H-polar result = ConfigurationReader(hrs_filename_h,["hrh_block_1","hrh_block_2","hrh_block_3","hrh_block_4","hrh_block_5","hrh_block_6","hrh_block_7","hrh_block_8"],band,0.0); string hrh_block_1 = result[0]{1}; string hrh_block_2 = result[1]{1}; string hrh_block_3 = result[2]{1}; string hrh_block_4 = result[3]{1}; string hrh_block_5 = result[4]{1}; string hrh_block_6 = result[5]{1}; string hrh_block_7 = result[6]{1}; string hrh_block_8 = result[7]{1}; // Hifi_HIFI_Config_HRS_H_blocks($BBID,hrh_block_1,hrh_block_2,hrh_block_3,hrh_block_4,hrh_block_5,hrh_block_6,hrh_block_7,hrh_block_8); //delay(hrs_config_delay); // //V-polar result = ConfigurationReader(hrs_filename_v,["hrv_block_1","hrv_block_2","hrv_block_3","hrv_block_4","hrv_block_5","hrv_block_6","hrv_block_7","hrv_block_8"],band,0.0); string hrv_block_1 = result[0]{1}; string hrv_block_2 = result[1]{1}; string hrv_block_3 = result[2]{1}; string hrv_block_4 = result[3]{1}; string hrv_block_5 = result[4]{1}; string hrv_block_6 = result[5]{1}; string hrv_block_7 = result[6]{1}; string hrv_block_8 = result[7]{1}; // Hifi_HIFI_Config_HRS_V_blocks($BBID,hrv_block_1,hrv_block_2,hrv_block_3,hrv_block_4,hrv_block_5,hrv_block_6,hrv_block_7,hrv_block_8); // //Wait delay to allow all setting to be configured delay(hrs_config_delay); } ////////////////////////////////////////////////////////// // Commanding procedures: 1:1 copy from normal raster // Procedure to generate the instrument commands for the DBS raster mode procedure HalfDBSRaster_commanding { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // chunk size int n_seq = 1; // Number of continuous chop cycles int n_cycles = 1; // Number of half OFF-ON-ON-OFF cycles int n_pointsperscan = 1; // Number of points measured before moving to the second pointing phase int n_loadinterval = 10; // number of nods before a load measurement int n_load = 0; // additional load measurements in one pointing phase bool final_load = false; // Need for final load measurement int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,10,0,10,20,21,0,0]; // Timing of the observation from telescope int loadlength = 21; // Load duration bool iscross = false; // Whether we use a cross instead of a raster }{ // Auxiliary variables // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Get all values from the telescope section int tinitslew = telescopetimes[1]; // Initial slew time //////////////////////////////////////////////////////////////////////// // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // // Clustering is currently not implemented in MPS - switched off here int clustered = 0; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] rates = dataparms{1}; int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); // Count phases by hand to allow simultaneous usage by Raster and Cross int iphase = 0; // There is no nod counter in the return values - count this by hand int inod = 0; // Do I have to make loads in short nods and subsequent holds? if(iscross) { bool holdforload = n_pointsperscan > 1; } else { holdforload = n_pointsperscan == 1 && n_loadinterval > n_cycles; } bool isOffAtPoint = false; //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; bool runintostate = false; while(state[0] >= 0) { if(runintostate) { state = next_state_no_check(); } else { state = next_state(); } if(state[0] == 1) { // Initialization if(clustered != 1) { HIFIInitObs(); TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal"); } delay(tinitslew - (time() - startobs) - loadlength - hkduration); // First load measurement HIFISetHK("normal",false); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); runintostate = false; iphase = iphase + 1; } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 3) { // First nodding position // Check whether we are in a cross mode using computed OFF isOffAtPoint = iscross && inod % 2 == 0; // Configure measurement HIFIConfigureSlowChopIntegration(data_time,n_seq,band,lo_freq,backendreadoutparms); // Loop for load cycles // The use of n_load differs by 1 from the other observing modes here for(int i1 = 1 .. n_load - 1) { if(isOffAtPoint) { HIFIHalfChopOffIntegration(data_time,n_seq,band,lo_freq,rates); } else { HIFIHalfChopOnIntegration(data_time,n_seq,band,lo_freq,rates); } // Perform load calibration delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); HIFIConfigureSlowChopIntegration(data_time,n_seq,band,lo_freq,backendreadoutparms); } // Last cycle if(isOffAtPoint) { HIFIHalfChopOffIntegration(data_time,n_seq,band,lo_freq,rates); } else { HIFIHalfChopOnIntegration(data_time,n_seq,band,lo_freq,rates); } // Load measurement if required - time included in pointing if(n_load > 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } // Final point before nod // Special treatment for all cases where load has to be replaced by hold: // n_pointsperscan=1, n_loadinterval > n_cycles if(iphase % n_pointsperscan == 0 && iphase / n_pointsperscan % 2 == 1) { inod = inod + 1; if(holdforload && inod % n_loadinterval == 0 && n_load == 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); runintostate = true; } } else { // keep shift if we come from a holdforload nod, otherwise reset if(!holdforload) { runintostate = false; } } // Update phase counter iphase = iphase + 1; } // Second pointing phase if(state[0] == 7) { // second nod position HIFIConfigureSlowChopIntegration(data_time,n_seq,band,lo_freq,backendreadoutparms); for(int i2 = 1 .. n_load - 1) { HIFIHalfChopOffIntegration(data_time,n_seq,band,lo_freq,rates); // Perform load calibration delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); HIFIConfigureSlowChopIntegration(data_time,n_seq,band,lo_freq,backendreadoutparms); } // Last cycle HIFIHalfChopOffIntegration(data_time,n_seq,band,lo_freq,rates); // Load measurement if required - time included in pointing if(n_load > 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } // Final point before nod // Special treatment for all cases where load has to be replaced by hold: if(iphase % n_pointsperscan == 0 && iphase / n_pointsperscan % 2 == 1) { inod = inod + 1; if(holdforload && inod % n_loadinterval == 0 && n_load == 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); runintostate = true; } } else { // keep shift if we come from a holdforload nod, otherwise reset if(!holdforload) { runintostate = false; } } // Update phase counter iphase = iphase + 1; } // Load nod if(state[0] == 9) { // Load nod delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); runintostate = false; } // Hold if(state[0] == 6) { // finished shift of instrument operations relative to pointing command runintostate = false; } // Final load if(state[0] == 5) { delay(readoutdead); if(final_load) { // Perform final load measurement LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } runintostate = false; HIFICloseObs(); } } } //HIFI measurement of HEB spectra variation vs Imix, procedure //Takes spectra over the full Vd2 range procedure HEB_Spectra_vs_Imix_proc_fm_COP { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band bool lo_chain_switch = true; //Whether the chain is already switched on int testtime = 900; //total time we want to spend on testing }{ //The same approach as for Vector_scan_BLUE_LIMIT_block_fm is followed, //except that spectra are taken at each Vd2 step. // //Variable for stabilization measurement string chopmode = "slowchop"; double chop_phase = 1.0; //not used here string backend = "both"; int integ_time = 4; string[] hrs_mode = ["wb1","wb1"]; //For bands 6 and 7, use wb8 if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { hrs_mode = ["wb8","wb8"]; } // // int starttime = time(); //Get the parameters used for the scan string tab = "config_HEB_Imix_spec.config"; double bandnb = GetBandCode(band); double lo_freq = dlookup(tab,"" + iceil(bandnb),"lofreq"); //Configure FPU at that frequency Init_MSA_HBB_fm(band,"CLOSE",lo_freq,"ON"); // int warmup_time = 860; if(lo_chain_switch) { //in this case we will have drift on top of the Vd2 scan LCU_switchon_proc_fm(band); LO_tuning_block_fm(band,lo_freq); //using best-guess Vd2 int intermediatetime = warmup_time - (time() - starttime); int n = intermediatetime / integ_time / 2; //number of frames for one phase //During the next ~15min, take data as a stability measurement Proc_stability_intcold_inthot(band,n,hrs_mode,integ_time,backend,chopmode,chop_phase); } // //Now system is stable but likely un-pumped again //This is the perfect point to re-adjust the WBS attenuators WBS_tune_proc_fm(band); //Perform vector scan with spectra within BLUE limits at that frequency Vector_scan_BLUE_LIMIT_w_spectra_proc_COP(band,lo_freq,testtime); } ///////////////////////////////////////////////////////////////// // Spectral scan in frequency switch with OFF calibration // // Implemented as procedure returning time and noise levels for HSPOT {int,double,double,double,double,double} obs HifiSScanProcFSwitch { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source double raoff = 0.0; // RA coordinate of the OFF position double decoff = 0.0; // DEC coordinate of the OFF position bool refSelected = true; // Dummy parameter required by HSPOT string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz int redundancy = 4 in [1,12]; // Frequency scan redundancy double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} effResolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz bool wbs1Used = true; // whether WBS1 is used bool wbs2Used = true; // whether WBS2 is used /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles per frequency and pointing int n_switch_off = 1 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles on OFF int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int n_cycles = 1 in [1,600]; // Number of half OFF-ON-ON-OFF cycles at one frequency int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Spectral Scan - Frequency Switch Ref",{data_time,data_time_off,0,n_switch_on,n_switch_off,0,0,n_freq_point,n_cycles,load_interval}); // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,redundancy,wbs1Used,wbs2Used,data_time); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; ////////////////////////////////////////////////////////////////////// // Call first part of the timing computer {{int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int},{int,double,double[],int[][],bool,double[],int,bool}} pre_timing = SScanFSwitch_pre_timing(band,lo_freq,lo_freq_up,redundancy,freq_throw,effResolution,hr1,hr2,wb1,wb2,data_time,data_time_off,n_switch_on,n_switch_off,n_freq_point,n_cycles,load_interval,docommands); // frequency parameters int groupnumber = pre_timing{1}{0}; double reffreq = pre_timing{1}{1}; double[] freqgrid = pre_timing{1}{2}; int[][] grouporder = pre_timing{1}{3}; bool retuning = pre_timing{1}{4}; double[] targetlevels = pre_timing{1}{5}; int nfreq_if = pre_timing{1}{6}; bool dsb = pre_timing{1}{7}; int n_total = groupnumber * n_cycles; ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {double,double} refPosition = {raoff,decoff}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,int,int,int,int,int,int} tpar = PositionSwitch_telescope(naifid,onPosition,refPosition,band,reffreq,pre_timing{0},n_total); // Dummy call to spacecraft command int[] telescopetimes = nodding_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},true); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int},double,double,double} post_timing = SScanDoubleChop_post_timing(pre_timing{0},telescopetimes,n_freq_point,groupnumber,n_cycles); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = PositionSwitch_telescope(naifid,onPosition,refPosition,band,reffreq,post_timing{1},n_total); // Call telescope command telescopetimes = nodding_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},true); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following // normal pre_timing values int on_inttime = post_timing{1}{0}; int off_inttime = post_timing{1}{1}; int n_loadinterval = post_timing{1}{7}; int n_long_on = post_timing{1}{8}; int n_long_off = post_timing{1}{9}; int shiftlength = post_timing{1}{5}; int initlength = post_timing{1}{14}; bool final_load = post_timing{1}{12}; // efficiency parameters double avnumchop_on = post_timing{2}; double avnumchop_off = post_timing{3}; double tscan = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { SScanFSwitch_commanding(band,reffreq,freq_throw,effResolution,hr1,hr2,wb1,wb2,n_freq_point,grouporder,freqgrid,retuning,targetlevels,data_time,data_time_off,n_switch_on,n_switch_off,n_long_on,n_long_off,n_cycles,n_total,n_loadinterval,final_load,startobs,telescopetimes,shiftlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double,double,double} tact = SScanDoubleChop_deadtimes("fs",band,reffreq,hr1,hr2,wb1,wb2,n_freq_point,data_time,data_time_off,n_switch_on,n_switch_off,n_long_on,n_long_off,n_cycles,avnumchop_on,avnumchop_off,tscan); // // Call noise computer {double,double,double,double,double} noisevalues = SScanFSwitch_noisecomputer(band,reffreq,nfreq_if,dsb,effResolution,on_inttime,off_inttime,n_cycles,tscan,tact); // Evaluate performance SScanDoubleChop_performance(band,reffreq,nfreq_if,dsb,effResolution,noisevalues,timeTaken,n_freq_point,n_cycles,groupnumber * n_freq_point,avnumchop_on,avnumchop_off,true,tscan,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } procedure IError { string errormessage = "Bad parameter combination."; // Error message }{ string fullmessage = "Invalid input parameter setting:
" + errormessage + "
Please, change your AOR parameters."; error(fullmessage); } // Wrapper for fixed instrument configurations. // // This is used for the COLD instrument - in-orbit configuration // {double,string}[] procedure ConfigurationReader { string topicname = "name_confilfpu"; // Name of entry in master file string[] objectnames = ["bias_standby_h"]; // Names of calibration objects to be read string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency }{ string mainmasterfile = "configuration_masterfile"; {double,string}[] retvalues = FlexibleConfigurationReader(mainmasterfile,topicname,objectnames,band,lo_freq); return retvalues; } // Very fast sampling stability measurement, procedure // Uses only the HRS in wb mode block Stability_fast_block_fm HIFI 3436 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band int n = 100; //Number of samples to be measured double sampling_rate = 2.0 in [1.0,6.0]; //Sampling rate: 2 (2 HRS-H + 2 HRS-V), 3 (HRS-H + HRS-V), 4 (2 HRS-H or 2 HRS-V) or 6 (1 HRS-H or 1 HRS-V) Hz string hrs_polarization = "H" in ["H","V","B"]; //HRS polarization: selection works only for 4 and 8 Hz }{ Start_block(); // //Derive number of n_wbs_start necessary to get all dumps. //We assume WBS loops 65 sec long max. int max_wbs_time = 65000; int total_time = n * 1000 / iround(sampling_rate); int n_loop = 20; int loop = 20; for(int i = 1 .. loop - 1) { //debug_print(i); if(total_time <= max_wbs_time * (loop - i)) { //debug_print(max_wbs_time*(loop-i)); n_loop = loop - i; } } // // Get fixed parameters from configuration and calibration files // Command jitter time is the default delay {double,string}[] result = ConfigurationReader("name_delays",["add_jitter"],band,0.0); int add_jitter = iround(result[0]{0}); // Additional delays in the readout loops - given in OBS user manual result = ConfigurationReader("name_delays",["add_hrs","add_wbs","add_jitter","wbs_init","wbs_chunksize","tacc_add","hrs_phase"],band,0.0); int add_hrs = iround(result[0]{0}); int add_wbs = iround(result[1]{0}); int wbs_init = iround(result[3]{0}); int wbs_chunksize = iround(result[4]{0}); int tacc_add = iround(result[5]{0}); int hrs_phase = iround(result[6]{0}); // HRS standard phase length // //Fetch default parameters result = ConfigurationReader("name_confilspec",["del_hrs","del_wbs","t_acc_wbs","t_acc_hrs","n_wbs_integr","n_hrs_integr","n_wbs_start","r_hrs","wbsh_offset1","wbsh_width1","wbsh_offset2","wbsh_width2","wbsh_offset3","wbsh_width3","wbsh_offset4","wbsh_width4","wbsv_offset1","wbsv_width1","wbsv_offset2","wbsv_width2","wbsv_offset3","wbsv_width3","wbsv_offset4","wbsv_width4","hrs_rshift","wbs_rshift","hrsh_sel","hrsv_sel","wbs_packing"],band,0.0); // int del_hrs = iround(result[0]{0}); int del_wbs = iround(result[1]{0}); int t_acc_wbs = iround(result[2]{0}); int t_acc_hrs = iround(result[3]{0}); int n_wbs_integr = iround(result[4]{0}); int n_hrs_integr = iround(result[5]{0}); int n_wbs_start = n_loop; int r_hrs = iround(result[7]{0}); int wbsh_offset1 = 0; int wbsh_width1 = 0; int wbsh_offset2 = 2048; int wbsh_width2 = 0; int wbsh_offset3 = 4096; int wbsh_width3 = 0; int wbsh_offset4 = 6144; int wbsh_width4 = 0; int wbsv_offset1 = 0; int wbsv_width1 = 0; int wbsv_offset2 = 2048; int wbsv_width2 = 0; int wbsv_offset3 = 4096; int wbsv_width3 = 0; int wbsv_offset4 = 6144; int wbsv_width4 = 0; int hrs_rshift = iround(result[24]{0}); int wbs_rshift = iround(result[25]{0}); int hrsh_sel = 192; //1100000 = 1U and 2U int hrsv_sel = 192; //1100000 = 1U and 2U string wbs_packing = "24_bits_format"; //result[28]{1}; // t_acc_wbs = (total_time - wbs_init) / n_loop - add_jitter - add_wbs - del_wbs; // discretize in 10ms chunks int nchunk = (t_acc_wbs - tacc_add) / wbs_chunksize; t_acc_wbs = nchunk * wbs_chunksize + tacc_add; //WBS time need to be at least 1 sec if(t_acc_wbs < 1000) { t_acc_wbs = 1005; } r_hrs = iceil(double(t_acc_wbs) * sampling_rate / 1000.0); t_acc_hrs = (t_acc_wbs - add_jitter) / r_hrs - del_hrs - add_hrs; // //Adapt parameters to our case //Currently 2Hz and polar = B: 2 subbands and 2 polar // Science data: n_polar*(n_band*2*258*24+1376+3*272) int allbits = 2 * (2 * 2 * 258 * 24 + 1376 + 3 * 272); string backend = "hrs"; if(sampling_rate == 3.0) { //polar = B: 1 band, 2 polar allbits = 2 * (2 * 258 * 24 + 1376 + 3 * 272); hrsh_sel = 128; //10000000 = 1U only hrsv_sel = 128; //10000000 = 1U only backend = "hrs"; } if(sampling_rate == 4.0) { if(hrs_polarization == "B") { //forbidden case error("You cannot use this speed with both HRS - try 3Hz"); } if(hrs_polarization == "H") { //2 bands, 1 polar allbits = 2 * 2 * 258 * 24 + 1376 + 3 * 272; hrsh_sel = 192; //11000000 = 1U and 2U hrsv_sel = 0; //00000000 = no subband backend = "hrsFast"; } if(hrs_polarization == "V") { //2 bands, 1 polar allbits = 2 * 2 * 258 * 24 + 1376 + 3 * 272; hrsh_sel = 0; //00000000 = no subband hrsv_sel = 192; //11000000 = 1U and 2U backend = "hrsFast"; } } if(sampling_rate > 4.0) { //only one band, one polarization if(hrs_polarization == "B") { //forbidden case error("You cannot use this speed with both HRS - try 3Hz"); } allbits = 2 * 258 * 24 + 1376 + 3 * 272; backend = "hrsFast"; //If polar = H hrsh_sel = 128; //10000000 = 1U only hrsv_sel = 0; //00000000 = no subband if(hrs_polarization == "V") { hrsh_sel = 0; //00000000 = no subband hrsv_sel = 128; //11000000 = 1U only } } // //Configure integration to be done Hifi_HIFI_config_spectroscopy($BBID,n_wbs_start,r_hrs,n_wbs_integr,n_hrs_integr,del_hrs,del_wbs,t_acc_wbs,t_acc_hrs,wbsh_offset1,wbsh_width1,wbsh_offset2,wbsh_width2,wbsh_offset3,wbsh_width3,wbsh_offset4,wbsh_width4,wbsv_offset1,wbsv_width1,wbsv_offset2,wbsv_width2,wbsv_offset3,wbsv_width3,wbsv_offset4,wbsv_width4,hrs_rshift,wbs_rshift,hrsh_sel,hrsv_sel,wbs_packing); // //Compute delay int delay_total_power = iceil(double(total_time) / 1000.0); //Prepare data-rate computation // Clean HK treatment for controlled data rates {string,int,double,double,double,double} hkparms = PeriodicHKParms("fast"); // HK data: stdrate=7744+864+2*272, IF packets=2*(592+272) int allhkbits = 1782; double hkrate = hkparms{3} + double(allhkbits) / double(t_acc_hrs) * 1000.0; double sciencerate = double(allbits) / double(t_acc_hrs) * 1000.0; // set data rates ess_hk_data_rate(hkparms{5} / 1024.0); non_ess_hk_data_rate(hkrate / 1024.0); data_rate(sciencerate / 1024.0); //start integration Hifi_HIFI_Spectr_total_power($BBID); Apply_Total_Power_delay(delay_total_power,band,backend); // reset data rates non_ess_hk_data_rate(hkparms{3} / 1024.0); data_rate(0.0); //Apply delay: add one second for security delay(1); // } ////////////////////////////////////////////////////////////////////// // Procedure to perform the noise level evaluation for the observing mode {double,double,double,double,double} procedure SScanLoadChop_noisecomputer { string band = "4a"; // HIFI band double reffreq = 978300.0; // Reference LO frequency in scan center int nfreq = 4; // Number of frequency points per IF bool dsb = true; // Both sidebands covered {double,double} eff_resolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz int on_inttime = 16; // Integration time per ON phase int off_inttime = 16; // Integration time per OFF phase int n_cycles = 1; // Number of half OFF-ON-ON-OFF cycles at one frequency double tscan = 60.0; // Total average duration of one scan {double,double,double,double,double} tact = {10.0,4.9,4.9,0.05,0.05}; // Field of actual dead and integration times }{ // spectral scans always use the full bandwidth for reference bool oneGHzReference = false; // Call load-chop noise computer {double,double,double,double,double} noisevalues = LoadChop_noisecomputer(band,reffreq,eff_resolution,oneGHzReference,on_inttime,off_inttime,n_cycles,tscan,tact); // Correct for multiple frequencies double multiplier = sqrt(1.0 / double(nfreq)); noisevalues{0} = noisevalues{0} * multiplier; noisevalues{1} = noisevalues{1} * multiplier; // Check for double sideband coverage if(dsb) { // Combine LSB-USB noise // In spectral scans we have only a combined noise temperature for both // sidebands, so that the USB/LSB separation is not used double[] gssb = InterpolateGssb(band,reffreq); double usbnoise_lores = noisevalues{0} / sqrt(1.0 + gssb[1] / gssb[0] * (gssb[1] / gssb[0])); double usbnoise_hires = noisevalues{1} / sqrt(1.0 + gssb[1] / gssb[0] * (gssb[1] / gssb[0])); double lsbnoise_lores = usbnoise_lores; double lsbnoise_hires = usbnoise_hires; } else { // Get single sideband noise equivalent usbnoise_lores = noisevalues{0}; usbnoise_hires = noisevalues{1}; lsbnoise_lores = noisevalues{2}; lsbnoise_hires = noisevalues{3}; } // Return noise values and the maximum ratio of drift to radiometric noise return {usbnoise_lores,usbnoise_hires,lsbnoise_lores,lsbnoise_hires,noisevalues{4}}; } // LCU configuration into NOMINAL mode, procedure // Uses best guess D2 voltage from confgilcu table procedure LCU_config_nominal_proc_fm { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency }{ //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlcutune = "name_configlcutune_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1_v = result[0]{1}; string curlim2_v = result[1]{1}; // result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); //Fetch best guess, and clip to blue max double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lo_freq); drain2_v = min(result[0]{0},drain2_bluemax); //Send command: expect that we have already switched to NOMINAL //We set D2 to best guess and wait some time to stabilize chain temperature HIFI_Configure_LCU_block_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum,config_lo_delay); // } // LCU4b configuration into SAFE mode, procedure procedure LCU4b_config_safe_proc_fm { string band = "4b"; // HIFI band double lo_freq = 1100.0 in [1056.0,1113.0]; //LO frequency }{ error("This module is obsolete: use LCU_config_nominal_proc_fm instead"); } // Stability test, procedure, no IF1 procedure Proc_stability_noIF1 { string band = "1a"; // HIFI band int n = 100; //Number of load pairs to be measured string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code string mixer_polarization = "B" in ["H","V","B"]; //Polarization: H, V, or both (B) int integ_time = 4; //Total integration time in sec. to be set at end of test string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Sets FPU with no IF1 Init_noIF1_fm(band,mixer_polarization); //WBS calibration if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band); //Configure and tune backends WBS_tune_proc_fm(band); //WBS_config_min_att_w_laser_block_fm(band,laser_H,laser_V); } if(backend == "hrs" || backend == "both" || backend == "hrsFast") { //Configure and tune backends HRS_config_min_att_block_fm(band,hrs_mode); HRS_tune_block_fm(band); } // //Configure spectrometers integration: done later //Configure_Spectrometer_proc_fm(band,4,hrs_mode,backend); //2 sec. integration // Stability_noIF1_fm(band,n,integ_time,backend,hrs_mode); //Configure spectrometers integration back to default in tp mode Configure_Spectrometer_proc_fm(band,4,hrs_mode,backend); } // WBS configuration with laser choice, block // Used to switch on laser block WBS_config_w_laser_block_ops HIFI 7637 { string band = "0"; // HIFI band string laser_H = "Laser1" in ["Laser1","Laser2"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2"]; //WBS-V laser to be set ON }{ //H-Polarization // {double,string}[] result_d = ConfigurationReader("name_configwbs",["hwh_laser1_s","hwh_laser2_s","hwh_heater","hwh_latchup_s","hwh_att_band4","hwh_att_band3","hwh_att_band2","hwh_att_band1","hwh_att_in"],band,0.0); string hwh_laser1_s = "OFF"; string hwh_laser2_s = "OFF"; if(laser_H == "Laser1") { hwh_laser1_s = "ON"; } if(laser_H == "Laser2") { hwh_laser2_s = "ON"; } int hwh_heater = iround(result_d[2]{0}); string hwh_latchup_s = result_d[3]{1}; int hwh_att_band4 = iround(result_d[4]{0}); int hwh_att_band3 = iround(result_d[5]{0}); int hwh_att_band2 = iround(result_d[6]{0}); int hwh_att_band1 = iround(result_d[7]{0}); int hwh_att_in = iround(result_d[8]{0}); // result_d = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result_d[0]{0}); // //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); // //delay(wbs_config_delay); //Wait for configuration to be applied // //V-Polarization // result_d = ConfigurationReader("name_configwbs",["hwv_laser1_s","hwv_laser2_s","hwv_heater","hwv_latchup_s","hwv_att_band4","hwv_att_band3","hwv_att_band2","hwv_att_band1","hwv_att_in"],band,0.0); string hwv_laser1_s = "OFF"; string hwv_laser2_s = "OFF"; if(laser_V == "Laser1") { hwv_laser1_s = "ON"; } if(laser_V == "Laser2") { hwv_laser2_s = "ON"; } int hwv_heater = iround(result_d[2]{0}); string hwv_latchup_s = result_d[3]{1}; int hwv_att_band4 = iround(result_d[4]{0}); int hwv_att_band3 = iround(result_d[5]{0}); int hwv_att_band2 = iround(result_d[6]{0}); int hwv_att_band1 = iround(result_d[7]{0}); int hwv_att_in = iround(result_d[8]{0}); // //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // delay(wbs_config_delay); //Wait for configuration to be applied // mois_tmcheck("Check that parameter HWH_Laser1_S is " + hwh_laser1_s); mois_tmcheck("Check that parameter HWH_Laser2_S is " + hwh_laser2_s); mois_tmcheck("Check that parameter HWV_Laser1_S is " + hwv_laser1_s); mois_tmcheck("Check that parameter HWV_Laser2_S is " + hwv_laser2_s); } ////////////////////////////////////////////////////////////////// // Procedure to compute detailed pre timing for the version of the // frequency switch mode without baseline measurement // {int,int,int,int,int,int,bool,int,int} procedure FSwitchNoRef_pre_timing { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4 in [1,20]; // data dump interval limited by the data rates int n_chop_on = 2 in [1,3600]; // number of half nu1-nu2-nu2-nu1 cycles on ON int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ///////////////////////////////////////////////////////////////////// CheckLOFrequencies(band,lo_freq + min(freq_throw,0.0),lo_freq + max(freq_throw,0.0)); // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // First perform consistency checks // Check chunk size given by the data rates CheckDataTaking(backendreadoutparms,data_time); CheckFswOutOfBand(band,lo_freq,freq_throw,backendreadoutparms); int jitterdead = GetMaxTimeJitter(band,lo_freq); // Compute parameters for the instrument timing int on_inttime = 2 * n_chop_on * data_time; // compute load integration time int loadlength = duration(DoubleLoadMeasurement(band,lo_freq,freq_throw,eff_resolution{0},data_time,backendreadoutparms)); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); loadlength = loadlength + readoutdead; // Compare load interval with duration of the observation int load_spacing = CheckedLoadSpacing(load_interval - loadlength,8); int n_load_on = on_inttime / load_spacing; // This determines the order of the loops if(load_spacing > 2 * on_inttime) { int n_per_on = n_chop_on; bool end_load_on = false; int on_pointing = on_inttime + jitterdead; } else { n_per_on = n_chop_on / (n_load_on + 1); if(n_per_on < 1) { SError("FS phase length on source too long relative to load period."); } end_load_on = true; on_inttime = 2 * n_per_on * (n_load_on + 1) * data_time; on_pointing = on_inttime + n_load_on * loadlength + jitterdead; } // Duration of initial set up // determine exact duration only in case of full commanding if(docommands) { int initlength = duration(HIFIInitObs()); initlength = initlength + duration(TuneHIFIFsw(band,lo_freq,freq_throw,hrs1,hrs2,wbs1{0},wbs2{0},"normal")); // Add time for HK readout int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); initlength = initlength + hkduration; } else { initlength = GetRoughInitLength(band,lo_freq,true); } initlength = initlength + loadlength; // dangling time given by readout dead time int dangling = readoutdead; // Return all the times needed for telescope call and post_timing processing return {on_inttime,on_pointing,loadlength,load_spacing,n_per_on,n_load_on,end_load_on,initlength,dangling}; } // Compute total power delay necessary for integration, procedure procedure Apply_Total_Power_delay { int total_time = 12; //single readout time * n_wbs_start string band = "1a"; // HIFI band string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Packet transfer time {double,string}[] result = ConfigurationReader("name_delays",["wbs_transfer_delay"],band,0.0); // int wbs_packet_transfer_time = iround(result[0]{0}); // //In case less channels are used, one must adapt the transfer time if(backend == "hrs" || backend == "wbs") { //wbs_packet_transfer_time = 0; //3000; } if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { //expect half backend //wbs_packet_transfer_time = 0; //2000; } // //Compute delay int delay_total_power = total_time + wbs_packet_transfer_time / 1000; //debug_print("Total power delay: " + delay_total_power + " sec"); // //Apply delay delay(delay_total_power); // } // WBS linearity test, loop on main attenuator, block block FT_WBS_linearity HIFI 3708 { string band = "1a"; // HIFI band int integ_time = 4; //Total integration time in sec. string laser_H = "Laser1" in ["Laser1","Laser2"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2"]; //WBS-V laser to be set ON string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); // //Set zero and comb off Hifi_HIFI_Single_cmd($BBID,"HWH_ZERO_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWV_ZERO_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWH_COMB_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWV_COMB_OFF"); delay(2); // //Initial configuration: overall attenuators set to max., individual attenuators to 0 //H-Polarization // {double,string}[] result = ConfigurationReader("name_configwbs",["hwh_heater","hwh_latchup_s"],band,0.0); string hwh_laser1_s = "OFF"; string hwh_laser2_s = "OFF"; if(laser_H == "Laser1") { hwh_laser1_s = "ON"; } if(laser_H == "Laser2") { hwh_laser2_s = "ON"; } int hwh_heater = iround(result[0]{0}); string hwh_latchup_s = result[1]{1}; int hwh_att_band4 = 0; int hwh_att_band3 = 0; int hwh_att_band2 = 0; int hwh_att_band1 = 0; int hwh_att_in = 16; // result = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result[0]{0}); // //V-Polarization // result = ConfigurationReader("name_configwbs",["hwv_heater","hwv_latchup_s"],band,0.0); string hwv_laser1_s = "OFF"; string hwv_laser2_s = "OFF"; if(laser_V == "Laser1") { hwv_laser1_s = "ON"; } if(laser_V == "Laser2") { hwv_laser2_s = "ON"; } int hwv_heater = iround(result[0]{0}); string hwv_latchup_s = result[1]{1}; int hwv_att_band4 = 0; int hwv_att_band3 = 0; int hwv_att_band2 = 0; int hwv_att_band1 = 0; int hwv_att_in = 16; // //Loop on overall attenuators for(int i = 0 .. 15) { // Change the value of the main attenuator //======================================== hwh_att_in = hwh_att_in - 1; hwv_att_in = hwv_att_in - 1; // Set WBS //======== //0dB attenuation on individual attenuators hwh_att_band4 = 0; hwh_att_band3 = 0; hwh_att_band2 = 0; hwh_att_band1 = 0; Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); delay(wbs_config_delay); //Wait for configuration to be applied // hwv_att_band4 = 0; hwv_att_band3 = 0; hwv_att_band2 = 0; hwv_att_band1 = 0; Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); delay(wbs_config_delay); //Wait for configuration to be applied // HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // // //1dB attenuation on individual attenuators hwh_att_band4 = 1; hwh_att_band3 = 1; hwh_att_band2 = 1; hwh_att_band1 = 1; Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); delay(wbs_config_delay); //Wait for configuration to be applied // hwv_att_band4 = 1; hwv_att_band3 = 1; hwv_att_band2 = 1; hwv_att_band1 = 1; Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); delay(wbs_config_delay); //Wait for configuration to be applied // HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // } //Set att. to max. WBS_config_proc_max_att_w_laser_fm(band,laser_H,laser_V); // } //Startblock procedure Start_block { }{ //These are ILT-EGSE commands, not ruled by the 2TC/sec. //HifiIltEgse_FPU_set_BB_ID($BBID); //HifiIltEgse_PDU_set_BB_ID($BBID); //SpireIltEgse_QCC_SETBBID($BBID); //delay(1); Hifi_HIFI_Set_OBS_ID($BBID,$OBSID); Hifi_HIFI_non_periodic_hk_FCU(); delay(1); } // Stability test, procedure, case 1 // Measurement of internal hot only procedure Proc_stability_inthot { string band = "1a"; // HIFI band int n = 100; //Number of load pairs to be measured string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int integ_time = 4; //Total integration time in sec. to be set at end of test string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string obsmode = "tp" in ["fastchop","tp"]; //tp or fastchop double chop_phase = 1.0 in [0.2,2.0]; // Chop phase length }{ // Chopper_Rotation_block_fm(band,"chop_M3_ang","chop_hot_ang"); //Look at HBB // //WBS calibration if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band); WBS_tune_proc_fm(band); } if(backend == "hrs" || backend == "both" || backend == "hrsFast") { //Configure and tune backends HRS_config_block_fm(band,hrs_mode); HRS_tune_block_fm(band); } // //Configure spectrometers integration: done later //Configure_Spectrometer_proc_fm(band,4,hrs_mode,backend); //2 sec. integration // Stability_inthot_fm(band,n,integ_time,backend,hrs_mode,obsmode,chop_phase); //Configure spectrometers integration back to default in tp mode Configure_Spectrometer_proc_fm(band,4,hrs_mode,backend); } ///////////////////////////////////////////////////////////////// // Second step of timing computation after telescope behaviour // is known - Spectral Scan frequency switch observing mode // without baseline measurement // {int,{int,int,int,int,int,int,bool,int,int},double,double} procedure SScanChopNoRef_post_timing { {int,int,int,int,int,int,bool,int,int} pre_timing = {16,16,21,1800,2,0,false,50,0}; // pre_timing parameter list int[] telescopetimes = [300,180,0]; }{ // Get all values from the pre_timing section int on_inttime = pre_timing{0}; int on_pointing = pre_timing{1}; int loadlength = pre_timing{2}; int load_spacing = pre_timing{3}; int n_per_on = pre_timing{4}; int n_load_on = pre_timing{5}; bool end_load_on = pre_timing{6}; int initlength = pre_timing{7}; int dangling = pre_timing{8}; // Get all values from the telescope section int telinit = telescopetimes[1]; // Initial slew time int tend = telescopetimes[2]; // Final deceleration time // No further computations needed // Dangling readout only applies if there is no dangling load in this case if(n_load_on > 0) { dangling = 0; } int closelength = duration(HIFICloseObs()); dangling = imax(dangling + closelength - tend,0); // Compute total duration int totaltime = on_pointing + dangling + tend; double tscan = double(on_inttime) / double(n_per_on * imax(n_load_on,1)); // No telescope dead time in fine pointing double tdead = 0.0; // show gyro-propagation messages // no gyro-propagation for fine_pointing GCPMessages(0,on_pointing,tend); // Return all the times needed in the observing mode modules return {totaltime,{on_inttime,on_pointing,loadlength,load_spacing,n_per_on,n_load_on,end_load_on,initlength,dangling},tscan,tdead}; } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the observing mode procedure LoadChop_commanding { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // data dump interval limited by the data rates int data_time_off = 4; // data dump interval on OFF int n_per_on = 2; // number of half load-sky-sky-load cycles on ON int n_per_off = 2; // number of half load-sky-sky-load cycles on OFF int n_loadinterval = 1; // number of nods before a load measurement int n_load_on = 0; // additional load measurements in ON pointing phase int n_load_off = 0; // additional load measurements in OFF pointing phase bool end_load_on = false; // Need for load after ON pointing phase bool end_load_off = false; // Need for load after OFF pointing phase bool final_load = false; // Need for final load measurement int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,20,1,21,0]; // Timing of the observation from telescope int loadlength = 21; // Load duration int shiftlength = 0; // Shift of the loop start relative to the pointing }{ // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time int tnodslew = telescopetimes[2]; // slew dead time between points //////////////////////////////////////////////////////////////////////// // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // // Clustering is currently not implemented in MPS - switched off here int clustered = 0; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] onrates = dataparms{1}; dataparms = DataTaking(backendreadoutparms,data_time_off); double[] offrates = dataparms{1}; int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; bool runintostate = false; while(state[0] >= 0) { if(runintostate) { state = next_state_no_check(); } else { state = next_state(); } if(state[0] == 1) { // Initialization if(clustered != 1) { HIFIInitObs(); TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal"); } delay(tinitslew - (time() - startobs) - loadlength + shiftlength - hkduration); // First load measurement HIFISetHK("normal",false); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); if(shiftlength > 0) { runintostate = true; } else { runintostate = false; } } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 7) { // The NOD-state represents our OFF position HIFIConfigureLoadChopIntegration(data_time_off,n_per_off,band,lo_freq,backendreadoutparms); // Loop for load cycles for(int i1 = 1 .. n_load_off) { HIFILoadChopOffIntegration(data_time_off,n_per_off,band,lo_freq,offrates); // Perform load calibration delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); HIFIConfigureLoadChopIntegration(data_time_off,n_per_off,band,lo_freq,backendreadoutparms); } // Last cycle - no load HIFILoadChopOffIntegration(data_time_off,n_per_off,band,lo_freq,offrates); // Second phase on OFF // occurs for even cycle numbers runintostate = false; if(state[2] % 2 == 0) { if(end_load_off) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); runintostate = true; } } else { if(state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } } if(state[0] == 3) { // The POINT-state represents out source position // ON integration HIFIConfigureLoadChopIntegration(data_time,n_per_on,band,lo_freq,backendreadoutparms); // Loop for load cycles for(int i2 = 1 .. n_load_on) { HIFILoadChopOnIntegration(data_time,n_per_on,band,lo_freq,onrates); // Perform load calibration delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); HIFIConfigureLoadChopIntegration(data_time,n_per_on,band,lo_freq,backendreadoutparms); } // Last cycle - no load HIFILoadChopOnIntegration(data_time,n_per_on,band,lo_freq,onrates); // First phase in source // occurs for odd cycle numbers runintostate = false; if(state[2] % 2 == 1) { if(end_load_on) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); runintostate = true; } } else { if(state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } } if(state[0] == 9) { // Load nod delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); runintostate = false; } if(state[0] == 5) { delay(readoutdead); if(final_load) { // Perform final load measurement // (Does not occur if end_load is set) LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } runintostate = false; HIFICloseObs(); } } } // Get frequency resolution needed to measure standing wave pattern // in load-chop measurements double procedure GetLoadChopSWResolution { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency }{ double[] dead = CalibrationReader("lchopswresolution",["resolution"],band,lo_freq); return dead[0]; } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //Not really used anymore // Initialisation for stability test, // Rotate chopper to perform backend attenuation setting on hottest spot block Stability_init_fm HIFI 3427 { string band = "1a"; // HIFI band }{ Start_block(); Chopper_Rotation_proc_fm(band,"chop_M3_ang","chop_hot_ang"); //Look at HBB } ////////////////////////////////////////////////////////////////////// // Generic procedure to call a Configure_spectroscopy command // for fast-chop observations {int,int} procedure FastConfigureSpectroscopy { /* Integration time */ int data_time = 10 in [4,128]; // data dump interval int n_int = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_data = 2; // Integration time counter /* Parameters determining the delays - used in calibration reader */ string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency /* Backend settings */ {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // HRS1/2 {used,resolution,subbands used}, WBS1/2 {used,channel windows} }{ // Get timing parameters bool wbs_used = backendreadoutparms{2}{0} || backendreadoutparms{3}{0}; {int,int,int,int,int,int,int,int,int,int,int,int,int} timing = FastConfigureSpectroscopyParams(data_time,n_int,n_data,band,lo_freq,wbs_used); int n_wbs_start = timing{0}; int r_hrs = timing{1}; int n_wbs_integr = timing{2}; int n_hrs_integr = timing{3}; int del_hrs = timing{4}; int del_wbs = timing{5}; int t_acc_wbs = timing{6}; int t_acc_hrs = timing{7}; int n_wbs1 = timing{8}; int n_hrs_trans = timing{9}; {int,int,int,int,int[],int[],string} backendconfigure = ConfigSpectroscopyBackends(data_time / 2,backendreadoutparms); int wbs_rshift = backendconfigure{0}; int hrs_rshift = backendconfigure{1}; int hrsh_sel = backendconfigure{2}; int hrsv_sel = backendconfigure{3}; int[] wbsh_par = backendconfigure{4}; int[] wbsv_par = backendconfigure{5}; string packing = backendconfigure{6}; // Now call the command Hifi_HIFI_config_spectroscopy($BBID,n_wbs_start,r_hrs,n_wbs_integr,n_hrs_integr,del_hrs,del_wbs,t_acc_wbs,t_acc_hrs,wbsh_par[0],wbsh_par[1],wbsh_par[2],wbsh_par[3],wbsh_par[4],wbsh_par[5],wbsh_par[6],wbsh_par[7],wbsv_par[0],wbsv_par[1],wbsv_par[2],wbsv_par[3],wbsv_par[4],wbsv_par[5],wbsv_par[6],wbsv_par[7],hrs_rshift,wbs_rshift,hrsh_sel,hrsv_sel,packing); // // Return dead times and comand parameters return {n_wbs1,n_hrs_trans}; } //////////////////////////////////////////////////////// // Testmodes expected to end as manual procedures // (i.e. no MTL commands) for MOC // DT - 27-02-07 //////////////////////////////////////////////////////// //Warm-up of 3b band mode HifiManCmd_LO_Warmup_3b { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! }{ mois_comment("Procedure Switch-on LO band 3b with safe settings"); StartMode_block_ops(); // mois_step("Switch-on LOU 3b with safe settings"); LCU_switchon_proc_spur("3b"); mois_step("Apply higher Vd2"); LCU_switchon_proc_spur("3b"); // StopMode_block_ops(); // -> to issue last obsd/bbid } //Generic procedure to launch engineering scan applied to chopper rotation, procedure procedure Engineering_scan_for_closed_loop_scan { double targetAngle = 0.0; //Target chopper voltage int milliSecSample = 3; // interval between samples int samplesBefore = 30 in [0,50]; // HIF_N_samples_1 int samplesAfter = 1000 in [0,1000]; // HIF_N_samples_2 }{ // HIFI_Chopper_scan_fast_proc_fm(milliSecSample,targetAngle,samplesBefore,samplesAfter); // // delay calculation int nb_HK = 1; //For this TC, the 2 last HK fields are blanked out int millisecondsUsed = 1000 + 10 + milliSecSample * nb_HK * (samplesBefore + samplesAfter); delay(iceil(0.0010 * double(millisecondsUsed))); // } // LCU1a tune: bit flip test, procedure // ALL DELAYS DECREASED TO 1 SEC. procedure LCU1a_bit_flip_proc_fm { string band = "1a"; // HIFI band double lo_freq = 500.0 in [488.0,552.0]; //LO frequency double drain_2_factor = 100.0; //Percentage factor of the targetted drain voltage int n = 100; //number of loops }{ error("This module is obsolete: use LCU_bit_flip_proc_fm instead"); } // Change LO frequency by a small step // // Externally it has to be guaranteed that this never uses a step larger // than one index in the LO table procedure HIFIChangeFreq { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency ion MHz }{ ConfigureFPU(band,lo_freq,false); HIFITuneFreqNoretune(band,lo_freq); } {int,double,double,double,double,double} obs HifiMappingModeDBSCross { string modeName = "cross"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_switch_on = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode OpenMessages("HIFI Mapping - DBS Cross Map slowChop",{data_time,0,0,n_switch_on,0,0,n_pointsperscan,0,n_cycles,load_interval}); // Call first part of the timing computer {int,int,int,int,int,int,int,int,int,int,int,int,int} pre_timing = DBSRaster_pre_timing(2,npoints,band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_switch_on,n_pointsperscan,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,bool,double,double,double,double[],double[],int[],double,double,int,int,int,int,int,int} tpar = DBSCross_telescope(naifid,onPosition,stepsize,npoints,band,lo_freq,"",pre_timing,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = custom_map_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21}); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,int},bool,double,double} post_timing = DBSCross_post_timing(pre_timing,telescopetimes,npoints,n_switch_on,n_cycles,load_interval,false); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = DBSCross_telescope(naifid,onPosition,stepsize,npoints,band,lo_freq,"",post_timing{1},n_cycles); telescopetimes = custom_map_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21}); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{3}; int n_load = post_timing{1}{6}; int n_loadinterval = post_timing{1}{7}; int n_seq = post_timing{1}{8}; int scansize = post_timing{1}{10}; int initlength = post_timing{1}{11}; int dangling = post_timing{1}{12}; bool final_load = post_timing{2}; double tscan = post_timing{3}; double tdead = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { DBSRaster_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_seq,n_cycles,scansize,n_loadinterval,n_load,final_load,startobs,telescopetimes,loadlength,true); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double} tact = DBSRaster_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_seq,n_load,scansize,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = DBS_noisecomputer(band,lo_freq,effResolution,continuumDetection,oneGHzReference,n_cycles,tscan,tact); // Evaluate performance DBSRaster_performance(band,lo_freq,effResolution,noisevalues,timeTaken,2,npoints,n_cycles,n_seq * imax(n_load,1),tact); // Correct for double counting of central point // The central point noise is returned only double multiplier = sqrt(0.5); noisevalues{0} = noisevalues{0} * multiplier; noisevalues{1} = noisevalues{1} * multiplier; noisevalues{2} = noisevalues{2} * multiplier; noisevalues{3} = noisevalues{3} * multiplier; noisevalues{4} = noisevalues{4} / multiplier; // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } {string,double,double}[] procedure HifiSScanModeLoadChopSequencerInit { string modeName = "load-freq"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 2 in [1,900]; // number of half load-sky-sky-load cycles per frequency and pointing int n_switch_off = 1 in [1,900]; // number of half load-sky-sky-load cycles on OFF int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int n_cycles = 1 in [1,600]; // Number of half OFF-ON-ON-OFF cycles at one frequency int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,redundancy,wbs1Used,wbs2Used,data_time); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hr1{0},hr1{1},hr1{3}},{hr2{0},hr2{1},hr2{3}},wb1,wb2}; // Get frequency grid characteristic parameters {double,int,double} gfref = GetFReference(band,lo_freq,lo_freq_up); double reffreq = gfref{0}; int stdredun = gfref{1}; double stdstep = gfref{2}; int increment = stdredun / redundancy; // allowed group size double nocaliblen = GetFNoCalibLength(band,reffreq); int n_freq_point_guess = ifloor(nocaliblen / (stdstep * double(increment)) + 1.0); int n_freq_point_range = 1 - n_freq_point_guess; if(n_freq_point_range == 0) { n_freq_point_range = 1; } // Now general part of LoadChop modes {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // limits from noise section // spectral scans always use the full bandwidth for reference bool narrowReference = false; {double,double,double,double} phaselengths = LoadChopPhaseLengths(band,lo_freq,effResolution,narrowReference); // Compute derived quantities int data_time_guess = imin(imax(iceil(phaselengths{1}),datalimit),20); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } // How much time for single ON phase int n_switch_on_guess = imax(iceil(2.0 * phaselengths{0} / ((double(n_freq_point_guess) + sqrt(double(n_freq_point_guess))) * 2.0 * double(data_time_guess))),1); int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } // OFF phase int data_time_off_guess = imin(imax(iceil(phaselengths{2}),datalimit),20); int data_time_off_range = datalimit - data_time_off_guess; if(data_time_off_range == 0) { data_time_off_range = 1; } int n_switch_off_guess = imax(iceil(double(data_time_guess * n_switch_on_guess) * sqrt(double(n_freq_point_guess)) / (double(data_time_off_guess) * sqrt(phaselengths{3} / effResolution{1}))),1); int n_switch_off_range = 1 - n_switch_off_guess; if(n_switch_off_range == 0) { n_switch_off_range = 1; } // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"data_time_off",double(data_time_off_guess),double(data_time_off_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)},{"n_switch_off",double(n_switch_off_guess),double(n_switch_off_range)},{"n_freq_point",double(n_freq_point_guess),double(n_freq_point_range)}]; return retvalues; } // LCU4a configuration into SAFE mode, procedure procedure LCU4a_config_safe_proc_fm { string band = "4a"; // HIFI band double lo_freq = 1000.0 in [967.0,1042.0]; //LO frequency }{ error("This module is obsolete: use LCU_config_nominal_proc_fm instead"); } //// END OF OBSOLETE MODULES //////////////////// //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // CUS for (some of the) stability tests. // // DT - 18 May 2004: first draft // DT - 19 Aug.2004: - Split tests into various pairs of loads // instead of doing all in a single testmode // - Allow short (1 spec/phase) for non-modulated // integrations and and long (3 spec/phase) // for differential integrations // - Allow non-modulated integration // 19 Sep 2004: - Updated for QM // 20 Jul 2005: - Updated for FM. Added new BBID to distinguish // between tests without IF/IF1/IF2, etc.. // //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //!!!!!!!!!!!!!!!!!!!!!!!!!! // Modes //!!!!!!!!!!!!!!!!!!!!!!!!!! //modes: see fm_testmodes.cus //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Associated high level procedures //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Very fast sampling stability measurement combined with int-load-chop // Uses only the HRS in wb mode procedure Stability_chopped_fasthrs_proc_fm { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 522.0; // LO frequency int phaselength = 10; // Chop phase length int nchop = 10; // Number of phases double readout = 0.333; // HRS readout length double[] hrs_subband = [5.0,5.0,5.0,5.0]; //Positions in IF of HRS sub-bands }{ // Configuration and tuning //Configure HRS: regardless of selected bands HRS_config_resol_block_fm(band,["wb1","wb1"]); HRS_config_att_lo_w_lo_input_block_fm(band,["wb1","wb1"],hrs_subband); //Tune backend on cold load Chopper_Rotation_block_fm(band,"chop_M3_ang","chop_cold_ang"); //Look at CBB HRS_tune_block_fm(band); // Clean HK treatment for controlled data rates HIFISetHK("fast",false); {string,int,double,double,double,double} hkparms = PeriodicHKParms("fast"); // HK data: stdrate=7744+864+2*272, IF packets=2*(592+272) int allhkbits = 1782; double hkrate = hkparms{3} + double(allhkbits) / readout; // Science data: 2*(2*258*24+1376+3*272) int allbits = 29152; double sciencerate = double(allbits) / readout; // set data rates ess_hk_data_rate(hkparms{5} / 1024.0); non_ess_hk_data_rate(hkrate / 1024.0); data_rate(sciencerate / 1024.0); // Run the actual chopped fast-HRS interation Stability_chopped_fasthrs_block(band,lo_freq,phaselength,nchop,readout); // reset data rates non_ess_hk_data_rate(hkparms{3} / 1024.0); data_rate(0.0); } // WBS attenuator tuning, block // Both polarizations are treated block WBS_tune_block_aot HIFI 6603 { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band; }{ // Get tuning goal {double,string}[] result_d = ConfigurationReader("name_configwbs",["tune_target"],band,0.0); int tune_target = iround(result_d[0]{0}); // Perform tuning Tune_WBS_aot(band,tune_target); } //Diplexer FSW investigation: phase-block procedure Dip_FSW_A_phase { string band = "3a" in ["3a","3b","4a","4b","6a","6b","7a","7b"]; // HIFI band bool retune = true; //whether the diplexer is adjusted between frequencies or not double lo_freq1 = 810.0; double lo_freq_ref = 810.0; int[] res = [4,1]; string backend = "both"; string polarization = "H" in ["H","V"]; //The polarization on which the test is done bool modulate = true; //whether we change FSW register and DPACT }{ //Integrate at FSW1 if(modulate) { Activate_FSW_register_block_fm("FSW1"); if(retune) { Set_Single_Diplexer_current_block_fm(band,lo_freq1,polarization); } else { Set_Single_Diplexer_current_block_fm(band,lo_freq_ref,polarization); } } else { //Hifi_HIFI_noop(); } Spectro_total_power_AOTLike_block_fm(band,res,backend); //Add 2sec for investigation of SPR-2404 delay(2); } //HIFI-COP-2.3-CPR-Scan1 procedure Chopper_calibration_COP_proc_ops { int band = 1 in [1,7]; // HIFI mixer band bool sky = true; //whether or not we scan over M3 area int integ_time = 4; //Integration time PER PHASE for the slowchop measurement bool shutter_used = false; string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int freq_index = 1 in [1,3]; //Frequency index: 2 is forbidden if sky=true }{ // //Read band+freq to perform string tab = "configchoppercalib_freq.config"; int total = table_size(tab); double[] freq = []; string[] subband = []; //We know that mixer bands have at most 3 freq. points int i = 3 * (band - 1) + freq_index; //If sky path scanned, index 2 is forbidden if(sky && freq_index == 2) { error("You cannot select frequency index 2 is option sky is selected"); } else { // freq[i] = dlookup(tab,"" + i,"frequency"); subband[i] = slookup(tab,"" + i,"subband"); //Check whether this combination of band+freq is allowed in the current CUS Check_Band_vs_Freq_proc_fm(subband[i],freq[i]); // //Warm-up time for LO switch-on or frequency change LCU_switchon_proc_fm(subband[i]); //Wait an extra delay of 1 min for short term stabilization delay(60); // Init_MSA_HBB_fm(subband[i],"CLOSE",freq[i],"ON"); LO_tuning_block_fm(subband[i],freq[i]); Chopper_calibration_proc_fm(band,integ_time,shutter_used,sky,hrs_mode); message("band " + subband[i] + ", LO freq " + freq[i]); } // } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // CUS scripts for spectroscopy operations // Dedicated FT for spectroscopy are in fm_FT_Spectro.cus // // DT - 17-Feb-06 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //The modes //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //modes: see fm_testmodes.cus //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //The procedures //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Spectrometer configuration for total power, procedure int[] procedure Configure_Spectrometer_proc_fm { string band = "1a"; // HIFI band int integ_time = 4; //Total integration time in sec. string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4,wb5,wb6,wb7,wb8 string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //First derive backend setting codes as expected by VO's routine //Build up backend parameter tupple: {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = BackendSettings(band,0.0,hrs_mode,backend); // Readout parameters for HRS1,HRS2, WBS1,WBS2 //Compute data_time and n_switch use the wrapper int[] res = ConfigSlowChop(integ_time,"tp",band,0.0,backendreadoutparms); int data_time = res[0]; int n_switch = res[1]; // Now call the spectroscopy setup: it is common to ILT and AOT CUS. // The deadtimes output is not used at ILT level. {double,double} dtimes = ConfigSpectroscopySlowChop_IST(data_time,n_switch,"tp",band,0.0,backendreadoutparms,true); // return res; } // Procedure to perform the HRS tuning including the counting // of the science data, must be called within a building block procedure Tune_HRS_aot { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band }{ //Get delay {double,string}[] result_d = ConfigurationReader("name_delays",["hrs_tune_delay"],band,0.0); int hrs_tune_delay = iround(result_d[0]{0}); // data frame transmission time (always 2 spectra) int data_time = hrs_tune_delay / 2; int rest_delay = hrs_tune_delay - 2 * data_time; hrs_tune_delay = hrs_tune_delay - rest_delay; // Compute data rates // The HIFI command reads out both full WBS {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} fullreadoutparms = FrequencyCalibrationParms(false,false,true,true); {int,double[]} fdataparms = AllDataRates(fullreadoutparms,data_time,false); // set data rates (IF power packets are ignored here) data_rate(fdataparms{1}[0] / 1024.0); //Now tune attenuators: it sets the HRS to ultra_wide Hifi_HIFI_Tune_HRS($BBID); delay(hrs_tune_delay); // // reset data rates data_rate(0.0); delay(rest_delay); } ////////////////////////////////////////////////////////////////////// // Procedure to perform the noise level evaluation for the observing mode // // The sum of drift noise and radiometric noise is computed. {double,double,double,double,double} procedure DBS_noisecomputer { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuum = false; // Whether timing is for total-power level bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF int n_cycles = 1; // Number of half OFF-ON-ON-OFF pointing cycles double tscan = 60.0; // Total average duration of one scan {double,double,double} tact = {10.0,4.9,0.05}; // Field of actual dead and integration times }{ double tdead = tact{0}; // Average total dead time in one scan double inttimeperphase = tact{1}; // Actual integration time double deadtimeperphase = tact{2}; // Dead time per switch phase // Get parameters which are needed double tsys = InterpolateTsys(band,lo_freq); double eta_mb = InterpolateCoupling(band,lo_freq); double[] gssb = InterpolateGssb(band,lo_freq); // Get the drift parameters to compute the drift noise if(continuum) { double[] allanparms = InterpolateTpAllan(band,lo_freq,oneGHzReference); } else { allanparms = InterpolateSpecAllan(band,lo_freq,oneGHzReference); } // rescale to frequency resolution double alpha = allanparms[1]; double binningexp = 1.0 / allanparms[2]; double allan_time_lores = allanparms[0] * pow(1.0 / eff_resolution{1},binningexp); double allan_time_hires = allanparms[0] * pow(1.0 / eff_resolution{0},binningexp); // Differential Allan variance if(continuum) { allanparms = InterpolateTpChopAllan(band,lo_freq,oneGHzReference); } else { allanparms = InterpolateSpecChopAllan(band,lo_freq,oneGHzReference); } // rescale to frequency resolution double dalpha = allanparms[1]; binningexp = 1.0 / allanparms[2]; double dallan_time_lores = allanparms[0] * pow(1.0 / eff_resolution{1},binningexp); double dallan_time_hires = allanparms[0] * pow(1.0 / eff_resolution{0},binningexp); // Compute the relative noise for the detailed timing double deadtimeperswitch = deadtimeperphase; double inttime = (tscan - tdead) / 2.0; // Get actual noise // This is returned twice: for both limiting resolutions double systemnoise_lores = DoubleDifferenceNoise(inttimeperphase / allan_time_lores,[1.0,1.0,inttime / allan_time_lores,inttime / allan_time_lores,deadtimeperswitch / allan_time_lores,tdead / allan_time_lores,alpha,dallan_time_lores / allan_time_lores,dalpha]); double systemnoise_hires = DoubleDifferenceNoise(inttimeperphase / allan_time_hires,[1.0,1.0,inttime / allan_time_hires,inttime / allan_time_hires,deadtimeperswitch / allan_time_hires,tdead / allan_time_hires,alpha,dallan_time_hires / allan_time_hires,dalpha]); double noiseratio = DoubleDifferenceNoiseRatio(inttimeperphase / allan_time_lores,[1.0,1.0,inttime / allan_time_lores,inttime / allan_time_lores,deadtimeperswitch / allan_time_lores,tdead / allan_time_lores,alpha,dallan_time_lores / allan_time_lores,dalpha]); // Compute total double sideband noise // Correct for signal in difference phase double dsbnoise_lores = tsys * sqrt(systemnoise_lores / (eff_resolution{1} * 4000000.0 * double(n_cycles) * tscan)); double dsbnoise_hires = tsys * sqrt(systemnoise_hires / (eff_resolution{0} * 4000000.0 * double(n_cycles) * tscan)); // Translate to the main beam scale, correct for eta_mb // (This is typically not done at ground based telescopes, // but leads often to problems there - to be discussed.) dsbnoise_lores = dsbnoise_lores / eta_mb; dsbnoise_hires = dsbnoise_hires / eta_mb; // Get single sideband noise equivalent double usbnoise_lores = dsbnoise_lores / gssb[0]; double usbnoise_hires = dsbnoise_hires / gssb[0]; double lsbnoise_lores = dsbnoise_lores / gssb[1]; double lsbnoise_hires = dsbnoise_hires / gssb[1]; // Return noise values and the maximum ratio of drift to radiometric noise return {usbnoise_lores,usbnoise_hires,lsbnoise_lores,lsbnoise_hires,noiseratio}; } //Recalculation of checksum //To be run only after upload of both mode HifiManCmd_recalc_LCU_checksum_flight { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! string section = "P" in ["P","R"]; }{ mois_comment("This procedure cannot be performed before completion of both HIF_CUPM and HIF_NUT"); mois_step("Recompute checksum and verify against expected value"); StartMode_block_ops(); LcuChecksumRecalc_ops(section); StopMode_block_ops(); } //Set LOU to nominal, block //Set LOU in nominal mode with no channel selected block Set_LO_Nominal_block_aot HIFI 6626 { }{ {double,string}[] result = ConfigurationReader("name_delays",["set_to_nominal_delay"],"0",0.0); int set_to_nominal_delay = iround(result[0]{0}); // Hifi_HIFI_HL_Normal($BBID); delay(set_to_nominal_delay); // } //General script to clear error flags and set to nominal, block block LCU_enable_all_bands_block_fm HIFI 3769 { }{ // //switch to standby {double,string}[] result = ConfigurationReader("name_delays",["stdby_delay"],"0",0.0); int stdby_delay = iround(result[0]{0}); mois_comment("Set LOU to standby"); Hifi_HIFI_HL_Standby($BBID); delay(stdby_delay); //Enable all bands mois_comment("Enable all bands"); mois_spacon("In the next TC, parameters HP444194 and HP443194 should be treated as FP"); Hifi_HIFI_Conf_LCU_internal($BBID,16383,"RESET","RESET",256); //sets bandmask to 3FFF: all bands //LSU_delta_f: 256 = 88mV // } // Procedure used by the mapping sequencer to compute the // OFF integration time int procedure SpotOTFOffTime { /* Basic setup */ string band = "4a"; double fe_lof_0 = 978.2; /* Map parameters */ double flyX = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; /* Other sequence parameters */ int n_int_on = 1; int n_linesperscan = 1; }{ // start Volkers list double lo_freq = 978200.0; // Lower LO frequency limit in MHz int nlines = 1; double stepsize = 0.0; int npoints = 1; // general definitions double factorMHzPerGHz = 1000.0; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; // start translation lo_freq = fe_lof_0 * factorMHzPerGHz; // Map size stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,lo_freq); stepsize = s[0]; } npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); // derive OFF integration time double n_pointsperscan = double(n_linesperscan * npoints); int n_switch_off = iceil(double(n_int_on) * 0.67 * sqrt(n_pointsperscan)); return n_switch_off; } ///////////////////////////////////////////////////////////////// // New routine to select the reference frequency as the median // of the three relevant points with respect to Tsys double procedure ComputeReferenceFreq { string band = "4a"; // HIFI band double lo_freq1 = 978200.0 in [480000.0,1950000.0]; // LO frequency double lo_freq2 = 979600.0 in [480000.0,1950000.0]; // LO frequency }{ // standard guess - center of the interval double reffreq = 0.5 * (lo_freq1 + lo_freq2); double t1 = InterpolateTsys(band,reffreq); double t2 = InterpolateTsys(band,lo_freq1); double t3 = InterpolateTsys(band,lo_freq2); // first check for exclusion of really bad values double excludelimit = 1.414; // sqrt(2) factor double bestt = min(min(t1,t2),t3); excludelimit = excludelimit * bestt; bool twoexcluded = false; // go through the three possible combinations if(t1 > excludelimit && t2 > excludelimit) { reffreq = lo_freq2; twoexcluded = true; } if(t1 > excludelimit && t3 > excludelimit) { reffreq = lo_freq1; twoexcluded = true; } if(t2 > excludelimit && t3 > excludelimit) { twoexcluded = true; } // Treatment for at least two valid points - use median if(!twoexcluded) { // go through the possible combinations if(t1 > t2 && t2 >= t3 || t1 < t2 && t2 <= t3) { reffreq = lo_freq1; } if(t1 > t3 && t3 > t2 || t1 < t3 && t3 < t2) { reffreq = lo_freq2; } } return reffreq; } ////////////////////////////////////////////////////////////////////// // Procedure to display performance parameters of the observing mode procedure DBSRaster_performance { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {double,double,double,double,double} noisevalues = {1.0,1.0,1.0,1.0,0.0}; // Noise values from noisecomputer int totaltime = 200; // Total observing time int nlines = 20; // Number of lines in the map int npoints = 20; // Number of points in the map int n_cycles = 1; // Number of nodding cycles int n_chop = 1; // number of chop cycles {double,double,double} tact = {10.0,4.9,0.05}; // Field of actual dead and integration times }{ double inttimeperphase = tact{1}; // Actual integration time in ON phase // Get performance of ideal instrument for comparison {int,double,double,double,double,double} idealvalues = IdealInstrument(band,lo_freq,eff_resolution,totaltime); double idealnoise = idealvalues{1} * idealvalues{1}; double obsnoise = noisevalues{0} * noisevalues{0}; // rescale for map coverage idealnoise = idealnoise * double(npoints * nlines); double efficiency = idealnoise / obsnoise; // Compute the actual integration time double posinttime = double(npoints * nlines * n_cycles * 2 * n_chop) * inttimeperphase; // Check total integration time double timeefficiency = 2.0 * posinttime / double(totaltime); // Noise contribution double relnoise = noisevalues{4} / (1.0 + noisevalues{4}); // Non-standard messages message("

"); message("The observed map consists of " + nlines + " lines with " + npoints + " points in each line.
"); // General messages PerformanceMessages(band,lo_freq,totaltime,posinttime,posinttime,timeefficiency,efficiency,relnoise,false); } //Single parameter change in FPU setting, block //Testmode dedicated to tests on FPU-C sim. Parameters //are changed 1 by 1 by operator and directly measured on simulator block Single_FPU_Param_Change_block_fm HIFI 3648 { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 522.0; //LO frequency string param_code = "DIPL" in ["DIPL","MAGN","MBIAS","CHOPV","CALIBC","FIF1V","FIF1C","FIF2V","FIF2C","SIF1V","SIF1C","SIF2V","SIF2C","SIF3V","SIF3C"]; //The parameter to scan: DIPL, MAG, MBIAS, FIF/SIF1V/C, FIF/SIF2V/C, SIF3V/C double param_value = 0.0; //Value for parameter to be set string context = "warm" in ["warm","cold"]; //Test context: warm or cold }{ Start_block(); //Read out all parameters as in config files: does as init_MSA. //Get parameters {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,lo_freq); if(context == "warm") { result_d = ConfigurationReaderWarm("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,lo_freq); } int band_nb = iround(result_d[0]{0}); double diplex_H = 0.0; double diplex_V = 0.0; int diplex_h_ctrl_mode = 0; int diplex_v_ctrl_mode = 0; // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,lo_freq); if(context == "warm") { result_d = ConfigurationReaderWarm("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,lo_freq); } // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // string chop_sine_s = "ON"; string chop_loop = "CLOSE"; result_d = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,lo_freq); if(context == "warm") { result_d = ConfigurationReaderWarm("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,lo_freq); } // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // double calibcurrent = result_d[7]{0}; // //Get biases result_d = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); if(context == "warm") { result_d = ConfigurationReaderWarm("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); } double bias_H = result_d[0]{0}; double bias_V = result_d[1]{0}; //Get magnets: not applicable to bands 6 and 7 double magnetcurrent_H = 0.0; double magnetcurrent_V = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,lo_freq); if(context == "warm") { result_d = ConfigurationReaderWarm("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,lo_freq); } magnetcurrent_H = result_d[0]{0}; magnetcurrent_V = result_d[1]{0}; } //Diplexer is interpolated from a table for Bands 3, 4, 6L and 6H if(band_nb <= 2 || band_nb == 5) { diplex_H = 0.0; //For bands 1, 2 and 5 diplex_V = 0.0; diplex_h_ctrl_mode = 0; diplex_v_ctrl_mode = 0; } else { //Get diplexer currents result_d = ConfigurationReader("name_confilfpu",["diplex_h_ctrl_mode","diplex_v_ctrl_mode"],band,lo_freq); if(context == "warm") { result_d = ConfigurationReaderWarm("name_confilfpu",["diplex_h_ctrl_mode","diplex_v_ctrl_mode"],band,lo_freq); } diplex_h_ctrl_mode = iround(result_d[0]{0}); diplex_v_ctrl_mode = iround(result_d[1]{0}); double[] result_dip = Get_Diplexer_setting(band,lo_freq); diplex_H = result_dip[0]; diplex_V = result_dip[1]; } // //Chopper on hot load result_d = ConfigurationReader("name_confilfpu",["chop_hot"],band,lo_freq); if(context == "warm") { result_d = ConfigurationReaderWarm("name_confilfpu",["chop_hot"],band,lo_freq); } double chopper = result_d[0]{0}; // //Update parameter changed by user if(param_code == "DIPL") { diplex_H = param_value; diplex_V = param_value; } if(param_code == "MAGN") { magnetcurrent_H = param_value; magnetcurrent_V = param_value; } if(param_code == "MBIAS") { bias_H = param_value; bias_V = param_value; } if(param_code == "CHOPV") { chopper = param_value; } if(param_code == "CALIBC") { calibcurrent = param_value; } if(param_code == "FIF1V") { volt_H_FIF_1 = param_value; volt_V_FIF_1 = param_value; } if(param_code == "FIF1C") { curr_H_FIF_1 = param_value; curr_V_FIF_1 = param_value; } if(param_code == "FIF2V") { volt_H_FIF_2 = param_value; volt_V_FIF_2 = param_value; } if(param_code == "FIF2C") { curr_H_FIF_2 = param_value; curr_V_FIF_2 = param_value; } if(param_code == "SIF1V") { volt_H_SIF_1 = param_value; volt_V_SIF_1 = param_value; } if(param_code == "SIF1C") { curr_H_SIF_1 = param_value; curr_V_SIF_1 = param_value; } if(param_code == "SIF2V") { volt_H_SIF_2 = param_value; volt_V_SIF_2 = param_value; } if(param_code == "SIF2C") { curr_H_SIF_2 = param_value; curr_V_SIF_2 = param_value; } if(param_code == "SIF3V") { volt_H_SIF_3 = param_value; volt_V_SIF_3 = param_value; } if(param_code == "SIF3C") { curr_H_SIF_3 = param_value; curr_V_SIF_3 = param_value; } // chopper = Check_Chopper_Prime_Redundant(chopper); HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result_d = ConfigurationReader("name_delays",["config_fpu_delay"],band,lo_freq); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); } //Set LCU1b back to standby status, procedure procedure LCU1b_standby_proc_fm { string band = "1b"; // HIFI band double lo_freq = 600.0 in [566.0,633.0]; //LO frequency }{ error("This module is obsolete: use LCU_standby_proc_fm instead"); } // Integrate with only backends, block // We take 1 spectrum per phase. block Stability_backend_fm HIFI 3428 { string band = "1a"; // HIFI band int n = 100; //The number of integrations int integ_time = 4; //Total integration time in sec. to be set at end of test string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code }{ Start_block(); //The system as is should be ready //No use of FPU capabilities. // //Do a long integration: 4 sec. is OK //We implement a special spectroscopy configuration with fixed values Total_power_spectro_for_Stability_proc_fm(band,n,integ_time,backend,hrs_mode); } //HIFI LO tuning only for M3 investigation in 3b, block //Target current is read from look-up table block LO_tuning_w_M3_block_fm HIFI 3818 { string band = "3b" in ["3b","3b"]; // HIFI band double lo_freq = 930.0; //LO frequency double m3 = -0.5; //M1 multiplier voltage }{ //Clear potential failure mode Set_LO_Nominal_proc_fm(); // //Start_block(); {double,string}[] result = ConfigurationReader("name_confpolar4lotune",[band],band,lo_freq); string mixer_polarization = result[0]{1}; // //Get target mixer current result = ConfigurationReader("name_confilmix",["target_mx_c_h","target_mx_c_v"],band,lo_freq); double target_current = result[0]{0}; if(mixer_polarization == "V") { target_current = result[1]{0}; } if(mixer_polarization == "B") { target_current = 0.5 * (result[1]{0} + result[0]{0}); } // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; name_configlcutune = "name_configlcutune_b"; } // result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = m3; //result[3]{0}; int d2_step = iround(result[4]{0}); // //multiplier settings which are not passed as input must be //taken from safe table if(band == "3b") { double[] cresult = CalibrationReader("name_lcu_safe_values",["m1_v","m2_v","m3_v"],band,lo_freq); m1_v = cresult[0]; m2_v = cresult[1]; } // cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // result = ConfigurationReader(name_configlotune,["step_drain2_v","nsteps","step_time"],band,lo_freq); double step_drain2_v = result[0]{0}; int nsteps = iround(result[1]{0}); double step_time = result[2]{0}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // //Adjust scan cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); double drain2_safe = cresult[0]; // double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); // //For all bands, scan will be done with decreasing drain2 voltages //The best guess is taken from look-up table double tune_range = 0.1; result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lo_freq); double middle_d2 = result[0]{0}; double drain2_v_start = drain2_bluemax; //min(middle_d2*(1.+tune_range/2.),drain2_bluemax); double drain2_v_end = (1.0 - tune_range / 2.0) / (1.0 + tune_range / 2.0) * middle_d2; //drain2_v_start; step_drain2_v = (drain2_v_end - drain2_v_start) / double(nsteps - 1); // result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); // if(band == "3b") { Hifi_HIFI_Conf_nom_LCU_ch3b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,macro_checksum); //Send command: specific to M3 in 3b delay(config_lo_delay); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } else { // //General command HIFI_Configure_LCU_proc_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,macro_checksum,config_lo_delay); } // //delay(5); //to settle at this value // //Load vector scan //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Load_vector_safe_1a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "1b") { //Band 1b Hifi_HIFI_Load_vector_safe_1b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2a") { //Band 2a Hifi_HIFI_Load_vector_safe_2a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2b") { //Band 2b Hifi_HIFI_Load_vector_safe_2b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3a") { //Band 3a Hifi_HIFI_Load_vector_safe_3a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3b") { //Band 3b Hifi_HIFI_Load_vector_nom_3b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "4a") { //Band 4a Hifi_HIFI_Load_vector_safe_4a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "4b") { //Band 4b Hifi_HIFI_Load_vector_safe_4b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "5a") { //Band 5a Hifi_HIFI_Load_vector_nom_5a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "5b") { //Band 5b Hifi_HIFI_Load_vector_nom_5b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6a") { //Band 6a Hifi_HIFI_Load_vector_nom_6a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6b") { //Band 6b Hifi_HIFI_Load_vector_nom_6b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7a") { //Band 7a Hifi_HIFI_Load_vector_nom_7a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7b") { //Band 7b Hifi_HIFI_Load_vector_nom_7b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } // delay(1); // //Execute tuning: check which mixer is to be used if(mixer_polarization == "V") { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCV($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCV($BBID,target_current); } } else { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCH($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCH($BBID,target_current); } } // double time_needed = double(nsteps) * step_time; delay(iround(time_needed + 2.0 + 0.5)); //0.5s added for completion of load_vector // //Store settings into available register HIFI_HL_store_tm_only_proc_fm(); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } ////////////////////////////////////// // Procedures ////////////////////////////////////// // HRS partial configuration, procedure // Configures the resolution mode procedure HRS_config_resol_proc_ops { string band = "0"; // HIFI band string[] hrs_mode = ["wb","wb"]; //HRS resolution code }{ //////////////////////////////////////////////////////////////////// //Now Configure blocks //H-polar string hrs_filename_h = "name_confighrs_" + hrs_mode[0]; {double,string}[] result = ConfigurationReader(hrs_filename_h,["hrh_block_1","hrh_block_2","hrh_block_3","hrh_block_4","hrh_block_5","hrh_block_6","hrh_block_7","hrh_block_8"],band,0.0); string hrh_block_1 = result[0]{1}; string hrh_block_2 = result[1]{1}; string hrh_block_3 = result[2]{1}; string hrh_block_4 = result[3]{1}; string hrh_block_5 = result[4]{1}; string hrh_block_6 = result[5]{1}; string hrh_block_7 = result[6]{1}; string hrh_block_8 = result[7]{1}; string resol_mode_h = hrh_block_3; // result = ConfigurationReader("name_delays",["hrs_config_delay"],band,0.0); int hrs_config_delay = iround(result[0]{0}); // Hifi_HIFI_Config_HRS_H_blocks($BBID,hrh_block_1,hrh_block_2,hrh_block_3,hrh_block_4,hrh_block_5,hrh_block_6,hrh_block_7,hrh_block_8); //delay(hrs_config_delay); // //V-polar string hrs_filename_v = "name_confighrs_" + hrs_mode[1]; result = ConfigurationReader(hrs_filename_v,["hrv_block_1","hrv_block_2","hrv_block_3","hrv_block_4","hrv_block_5","hrv_block_6","hrv_block_7","hrv_block_8"],band,0.0); string hrv_block_1 = result[0]{1}; string hrv_block_2 = result[1]{1}; string hrv_block_3 = result[2]{1}; string hrv_block_4 = result[3]{1}; string hrv_block_5 = result[4]{1}; string hrv_block_6 = result[5]{1}; string hrv_block_7 = result[6]{1}; string hrv_block_8 = result[7]{1}; string resol_mode_v = hrv_block_3; // Hifi_HIFI_Config_HRS_V_blocks($BBID,hrv_block_1,hrv_block_2,hrv_block_3,hrv_block_4,hrv_block_5,hrv_block_6,hrv_block_7,hrv_block_8); // //Wait delay to allow all setting to be configured delay(hrs_config_delay); //Check HK - depends on the configured mode if(hrs_mode[0] == "hr") { resol_mode_h = "corr_high"; } if(hrs_mode[1] == "hr") { resol_mode_v = "corr_high"; } if(hrs_mode[0] == "mr") { resol_mode_h = "corr_nominal"; } if(hrs_mode[1] == "mr") { resol_mode_v = "corr_nominal"; } //removed as this only appears when taking science data //mois_tmcheck("Check that parameters HRH_config and HRV_config are respectively " + resol_mode_h + " and " + resol_mode_v); } //////////////////////////////////// // Test mode - Load chop mode without baseline calibration // {int,double,double,double,double,double} obs HifiPointProcLoadChopNoRef_FCal { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rates int n_cycles = 2 in [1,3600]; // number of half load-sky-sky-load cycles on ON int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Engineering - Load Chop noRef newComb",{data_time,0,0,0,0,0,0,0,n_cycles,load_interval}); // Call first part of the timing computer {int,int,int,int,int,int,bool,int,int} pre_timing_f = LoadChopNoRef_FCal_pre_timing(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_cycles,load_interval,docommands); // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,double,double,int} tpar_f = Fine_telescope(naifid,onPosition,band,lo_freq,pre_timing_f); // Dummy call to spacecraft command int[] telescopetimes = basic_fine_pointing(false,tpar_f{0},tpar_f{1},tpar_f{2},tpar_f{3},tpar_f{4},tpar_f{5},tpar_f{6},tpar_f{7},tpar_f{8},tpar_f{9}); // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,bool,int,int},double,double} post_timing_f = SingleChopNoRef_post_timing(pre_timing_f,telescopetimes); // Now the actual observation starts // Prepare telescope command tpar_f = Fine_telescope(naifid,onPosition,band,lo_freq,post_timing_f{1}); // Call telescope command telescopetimes = basic_fine_pointing(true,tpar_f{0},tpar_f{1},tpar_f{2},tpar_f{3},tpar_f{4},tpar_f{5},tpar_f{6},tpar_f{7},tpar_f{8},tpar_f{9}); // Consistency check int totaltime = post_timing_f{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following ////////////////////////////////////////////////////////////////////// // standard parameters for fine pointing int loadlength = post_timing_f{1}{2}; int n_per_on = post_timing_f{1}{4}; int n_load_on = post_timing_f{1}{5}; bool end_load_on = post_timing_f{1}{6}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands ////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { LoadChopNoRef_FCal_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_per_on,n_load_on,end_load_on,startobs,telescopetimes,loadlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // There are no telescope dead times involved in this mode {double,double,double} tact = SingleChop_deadtimes("lchop",band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_per_on); double tscan = 2.0 * (tact{1} + tact{2}); double tdead = 2.0 * tact{2}; // // Call noise computer {double,double,double,double,double} noisevalues = PositionSwitch_noisecomputer(band,lo_freq,effResolution,oneGHzReference,n_per_on * (n_load_on + 1),tscan,tdead); // Evaluate performance SingleChopNoRef_performance(band,lo_freq,effResolution,noisevalues,timeTaken,n_per_on * (n_load_on + 1),false,tscan,tdead); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // WBS linearity test, loop on individual attenuators, block block FT_WBS_linearity_indiv HIFI 3710 { string band = "1a"; // HIFI band int integ_time = 4; //Total integration time in sec. string laser_H = "Laser1" in ["Laser1","Laser2"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2"]; //WBS-V laser to be set ON string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); // //Set zero and comb off Hifi_HIFI_Single_cmd($BBID,"HWH_ZERO_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWV_ZERO_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWH_COMB_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWV_COMB_OFF"); delay(2); // //Initial configuration: overall attenuators set to max., individual attenuators to 0 //H-Polarization // {double,string}[] result = ConfigurationReader("name_configwbs",["hwh_heater","hwh_latchup_s"],band,0.0); string hwh_laser1_s = "OFF"; string hwh_laser2_s = "OFF"; if(laser_H == "Laser1") { hwh_laser1_s = "ON"; } if(laser_H == "Laser2") { hwh_laser2_s = "ON"; } int hwh_heater = iround(result[0]{0}); string hwh_latchup_s = result[1]{1}; int hwh_att_band4 = 8; int hwh_att_band3 = 8; int hwh_att_band2 = 8; int hwh_att_band1 = 8; int hwh_att_in = 0; // result = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result[0]{0}); // //V-Polarization // result = ConfigurationReader("name_configwbs",["hwv_heater","hwv_latchup_s"],band,0.0); string hwv_laser1_s = "OFF"; string hwv_laser2_s = "OFF"; if(laser_V == "Laser1") { hwv_laser1_s = "ON"; } if(laser_V == "Laser2") { hwv_laser2_s = "ON"; } int hwv_heater = iround(result[0]{0}); string hwv_latchup_s = result[1]{1}; int hwv_att_band4 = 8; int hwv_att_band3 = 8; int hwv_att_band2 = 8; int hwv_att_band1 = 8; int hwv_att_in = 0; // //Loop on overall attenuators for(int i = 0 .. 7) { // Change the value of the individual attenuators //=============================================== hwh_att_band4 = hwh_att_band4 - 1; hwh_att_band3 = hwh_att_band3 - 1; hwh_att_band2 = hwh_att_band2 - 1; hwh_att_band1 = hwh_att_band1 - 1; // Set WBS //======== //0dB attenuation on main attenuators hwh_att_in = 0; hwv_att_in = 0; Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); delay(wbs_config_delay); //Wait for configuration to be applied // hwv_att_band4 = hwv_att_band4 - 1; hwv_att_band3 = hwv_att_band3 - 1; hwv_att_band2 = hwv_att_band2 - 1; hwv_att_band1 = hwv_att_band1 - 1; Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); delay(wbs_config_delay); //Wait for configuration to be applied // HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // // //1dB attenuation on main attenuator hwh_att_in = 1; hwv_att_in = 1; Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); delay(wbs_config_delay); //Wait for configuration to be applied Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); delay(wbs_config_delay); //Wait for configuration to be applied // HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // } //Set att. to max. WBS_config_proc_max_att_w_laser_fm(band,laser_H,laser_V); // } //Systematic deflux at beginning of each band switch procedure Deflux_SingleBand_proc_aot { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978.2; // LO frequency in GHz }{ //Do deflux block only for bands 1 to 4 if(band == "1a" || band == "1b" || band == "2a" || band == "2b" || band == "3a" || band == "3b" || band == "4a" || band == "4b") { //First magnet tuning Magnet_tuning_block_aot(band,lo_freq,"HRS"); //Deflux heaters Heater_block_aot(band); //Second magnet tuning Magnet_tuning_block_aot(band,lo_freq,"HRS"); } } //////////////////////////////////// // Auxiliary function to compute the noise of an ideal instrument with // 100% observing efficiency for comparison {int,double,double,double,double,double} procedure IdealInstrument { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz int totaltime = 8; // Total integration time }{ // Get parameters which are needed double tsys = InterpolateTsys(band,lo_freq); double eta_mb = InterpolateCoupling(band,lo_freq); double[] gssb = InterpolateGssb(band,lo_freq); double phasetime = double(totaltime); double noiseratio = 0.0; // Compute total double sideband noise double dsbnoise_lores = tsys * sqrt(1.0 / (eff_resolution{1} * 1000000.0 * phasetime)); double dsbnoise_hires = tsys * sqrt(1.0 / (eff_resolution{0} * 1000000.0 * phasetime)); // Translate to the main beam scale, correct for eta_mb // (This is typically not done at ground based telescopes, // but leads often to problems there - to be discussed.) dsbnoise_lores = dsbnoise_lores / eta_mb; dsbnoise_hires = dsbnoise_hires / eta_mb; // Get single sideband noise equivalent double usbnoise_lores = dsbnoise_lores / gssb[0]; double usbnoise_hires = dsbnoise_hires / gssb[0]; double lsbnoise_lores = dsbnoise_lores / gssb[1]; double lsbnoise_hires = dsbnoise_hires / gssb[1]; // return total time with initial slew int returntime = totaltime; // Originally I had added 180s from telescope // Return noise values and the maximum ratio of drift to radiometric noise return {returntime,usbnoise_lores,usbnoise_hires,lsbnoise_lores,lsbnoise_hires,noiseratio}; } //Reduced version: IVC //HIFI-COP-7.2-FPU_FT obs HifiEng_FPU_FT_IVC_COP { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b","8"]; // HIFI band string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(FPU_FT_IVC_COP_proc_ops(band,prime_or_redundant)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution FPU_FT_IVC_COP_proc_ops(band,prime_or_redundant); } if(state[0] == 5) { HIFISetHK("normal",true); StopMode_block_ops(); } } } ///////////////////////////////////////////////////////////////// // Procedure to derive the backend settings for the peakup {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} procedure PeakupBackendSettings { string backend = "WBS" in ["WBS","HRS"]; // backend to use - resolution string polarization = "H" in ["H","V"]; // backend to use - polarization string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz int redundancy = 4; // Equivalent frequency scan redundancy }{ // First get the backend configuration bool isWbs = backend == "WBS"; bool isH = polarization == "H"; // Settings for unused spectrometers int[][] emptyWbsWindows = [[0,0],[0,0],[0,0],[0,0]]; {bool,int,double[],bool[]} unusedHrs = {false,1,[-110.0,110.0,0.0,0.0],[false,false,false,false]}; // Standard configuration of the backends if(isWbs) { // Get normal WBS windows double[] x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,lo_freq); int[][] stdWbsWindows = [[iround(x[0]),iround(x[1])],[iround(x[2]),iround(x[3])],[iround(x[4]),iround(x[5])],[iround(x[6]),iround(x[7])]]; // Assign to polarizations if(isH) { {bool,int[][]} wbs1 = {true,stdWbsWindows}; {bool,int[][]} wbs2 = {false,emptyWbsWindows}; {bool,int,double[],bool[]} hrs1 = unusedHrs; {bool,int,double[],bool[]} hrs2 = unusedHrs; } else { wbs1 = {false,emptyWbsWindows}; wbs2 = {true,stdWbsWindows}; hrs1 = unusedHrs; hrs2 = unusedHrs; } } else { // Get fixed HRS parameters {{bool,int,double[],bool[]},{bool,int,double[],bool[]}} hrsparms = GetSpectralScanHRS(redundancy,band); if(isH) { hrs1 = hrsparms{0}; hrs2 = unusedHrs; wbs1 = {false,emptyWbsWindows}; wbs2 = {false,emptyWbsWindows}; } else { hrs1 = unusedHrs; hrs2 = hrsparms{1}; wbs1 = {false,emptyWbsWindows}; wbs2 = {false,emptyWbsWindows}; } } return {hrs1,hrs2,wbs1,wbs2}; } //TM to control heater values of LOU, block block HL_heater_test_block_fm HIFI 3915 { double hifi_HL_heater = 0.0 in [0.0,6.0]; // HL_heater }{ //Start_block(); Hifi_HIFI_HL_heater($BBID,hifi_HL_heater); delay(1); } ///////////////////////////////////////////////////////////////// // Spectral scan in frequency switch without OFF calibration // // Implemented as procedure returning time and noise levels for HSPOT {int,double,double,double,double,double} obs HifiSScanProcFSwitchNoRef { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz int redundancy = 4 in [1,12]; // Frequency scan redundancy double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} effResolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz bool wbs1Used = true; // whether WBS1 is used bool wbs2Used = true; // whether WBS2 is used /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_cycles = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles per frequency and pointing int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Spectral Scan - Frequency Switch noRef",{data_time,0,0,0,0,0,0,n_freq_point,n_cycles,load_interval}); // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,redundancy,wbs1Used,wbs2Used,data_time); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; ////////////////////////////////////////////////////////////////////// // Call first part of the timing computer {{int,int,int,int,int,int,bool,int,int},{int,double,double[],int[][],bool,double[],int,bool}} pre_timing = SScanFSwitchNoRef_pre_timing(band,lo_freq,lo_freq_up,redundancy,freq_throw,effResolution,hr1,hr2,wb1,wb2,data_time,n_cycles,n_freq_point,load_interval,docommands); // frequency parameters int groupnumber = pre_timing{1}{0}; double reffreq = pre_timing{1}{1}; double[] freqgrid = pre_timing{1}{2}; int[][] grouporder = pre_timing{1}{3}; bool retuning = pre_timing{1}{4}; double[] targetlevels = pre_timing{1}{5}; int nfreq_if = pre_timing{1}{6}; bool dsb = pre_timing{1}{7}; ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,double,double,int} tpar = Fine_telescope(naifid,onPosition,band,reffreq,pre_timing{0}); // Dummy call to spacecraft command int[] telescopetimes = basic_fine_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9}); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,bool,int,int},double,double} post_timing = SScanChopNoRef_post_timing(pre_timing{0},telescopetimes); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = Fine_telescope(naifid,onPosition,band,reffreq,post_timing{1}); // Call telescope command telescopetimes = basic_fine_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9}); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following // normal pre_timing values int loadlength = post_timing{1}{2}; int n_per_on = post_timing{1}{4}; int n_load_on = post_timing{1}{5}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { SScanFSwitchNoRef_commanding(band,reffreq,freq_throw,effResolution,hr1,hr2,wb1,wb2,n_freq_point,grouporder,freqgrid,retuning,targetlevels,data_time,n_per_on,n_load_on,groupnumber,startobs,telescopetimes,loadlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double} tact = SingleChop_deadtimes("fs",band,reffreq,hr1,hr2,wb1,wb2,data_time,n_per_on); double tscan = 2.0 * (tact{1} + tact{2}); double tdead = 2.0 * tact{2}; // // Call noise computer {double,double,double,double,double} noisevalues = SScanChopNoRef_noisecomputer(band,reffreq,nfreq_if,dsb,effResolution,n_per_on * imax(n_load_on,1),true,tscan,tdead); // Evaluate performance SScanChopNoRef_performance(band,reffreq,nfreq_if,dsb,effResolution,noisevalues,timeTaken,n_per_on * imax(n_load_on,1),groupnumber * n_freq_point,true,tscan,tdead); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // LCU configuration into NOMINAL mode, procedure // Uses SFT approach with old 5 TM TC call procedure LCU_config_nominal_w_D2_proc_sft { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency double drain2_v = 1.4; //Drain2 voltage in V }{ //Clear potential failure mode Set_LO_Nominal_block_fm(); // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_confindex = "name_confindex_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v_start = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1_v = result[0]{1}; string curlim2_v = result[1]{1}; // result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); // //Send command: expect that we have already switched to NOMINAL //Contrary to QM, the channel is automatically switched ON HIFI_Configure_LCU_block_sft(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum,config_lo_delay); // } ///////////////////////////////////////////////////////////////// // Spectral scan in DBS observing modes // // Implemented as procedure returning time and noise levels for HSPOT {int,double,double,double,double,double} obs HifiEngSScanDBS { /* Setup parameters */ int naifid = 0; // Tracing object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source string freqgridfile = "config_StWv_scan_onsky"; // file of frequency grids string scan_name = "CO(7-6)" in ["CO(7-6)","CO(8-7)","CO(9-8)","CO(13-12)","N+","C+"]; // name of the relevant column in the grid file bool retunediplexer = false; // whether to change the diplexer with freq bool retunelo = false; // whether to retune LO Vd2 with freq /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_switch_on = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per frequency and pointing int n_cycles = 1 in [1,600]; // Number of half OFF-ON-ON-OFF cycles at one frequency }{ ////////////////////////////////////////////////////////////////////// // Parameters inherited from the standard AOTs but kept constant {double,double} effResolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz int load_interval = 4 * data_time * n_switch_on * n_cycles; // Get band and LO_freq freom reference configuration file string band = slookup("config_eng_scan",scan_name,"band"); double lo_freq = dlookup("config_eng_scan",scan_name,"ref_freq"); ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Engineering - Spectral Scan DBS slowChop",{data_time,0,0,n_switch_on,0,0,0,1,n_cycles,load_interval}); // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,2,true,true,data_time); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; ////////////////////////////////////////////////////////////////////// // Call first part of the timing computer {{int,int,int,int,int,int,int,int,int,bool,int,int,int},{int,double[]}} pre_timing = EngSScanDBS_pre_timing(band,lo_freq,freqgridfile,scan_name,retunediplexer,retunelo,effResolution,hr1,hr2,wb1,wb2,data_time,n_switch_on,n_cycles); // frequency parameters int freqnumber = pre_timing{1}{0}; double[] freqgrid = pre_timing{1}{1}; int n_total = freqnumber * n_cycles; ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,int,int,int,int,int,int} tpar = DBS_telescope(naifid,onPosition,band,lo_freq,"",pre_timing{0},n_total); // Dummy call to spacecraft command int[] telescopetimes = nodding_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},false); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,bool,int,int,int},double,double} post_timing = EngSScanDBS_post_timing(pre_timing{0},telescopetimes,freqnumber,n_cycles); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = DBS_telescope(naifid,onPosition,band,lo_freq,"",post_timing{1},n_total); // Call telescope command telescopetimes = nodding_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},false); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following // (The structure is more complex than needed, but allows to use normal // AOT telescope routines) int shiftlength = post_timing{1}{10}; int initlength = post_timing{1}{11}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands EngSScanDBS_commanding(band,lo_freq,effResolution,hr1,hr2,wb1,wb2,freqgrid,retunediplexer,retunelo,data_time,n_switch_on,n_cycles,n_total,shiftlength,startobs,telescopetimes); // Consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // efficiency parameters double tscan = post_timing{2}; double tdead = post_timing{3}; // // get additional dead times from instrument {double,double,double} tact = DBS_deadtimes(band,lo_freq,hr1,hr2,wb1,wb2,data_time,n_switch_on,0,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = DBS_noisecomputer(band,lo_freq,effResolution,false,true,n_cycles,tscan,tact); // Close all messages message("

"); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } ///////////////////////////////////////////////////////////////// // Procedure to simulate a spectral scan frequency change using // HSPOT parameters needed by the sequencer // procedure SScanRetuning { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double fe_lof_0 = 978.2; //LO frequency in normal modes double lo_freq1 = 978.2; //LO frequency in spectral scans }{ double lo_freq = 978.2; // LO frequency in MHz if(lo_freq == lo_freq1) { lo_freq = fe_lof_0 * 1000.0; } else { lo_freq = lo_freq1 * 1000.0; } HIFIRetuneFreq(band,lo_freq,""); } ////////////////////////////////////////////////////////////////////////// // Auxiliary procedure to compute sum of dead times across the map {int,int} procedure Raster_slewtimes { /* Map setup */ int nlines_tot = 1; // Number of rows in the map int npoints = 10; // Number of points per row int n_cycles = 1; // Number of half OFF-ON-ON-OFF pointing cycles int scansize = 1; // Number of points measured in one scan /* Telescope dead times */ int nodtime = 20; // Slew time to second nod int slewtime = 10; // Slew time to next point int slewline = 10; // Slew between lines int returntime = 2; // Idle time between two phases }{ /////////////////////// // Long computation for scansize > 1 to obtain all slew durations // create field of slews in the maps for simple counting if(scansize > 1) { // Create array containing all slews int[] inslews = []; int slewcount = -1; for(int icycl = 0 .. n_cycles - 1) { for(int iline = 0 .. nlines_tot - 1) { for(int ipoints = 0 .. npoints - 1) { slewcount = slewcount + 1; inslews[slewcount] = slewtime; } inslews[slewcount] = slewline; } inslews[slewcount] = returntime; } inslews[slewcount] = 0; // Count all slews using the array produced above int tinscandead = 0; int toutscandead = 0; // map point counter int slew1 = 0; int slew2 = 0; bool inmap1 = true; // k-2k-2k .. phase indicator bool aphase1 = false; bool aphase2 = true; while(slew1 <= slewcount || slew2 <= slewcount) { // A pointing phase if(inmap1) { slew1 = slew1 + 1; if(slew1 % scansize == 0) { aphase1 = !aphase1; if(aphase1) { tinscandead = tinscandead + nodtime; inmap1 = !inmap1; } else { toutscandead = toutscandead + inslews[slew1 - 1]; } } else { tinscandead = tinscandead + inslews[slew1 - 1]; } } else { // B pointing phase slew2 = slew2 + 1; if(slew2 % scansize == 0) { aphase2 = !aphase2; if(aphase2) { tinscandead = tinscandead + nodtime; inmap1 = !inmap1; } else { toutscandead = toutscandead + inslews[slew2 - 1]; } } else { tinscandead = tinscandead + inslews[slew2 - 1]; } } } } else { // Single point per nod int n_scans = nlines_tot * npoints / scansize; tinscandead = n_scans * n_cycles * nodtime; toutscandead = nlines_tot * (npoints - 1) * slewtime + (nlines_tot - 1) * slewline + n_scans * (n_cycles - 1) * returntime; } return {tinscandead,toutscandead}; } ////////////////////////////////////////////////////////////////////// // Compatibility procedure to provide the same API as used in // the previous versions // // Returns the actual integration time and the dead time per phase {double,double} procedure ConfigSpectroscopySlowChop_IST { /* Integration time */ int data_time = 4; // Integration time between two data readouts int n_data = 2; // Integration time counter /* Parameters determining the delays - used in calibration reader */ string chopmode = "chop" in ["chop","lchop","fs","hot-cold","tp","chopcal"]; // Chop mode determining the modulation dead time string band = "1a"; // HIFI band double lo_freq = 522000.0; // LO frequency /* Backend settings */ {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // HRS1/2 {used,resolution,subbands used}, WBS1/2 {used,channel windows} bool docommands = false; // Whether instrument command is issued }{ // Get timing parameters {int,int,int,int,int,int,int,int,int,int} timing = ConfigureSpectroscopyParams_IST(data_time,n_data,chopmode,band,lo_freq,backendreadoutparms); int n_wbs_start = timing{0}; int r_hrs = timing{1}; int n_wbs_integr = timing{2}; int n_hrs_integr = timing{3}; int del_hrs = timing{4}; int del_wbs = timing{5}; int t_acc_wbs = timing{6}; int t_acc_hrs = timing{7}; int tdead = timing{8}; int tint_act = timing{9}; // Transfer mode {int,int,int,int,int[],int[],string} backendconfigure = ConfigSpectroscopyBackends(data_time,backendreadoutparms); int wbs_rshift = backendconfigure{0}; int hrs_rshift = backendconfigure{1}; int hrsh_sel = backendconfigure{2}; int hrsv_sel = backendconfigure{3}; int[] wbsh_par = backendconfigure{4}; int[] wbsv_par = backendconfigure{5}; string packing = backendconfigure{6}; // Now call the command if(docommands) { Hifi_HIFI_config_spectroscopy($BBID,n_wbs_start,r_hrs,n_wbs_integr,n_hrs_integr,del_hrs,del_wbs,t_acc_wbs,t_acc_hrs,wbsh_par[0],wbsh_par[1],wbsh_par[2],wbsh_par[3],wbsh_par[4],wbsh_par[5],wbsh_par[6],wbsh_par[7],wbsv_par[0],wbsv_par[1],wbsv_par[2],wbsv_par[3],wbsv_par[4],wbsv_par[5],wbsv_par[6],wbsv_par[7],hrs_rshift,wbs_rshift,hrsh_sel,hrsv_sel,packing); } // Return actual integration time and dead time per readout return {double(tint_act) / 1000.0,double(tdead) / 1000.0}; } ////////////////////////////////////////////////////////////////////////// // Procedure to compute detailed timing of OTF observing mode {int,int,int,int,int,int,int,int} procedure OTFLoadChop_pre_timing { int nlines_tot = 1; // Number of rows in the map int npoints = 10; // Number of data dumps per row string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // chunk size given by the data rates and optimum speed int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 1 in [1,1800]; // Supersamplingfactor int n_switch_off = 3 in [1,3600]; // Number of data dumps for the OFF integration time int n_linesperscan = 1 in [1,32]; // Number of lines between two OFFs int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // First check validity of frequencies CheckLOFrequencies(band,lo_freq,lo_freq); // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // First perform consistency checks // Check chunk size given by the data rates CheckDataTaking(backendreadoutparms,data_time); // Is the map size an integer multiple of the scan size? CheckReasonableLineNumber(nlines_tot,true); if(nlines_tot == 1) { int n_scans = 1; } else { if(nlines_tot % n_linesperscan != 0) { SError("Map size is no integer multiple of the scan size."); } n_scans = nlines_tot / n_linesperscan; } // Compute parameters for the instrument timing int n_pp = 2 * npoints * n_switch_on; // compute load integration time int loadlength = duration(LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms)); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); loadlength = loadlength + readoutdead; // Compute parameters for the pointing command int jitterdead = GetMaxTimeJitter(band,lo_freq); int off_inttime = 2 * data_time_off * n_switch_off; // OFF integration time int off_pointing = off_inttime + jitterdead; // increase by commanding jitter // Duration of initial set up // determine exact duration only in case of full commanding if(docommands) { int initlength = duration(HIFIInitObs()); initlength = initlength + duration(TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal")); // Add time for HK readout int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); initlength = initlength + hkduration; } else { initlength = GetRoughInitLength(band,lo_freq,false); } initlength = initlength + loadlength; // First estimate of the load interval int scan_time = n_linesperscan * n_pp * data_time + off_pointing; if(scan_time > load_interval) { IError("Scan duration too long for required load period. " + "Reduce the map size or increase the step size."); } int n_loadinterval = imax(load_interval / scan_time,1); n_loadinterval = imin(n_loadinterval,32); // Make sure that load slews occur at the same position in each coverage n_loadinterval = IMultiple(n_loadinterval,n_scans); // dangling time given by readout dead time int dangling = readoutdead; // Return all the times needed in the observing mode modules return {n_pp,n_scans,off_inttime,off_pointing,loadlength,n_loadinterval,initlength,dangling}; } //Generic procedure to configure the FPU using the adequate instrument side procedure HIFI_Configure_FCU_proc_fm { int band_nb = 0; // HF_CPR_MXBAND int diplex_h_ctrl_mode = 227; // HF_CV1_DPFPP1 double volt_H_FIF_1 = 0.075; // HF_CH2_FIF1_Drain_V double curr_H_FIF_1 = 0.5; // HF_CH2_FIF1_Drain_C double volt_H_FIF_2 = 0.075; // HF_CH2_FIF2_Drain_V double curr_H_FIF_2 = 0.5; // HF_CH2_FIF2_Drain_C double volt_H_SIF_1 = 0.075; // HF_CH2_SIF1_Drain_V double curr_H_SIF_1 = 0.5; // HF_CH2_SIF1_Drain_C double volt_H_SIF_2 = 0.075; // HF_CH2_SIF2_Drain_V double curr_H_SIF_2 = 0.5; // HF_CH2_SIF2_Drain_C double volt_H_SIF_3 = 0.075; // HF_CH2_SIF3_Drain_V double curr_H_SIF_3 = 0.5; // HF_CH2_SIF3_Drain_C int diplex_v_ctrl_mode = 227; // HF_CV1_DPFPP1 double volt_V_FIF_1 = 0.075; // HF_CV2_FIF1_Drain_V double curr_V_FIF_1 = 0.5; // HF_CV2_FIF1_Drain_C double volt_V_FIF_2 = 0.075; // HF_CV2_FIF2_Drain_V double curr_V_FIF_2 = 0.5; // HF_CV2_FIF2_Drain_C double volt_V_SIF_1 = 0.075; // HF_CV2_SIF1_Drain_V double curr_V_SIF_1 = 0.5; // HF_CV2_SIF1_Drain_C double volt_V_SIF_2 = 0.075; // HF_CV2_SIF2_Drain_V double curr_V_SIF_2 = 0.5; // HF_CV2_SIF2_Drain_C double volt_V_SIF_3 = 0.075; // HF_CV2_SIF3_Drain_V double curr_V_SIF_3 = 0.5; // HF_CV2_SIF3_Drain_C string chop_sine_s = "ON" in ["OFF","ON"]; // HF_CPR_CH_SINE_S string chop_loop = "CLOSE" in ["CLOSE","OPEN"]; // HF_CPR_CH_LOOP_S int chop_G1 = 0; // HF_CPR_CHFPG1 int chop_G2 = 0; // HF_CPR_CHFPG2 int chop_Z1 = 0; // HF_CPR_CHFPZ1 int chop_Z2 = 0; // HF_CPR_CHFPZ2 int chop_P2 = 0; // HF_CPR_CHFPP2 double calibcurrent = 0.0; // HF_CPR_Cal_Heater_C double bias_H = 0.0; // HF_CH1_MXBIAS_V double magnetcurrent_H = 0.0; // HF_CH1_MX_MG_C double bias_V = 0.0; // HF_CV1_MXBIAS_V double magnetcurrent_V = 0.0; // HF_CV1_MX_MG_C double chopper = -4.0 in [-8.88,8.5]; // HF_CPR_Chopper_Rot double diplex_H = 0.0; // HF_CH1_DPACT_C double diplex_V = 0.0; // HF_CV1_DPACT_C }{ //check prime or redundant keyword {double,string}[] result_d = ConfigurationReader("name_chopper",["prime_or_redundant"],"0",0.0); if(result_d[0]{1} == "prime") { Hifi_HIFI_P_Configure_FCU($BBID,band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); } else { Hifi_HIFI_R_Configure_FCU($BBID,band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); } // } // Mode initialisation, block // Same content as "block HIFIInitObs HIFI 6000" block StartMode_block_ops HIFI 7922 { }{ mois_comment("Assign obsid number to procedure execution"); mois_spacon("In the following command, the second parameter (OBS_ID) shall be replaced by a Formal Parameter value according to the list provided by the instrument ICC."); Hifi_HIFI_Set_OBS_ID($BBID,$OBSID); } {int,double,double,double,double,double} obs HifiMappingModeFastDBSRaster { string modeName = "raster"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 10 in [4,80]; // data dump interval int n_int_on = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_switch_on = 1 in [1,1800]; // number of data transfer cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode OpenMessages("HIFI Mapping - DBS Raster Map fastChop",{data_time,0,n_switch_on,n_int_on,0,0,n_pointsperscan,0,n_cycles,load_interval}); // Call first part of the timing computer {int,int,int,int,int,int,int,int,int,int,int,int,int} pre_timing = FastDBSRaster_pre_timing(nlines,npoints,band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_switch_on,n_pointsperscan,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; // Check for NoddingInRaster or NoddingOfRaster int scansize = pre_timing{10}; if(scansize > 1) { {int,int,int,string,int,double,double,bool,double,double,double,int,int,double,double,int,int,double,double,int,int,int,int,int} tmpar = DBSMultiRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",pre_timing,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = nodding_of_raster_pointing(false,tmpar{0},tmpar{1},tmpar{2},tmpar{3},tmpar{4},tmpar{5},tmpar{6},tmpar{7},tmpar{8},tmpar{9},tmpar{10},tmpar{11},tmpar{12},tmpar{13},tmpar{14},tmpar{15},tmpar{16},tmpar{17},tmpar{18},tmpar{19},tmpar{20},tmpar{21},tmpar{22},tmpar{23}); } else { {int,int,int,string,int,double,double,bool,double,double,double,int,int,double,double,int,int,int,double,double,int,int,int,double,double,int,int,int,int} tpar = DBSRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",pre_timing,n_cycles); telescopetimes = nodding_raster_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23},tpar{24},tpar{25},tpar{26},tpar{27},tpar{28}); } ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,int},bool,double,double} post_timing = DBSRaster_post_timing(pre_timing,telescopetimes,nlines,npoints,n_switch_on,n_cycles,load_interval,true); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command if(scansize > 1) { tmpar = DBSMultiRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",post_timing{1},n_cycles); // Call telescope command telescopetimes = nodding_of_raster_pointing(true,tmpar{0},tmpar{1},tmpar{2},tmpar{3},tmpar{4},tmpar{5},tmpar{6},tmpar{7},tmpar{8},tmpar{9},tmpar{10},tmpar{11},tmpar{12},tmpar{13},tmpar{14},tmpar{15},tmpar{16},tmpar{17},tmpar{18},tmpar{19},tmpar{20},tmpar{21},tmpar{22},tmpar{23}); } else { tpar = DBSRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",post_timing{1},n_cycles); telescopetimes = nodding_raster_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23},tpar{24},tpar{25},tpar{26},tpar{27},tpar{28}); } // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{3}; int n_load = post_timing{1}{6}; int n_loadinterval = post_timing{1}{7}; int n_seq = post_timing{1}{8}; int initlength = post_timing{1}{11}; int dangling = post_timing{1}{12}; bool final_load = post_timing{2}; double tscan = post_timing{3}; double tdead = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { FastDBSRaster_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_seq,n_cycles,scansize,n_loadinterval,n_load,final_load,startobs,telescopetimes,loadlength,false); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double} tact = FastDBSRaster_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_seq,n_load,scansize,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = DBS_noisecomputer(band,lo_freq,effResolution,continuumDetection,oneGHzReference,n_cycles,tscan,tact); // Evaluate performance DBSRaster_performance(band,lo_freq,effResolution,noisevalues,timeTaken,nlines,npoints,n_cycles,n_seq * n_int_on * imax(n_load,1),tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // The procedures //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // WBS zero+comb, procedure procedure WBS_calib_fm { string band = "1a"; // HIFI band }{ //We shall always call these two blocks WBS0_fm(band); WBS_comb_fm(band); // } //TM to control heater values of LOU, procedure procedure HL_heater_proc_fm { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band. ALL does all bands and all multipliers string context = "nominal" in ["nominal","stby"]; //whether heater applies to stby or nominal context }{ double[] cresult = CalibrationReader("name_loheater",["heater_nominal","heater_stby"],band,0.0); double hifi_HL_heater = cresult[0]; if(context == "stby") { hifi_HL_heater = cresult[1]; } Hifi_HIFI_HL_heater($BBID,hifi_HL_heater); } // HRS partial configuration, block // Configures the LO and attenuators block HRS_config_att_lo_w_lo_input_block_fm HIFI 3679 { string band = "1a"; // HIFI band string[] hrs_mode = ["mr","mr"]; //HRS resolution code double[] hrs_subband = [5.0,5.0,5.0,5.0]; //Positions in IF of HRS sub-bands 1 and 2 for H/V }{ //Start_block(); // Fetch HRS configuration parameters //=================================== //H-polar string hrs_filename_h = "name_confighrs_" + hrs_mode[0]; {double,string}[] result = ConfigurationReader(hrs_filename_h,["hrh_switch","hrh_1u_att","hrh_1l_att","hrh_2u_att","hrh_2l_att","hrh_3u_att","hrh_3l_att","hrh_4u_att","hrh_4l_att","hrh_up_ol1","hrh_up_ol2","hrh_up_ol3","hrh_up_ol4","hrh_down_ol5","hrh_down_ol6","hrh_down_ol7"],band,0.0); string hrs_polarization_h = result[0]{1}; double hrsH_ATT_U1 = result[1]{0}; double hrsH_ATT_L1 = result[2]{0}; double hrsH_ATT_U2 = result[3]{0}; double hrsH_ATT_L2 = result[4]{0}; double hrsH_ATT_U3 = result[5]{0}; double hrsH_ATT_L3 = result[6]{0}; double hrsH_ATT_U4 = result[7]{0}; double hrsH_ATT_L4 = result[8]{0}; double[] hrsH_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; //V-polar string hrs_filename_v = "name_confighrs_" + hrs_mode[1]; result = ConfigurationReader(hrs_filename_v,["hrv_switch","hrv_1u_att","hrv_1l_att","hrv_2u_att","hrv_2l_att","hrv_3u_att","hrv_3l_att","hrv_4u_att","hrv_4l_att","hrv_up_ol1","hrv_up_ol2","hrv_up_ol3","hrv_up_ol4","hrv_down_ol5","hrv_down_ol6","hrv_down_ol7"],band,0.0); string hrs_polarization_v = result[0]{1}; double hrsV_ATT_U1 = result[1]{0}; double hrsV_ATT_L1 = result[2]{0}; double hrsV_ATT_U2 = result[3]{0}; double hrsV_ATT_L2 = result[4]{0}; double hrsV_ATT_U3 = result[5]{0}; double hrsV_ATT_L3 = result[6]{0}; double hrsV_ATT_U4 = result[7]{0}; double hrsV_ATT_L4 = result[8]{0}; double[] hrsV_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; // //Update subbands 1 and 2 frequencies for H and V, and shift by half LO7 if wb mode double fshift = hrsH_LO[6] / 2000.0; //We assume that USB of wb mode will be used hrsH_LO[0] = hrs_subband[0] + fshift; hrsH_LO[1] = hrs_subband[1] + fshift; hrsV_LO[0] = hrs_subband[2] + fshift; hrsV_LO[1] = hrs_subband[3] + fshift; // result = ConfigurationReader("name_delays",["hrs_config_delay"],band,0.0); int hrs_config_delay = iround(result[0]{0}); //Convert IF frequencies into A and M parameters //Truncate wb or hr keyword: string[] output_hrs_mode = GetHrsMode_proc_fm(hrs_mode); string hrs_mode_h = output_hrs_mode[0]; string hrs_mode_v = output_hrs_mode[1]; // int[] a_m_parameter = ComputeA_M_parameters([hrs_mode_h,hrs_mode_v],hrsH_LO[0],hrsH_LO[1],hrsH_LO[2],hrsH_LO[3],hrsH_LO[4],hrsH_LO[5],hrsH_LO[6],hrsV_LO[0],hrsV_LO[1],hrsV_LO[2],hrsV_LO[3],hrsV_LO[4],hrsV_LO[5],hrsV_LO[6]); //H-polar int hrsH_LO1_M = a_m_parameter[1]; int hrsH_LO1_A = a_m_parameter[0]; int hrsH_LO2_M = a_m_parameter[3]; int hrsH_LO2_A = a_m_parameter[2]; int hrsH_LO3_M = a_m_parameter[5]; int hrsH_LO3_A = a_m_parameter[4]; int hrsH_LO4_M = a_m_parameter[7]; int hrsH_LO4_A = a_m_parameter[6]; int hrsH_LO5_M = a_m_parameter[9]; int hrsH_LO5_A = a_m_parameter[8]; int hrsH_LO6_M = a_m_parameter[11]; int hrsH_LO6_A = a_m_parameter[10]; int hrsH_LO7_M = a_m_parameter[12]; Hifi_HIFI_Config_HRS_H_att_lo($BBID,hrs_polarization_h,hrsH_ATT_U1,hrsH_ATT_L1,hrsH_ATT_U2,hrsH_ATT_L2,hrsH_ATT_U3,hrsH_ATT_L3,hrsH_ATT_U4,hrsH_ATT_L4,hrsH_LO1_M,hrsH_LO1_A,hrsH_LO2_M,hrsH_LO2_A,hrsH_LO3_M,hrsH_LO3_A,hrsH_LO4_M,hrsH_LO4_A,hrsH_LO5_M,hrsH_LO5_A,hrsH_LO6_M,hrsH_LO6_A,hrsH_LO7_M); // //delay(hrs_config_delay); //V-polar int hrsV_LO1_M = a_m_parameter[14]; int hrsV_LO1_A = a_m_parameter[13]; int hrsV_LO2_M = a_m_parameter[16]; int hrsV_LO2_A = a_m_parameter[15]; int hrsV_LO3_M = a_m_parameter[18]; int hrsV_LO3_A = a_m_parameter[17]; int hrsV_LO4_M = a_m_parameter[20]; int hrsV_LO4_A = a_m_parameter[19]; int hrsV_LO5_M = a_m_parameter[22]; int hrsV_LO5_A = a_m_parameter[21]; int hrsV_LO6_M = a_m_parameter[24]; int hrsV_LO6_A = a_m_parameter[23]; int hrsV_LO7_M = a_m_parameter[25]; Hifi_HIFI_Config_HRS_V_att_lo($BBID,hrs_polarization_v,hrsV_ATT_U1,hrsV_ATT_L1,hrsV_ATT_U2,hrsV_ATT_L2,hrsV_ATT_U3,hrsV_ATT_L3,hrsV_ATT_U4,hrsV_ATT_L4,hrsV_LO1_M,hrsV_LO1_A,hrsV_LO2_M,hrsV_LO2_A,hrsV_LO3_M,hrsV_LO3_A,hrsV_LO4_M,hrsV_LO4_A,hrsV_LO5_M,hrsV_LO5_A,hrsV_LO6_M,hrsV_LO6_A,hrsV_LO7_M); // delay(hrs_config_delay); } // Put system into pumped mixing state, i.e. init FPU and LO tuning procedure Init_Mixing_proc_aot { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978.2; // LO frequency in GHz }{ // At that stage we should just have switched on the LO sync(); int startobs = time(); // FPU setting at this frequency Init_MSA_aot(band,"CLOSE",lo_freq,true,"ON"); // How long do we have to wait between LO switch-on and first tuning ? // The Init_MSA time is included in the delay double[] tunewait = CalibrationReader("tunetime",["lowarmup"],band,lo_freq * 1000.0); int rest = iceil(tunewait[0]) - (time() - startobs); delay(rest); // //LO power tuning: could use either H or V polar {double,string}[] result = ConfigurationReader("name_confpolar4lotune",[band],band,lo_freq); double x = result[0]{0}; string tuningbackend = "H"; if(iround(x) == 2) { tuningbackend = "V"; } else { tuningbackend = "H"; } // Actually perform LO tuning LO_tuning_block_aot(band,lo_freq,lo_freq,tuningbackend,true,true,false); } ///////////////////////////////////////////////////////////////// // Procedure to compute the WBS IF levels for spectral scans {bool,double[]} procedure TargetLevels { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency double[][] retunegrid = [[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0]]; // dB grid }{ // Get target limits double[] limits = CalibrationReader("attenuator_levels",["sscan_max","sscan_min"],band,lo_freq); // Parameters of the field int nfreq = length(retunegrid); int nsub = length(retunegrid[0]); // Go through subbands - find maximum double[] maxfield = []; for(int i = 0 .. nsub - 1) { maxfield[i] = retunegrid[0][i]; for(int j = 1 .. nfreq - 1) { maxfield[i] = max(retunegrid[j][i],maxfield[i]); } } // Renormalize for(int ii = 0 .. nsub - 1) { double norm = limits[0] / maxfield[ii]; for(int jr = 0 .. nfreq - 1) { retunegrid[jr][ii] = norm * retunegrid[jr][ii]; } } // search for minimum - use for target level double[] targetlevels = []; for(int jj = 0 .. nfreq - 1) { targetlevels[jj] = arraymin(retunegrid[jj]); } double absmin = arraymin(targetlevels); // Check for retuning needs bool retuning = absmin < limits[1]; if(retuning) { message("Wide spectral range requires repeated backend tunings.
"); } return {retuning,targetlevels}; } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the observing mode procedure FSwitch_commanding { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // data dump interval limited by the data rates int data_time_off = 4; // data dump interval on OFF int n_per_on = 1; // number of half nu1-nu2-nu2-nu1 cycles on ON int n_per_off = 1; // number of half nu1-nu2-nu2-nu1 cycles on OFF int n_loadinterval = 1; // number of nods before a load measurement int n_load_on = 0; // additional load measurements in ON pointing phase int n_load_off = 0; // additional load measurements in OFF pointing phase bool end_load_on = false; // Need for load after ON pointing phase bool end_load_off = false; // Need for load after OFF pointing phase bool final_load = false; // Need for final load measurement int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,20,1,21,0]; // Timing of the observation from telescope int loadlength = 50; // Load duration int shiftlength = 0; // Shift of the loop start relative to the pointing }{ ////////////////////////////////////////////////////////////////////// // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time int tnodslew = telescopetimes[2]; // slew dead time between points //////////////////////////////////////////////////////////////////////// // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // // Clustering is currently not implemented in MPS - switched off here int clustered = 0; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] onrates = dataparms{1}; dataparms = DataTaking(backendreadoutparms,data_time_off); double[] offrates = dataparms{1}; int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; bool runintostate = false; while(state[0] >= 0) { if(runintostate) { state = next_state_no_check(); } else { state = next_state(); } if(state[0] == 1) { // Initialization if(clustered != 1) { HIFIInitObs(); TuneHIFIFsw(band,lo_freq,freq_throw,hrs1,hrs2,wbs1{0},wbs2{0},"normal"); } delay(tinitslew - (time() - startobs) - loadlength + shiftlength - hkduration); // First load measurement HIFISetHK("normal",false); DoubleLoadMeasurement(band,lo_freq,freq_throw,eff_resolution{0},data_time,backendreadoutparms); if(shiftlength > 0) { runintostate = true; } else { runintostate = false; } } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 7) { // The NOD-state represents our OFF position HIFIConfigureFSwitchIntegration(data_time_off,n_per_off,band,lo_freq,backendreadoutparms); // Loop for load cycles for(int i1 = 1 .. n_load_off) { HIFIFSwitchOffIntegration(data_time_off,n_per_off,band,lo_freq,offrates); // Perform load calibration delay(readoutdead); DoubleLoadMeasurement(band,lo_freq,freq_throw,eff_resolution{0},data_time,backendreadoutparms); HIFIConfigureFSwitchIntegration(data_time_off,n_per_off,band,lo_freq,backendreadoutparms); } // Last cycle - no load HIFIFSwitchOffIntegration(data_time_off,n_per_off,band,lo_freq,offrates); // Second phase on OFF // occurs for even cycle numbers runintostate = false; if(state[2] % 2 == 0) { if(end_load_off) { delay(readoutdead); DoubleLoadMeasurement(band,lo_freq,freq_throw,eff_resolution{0},data_time,backendreadoutparms); runintostate = true; } } else { if(state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } } if(state[0] == 3) { // The POINT-state represents our source position HIFIConfigureFSwitchIntegration(data_time,n_per_on,band,lo_freq,backendreadoutparms); // ON integration // Loop for load cycles for(int i2 = 1 .. n_load_on) { HIFIFSwitchOnIntegration(data_time,n_per_on,band,lo_freq,onrates); // Perform load calibration delay(readoutdead); DoubleLoadMeasurement(band,lo_freq,freq_throw,eff_resolution{0},data_time,backendreadoutparms); HIFIConfigureFSwitchIntegration(data_time,n_per_on,band,lo_freq,backendreadoutparms); } // Last cycle - no load HIFIFSwitchOnIntegration(data_time,n_per_on,band,lo_freq,onrates); // First phase in source // occurs for odd cycle numbers runintostate = false; if(state[2] % 2 == 1) { if(end_load_on) { delay(readoutdead); DoubleLoadMeasurement(band,lo_freq,freq_throw,eff_resolution{0},data_time,backendreadoutparms); runintostate = true; } } else { if(state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } } if(state[0] == 9) { // Load nod delay(readoutdead); DoubleLoadMeasurement(band,lo_freq,freq_throw,eff_resolution{0},data_time,backendreadoutparms); runintostate = false; } if(state[0] == 5) { delay(readoutdead); if(final_load) { // Perform final load measurement // ( Does not occur if end_load is set) DoubleLoadMeasurement(band,lo_freq,freq_throw,eff_resolution{0},data_time,backendreadoutparms); } runintostate = false; HIFICloseObs(); } } } //Fast readout of diplexer currents, block block Diplexer_engineering_scan_block_fm HIFI 3696 { string mixer_polarization = "H" in ["H","V"]; //Polarization to be scanned double diplexer_C = 0.0; // Value of the diplexer current to move to int milliSecSample = 3; // interval between samples int samplesBefore = 30 in [0,50]; //Samples before movement int samplesAfter = 1000 in [0,1000]; //Samples after movement }{ Start_block(); if(mixer_polarization == "H") { Hifi_HIFI_DiplexerH_scan_fast(milliSecSample,diplexer_C,samplesBefore,samplesAfter); } else { Hifi_HIFI_DiplexerV_scan_fast(milliSecSample,diplexer_C,samplesBefore,samplesAfter); } //Compute delay for scan int nb_HK = 2; //For this TC, the last HK field is blanked out int millisecondsUsed = 1000 + 10 + milliSecSample * nb_HK * (samplesBefore + samplesAfter); delay(iceil(0.0010 * double(millisecondsUsed))); } //////////////////////////////////// // Special DBS raster - cross observing mode // {string,double,double}[] procedure HifiMappingProcDBSCrossSequencerInit { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source double stepsize = 0.0050 in [5.5556E-4,0.13333]; // Distance between subsequent points in the two raster lines int npoints = 10 in [2,100]; // Number of points per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_switch_on = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode // inherit from dbs-raster mode {string,double,double}[] retvalues = HifiMappingProcDBSRasterSequencerInit(naifid,ra,dec,{0.0,double(npoints / 2) * stepsize},2,stepsize,npoints,band,lo_freq,effResolution,continuumDetection,oneGHzReference,hrs1,hrs2,wbs1,wbs2,data_time,n_switch_on,n_pointsperscan,n_cycles,load_interval,docommands); return retvalues; } ////////////////////////////////////////////////////////////////////// // Procedure to display performance parameters of the observing mode procedure OTFDoubleChopNoRef_performance { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {double,double,double,double,double} noisevalues = {1.0,1.0,1.0,1.0,0.0}; // Noise values from noisecomputer int totaltime = 200; // Total observing time int nlines = 20; // Number of lines in the map int npoints = 20; // Number of points in the map int n_cycles = 1; // Number of map coverages bool fs = false; // whether frequency switch used double tscan = 10.0; // Total average duration of one scan double tdead = 0.05; // Average dead time in one chop cycle }{ // Get performance of ideal instrument for comparison {int,double,double,double,double,double} idealvalues = IdealInstrument(band,lo_freq,eff_resolution,totaltime); double idealnoise = idealvalues{1} * idealvalues{1}; double obsnoise = noisevalues{0} * noisevalues{0}; // rescale for map coverage idealnoise = idealnoise * double(npoints * nlines); double efficiency = idealnoise / obsnoise; // Compute the actual integration time double posinttime = double(n_cycles * nlines * npoints) * (tscan - tdead); double posofftime = 0.0; int instrumenttime = iceil(double(n_cycles * nlines * npoints) * tscan); // Check total integration time double timeefficiency = (posinttime + posofftime) / double(totaltime); // Noise contribution double relnoise = noisevalues{4} / (1.0 + noisevalues{4}); // Non-standard messages message("

"); message("The observed map consists of " + nlines + " OTF lines, each covering " + npoints + " readout points.
"); // General messages PerformanceMessages(band,lo_freq,totaltime,posinttime,posofftime,timeefficiency,efficiency,relnoise,fs); } //Procedure computing the maximum time for LO configuration // over a given SScan range relative to the time at a reference frequency // int procedure ComputeLOTimeDifference { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz double reffreq = 978200.0; // Reference frequency }{ // Translate MHz from AOT API to configuration table in GHz double lofreq_ref = reffreq / 1000.0; double lofreq_min = lo_freq / 1000.0; double lofreq_max = lo_freq_up / 1000.0; //Some sanity checks if(lofreq_min >= lofreq_max) { error("Min LO frequency for SScan is higher than max one"); } //Get safe Vd2 value for this LO subband double[] cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lofreq_ref); double drain2_safe = cresult[0]; //Get tuning delays {double,string}[] result = ConfigurationReader("name_delays",["lock_lo_delay","vd2_rampup_speed"],band,lofreq_ref); double lock_lo_delay = result[0]{0}; double vd2_rampup_speed = result[1]{0}; // Reference value double tune_range_factor = 1.05; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlcutune = "name_configlcutune_b"; } result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lofreq_ref); //Value must be clipped to blue max double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq / 1000.0); int ref_delay = iceil(lock_lo_delay + (min(result[0]{0},drain2_bluemax) * tune_range_factor - drain2_safe) / vd2_rampup_speed); //Readout content of LCU Vd2 table only once out of loop string tab = "configlcu" + band + "tune.config"; double[] allVd2 = dcolumn(tab,"drain2_v"); //Determine bracketting indices int index_min = ibracket(tab,"index",lofreq_min); int index_max = ibracket(tab,"index",lofreq_max); //Loop on all bracketted indices double max_vd2 = 0.0; for(int i = index_min .. index_max) { max_vd2 = max(allVd2[i],max_vd2); } // Maximum value int delay_max = iceil(lock_lo_delay + (max_vd2 * tune_range_factor - drain2_safe) / vd2_rampup_speed); // Return difference by which the duration has to be corrected return delay_max - ref_delay; } // active HK while instrument is not integrating block HIFIActiveHK HIFI 6002 { string speed = "normal" in ["fast","normal","slow"]; // Select HK rate int period = 10; // Time for which active HK is to be used }{ // Compute active period int aperiod = period - 4; // Get parameters {string,int,double,double,double,double} hkparms = PeriodicHKParms(speed); // ignored if time is too short if(aperiod > hkparms{1}) { // initial delay delay(2); // Correct for additional readouts double numreadout = double(aperiod / hkparms{1}); double enhance = (1.0 + numreadout) / numreadout; // Active HK string[] pattern = QueryHKPattern(true); non_ess_hk_data_rate(enhance * hkparms{3} / 1024.0); ess_hk_data_rate(enhance * hkparms{5} / 1024.0); Hifi_HIFI_Housekeeping_on(hkparms{0},pattern[0],pattern[1],pattern[2],pattern[3],pattern[4],pattern[5]); delay(aperiod); // Back to passive HK pattern = QueryHKPattern(false); non_ess_hk_data_rate(hkparms{3} / 1024.0); ess_hk_data_rate(hkparms{5} / 1024.0); Hifi_HIFI_Housekeeping_on(hkparms{0},pattern[0],pattern[1],pattern[2],pattern[3],pattern[4],pattern[5]); delay(2); } else { delay(period); } } //HIFI vector scan investigation, block //Check vector scan from safe to values close to BLUE MAX block Vecscan_Investigation_block_fm HIFI 3972 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency int pretime = 5 in [0,10]; // time between preamble and scan, if < 4, no preamble double step_time = 5.0 in [4.0,10.0]; // time between steps in scan }{ //Clear potential failure mode Set_LO_Nominal_proc_fm(); // //Start_block(); //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v_start = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); double drain2_safe = cresult[0]; drain2_v_start = drain2_safe; // double drain2_max = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // //For bands 1 to 5, scan will be done with increasing drain2 voltages // //For bands 6 to 7, scan will be done with decreasing drain2 voltages: NOT FOR THIS TEST !! if(band == "6a" || band == "7a" || band == "6b" || band == "7b") { //step_drain2_v = -1.0*step_drain2_v; //drain2_v_start = drain2_max; //Also, it probably makes no sense to go down to the safe value drain2_v_start = drain2_safe + 0.45; //i.e. go to 1.7 //Need to check that drain2_v_start has not got above the blue max //If so, the range to scan is not so big so we stick to the safe value //as minimum drain2 for the scan if(drain2_v_start >= drain2_max) { drain2_v_start = drain2_safe; } } // result = ConfigurationReader(name_configlotune,["nsteps","step_time"],band,lo_freq); int nsteps = iround(result[0]{0}); double step_drain2_v = -1.0 * (drain2_max - drain2_v_start) / double(nsteps - 1); drain2_v_start = drain2_max; // double step_time = steptime ; //result[1]{0}; // //Preamble tuning macro to highest Vd2 of the upcoming scan result = ConfigurationReader("name_delays",["lock_lo_delay","vd2_rampup_speed"],band,lo_freq); int config_lo_delay = iceil(result[0]{0} + (drain2_v_start - drain2_safe) / result[1]{0}); // // override by parameter value if(pretime >= 4) { config_lo_delay = pretime; HIFI_Configure_LCU_proc_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,macro_checksum,config_lo_delay); } // //Load vector scan //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Load_vector_safe_1a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "1b") { //Band 1b Hifi_HIFI_Load_vector_safe_1b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2a") { //Band 2a Hifi_HIFI_Load_vector_safe_2a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2b") { //Band 2b Hifi_HIFI_Load_vector_safe_2b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3a") { //Band 3a Hifi_HIFI_Load_vector_safe_3a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3b") { //Band 3b Hifi_HIFI_Load_vector_nom_3b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "4a") { //Band 4a Hifi_HIFI_Load_vector_safe_4a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "4b") { //Band 4b Hifi_HIFI_Load_vector_safe_4b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "5a") { //Band 5a Hifi_HIFI_Load_vector_nom_5a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "5b") { //Band 5b Hifi_HIFI_Load_vector_nom_5b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6a") { //Band 6a Hifi_HIFI_Load_vector_nom_6a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6b") { //Band 6b Hifi_HIFI_Load_vector_nom_6b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7a") { //Band 7a Hifi_HIFI_Load_vector_nom_7a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7b") { //Band 7b Hifi_HIFI_Load_vector_nom_7b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } // //delay(1); //Execute vector scan Hifi_HIFI_vector_scan($BBID); double time_needed = double(nsteps) * step_time; delay(iround(time_needed + 2.0 + 0.5)); //0.5s added for completion of load_vector //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } ////////////////////////////////////////////////////////////////// // HRS complete configuration with maximum attenuation, block // Both polarizations are treated block HRS_standby_block_fm HIFI 3633 { string band = "1a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code }{ //Start_block(); // Fetch HRS configuration parameters //=================================== //H-polar string hrs_filename_h = "name_confighrs_" + hrs_mode[0]; {double,string}[] result = ConfigurationReader(hrs_filename_h,["hrh_switch","hrh_1u_att","hrh_1l_att","hrh_2u_att","hrh_2l_att","hrh_3u_att","hrh_3l_att","hrh_4u_att","hrh_4l_att","hrh_up_ol1","hrh_up_ol2","hrh_up_ol3","hrh_up_ol4","hrh_down_ol5","hrh_down_ol6","hrh_down_ol7"],band,0.0); string hrs_polarization_h = result[0]{1}; double[] hrsH_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; //V-polar string hrs_filename_v = "name_confighrs_" + hrs_mode[1]; result = ConfigurationReader(hrs_filename_v,["hrv_switch","hrv_1u_att","hrv_1l_att","hrv_2u_att","hrv_2l_att","hrv_3u_att","hrv_3l_att","hrv_4u_att","hrv_4l_att","hrv_up_ol1","hrv_up_ol2","hrv_up_ol3","hrv_up_ol4","hrv_down_ol5","hrv_down_ol6","hrv_down_ol7"],band,0.0); string hrs_polarization_v = result[0]{1}; double[] hrsV_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; // result = ConfigurationReader("name_delays",["hrs_config_delay"],band,0.0); int hrs_config_delay = iround(result[0]{0}); //Convert IF frequencies into A and M parameters //Truncate wb or hr keyword: string[] output_hrs_mode = GetHrsMode_proc_fm(hrs_mode); string hrs_mode_h = output_hrs_mode[0]; string hrs_mode_v = output_hrs_mode[1]; // int[] a_m_parameter = ComputeA_M_parameters([hrs_mode_h,hrs_mode_v],hrsH_LO[0],hrsH_LO[1],hrsH_LO[2],hrsH_LO[3],hrsH_LO[4],hrsH_LO[5],hrsH_LO[6],hrsV_LO[0],hrsV_LO[1],hrsV_LO[2],hrsV_LO[3],hrsV_LO[4],hrsV_LO[5],hrsV_LO[6]); //H-polar int hrh_up_ol1_m = a_m_parameter[1]; int hrh_up_ol1_a = a_m_parameter[0]; int hrh_up_ol2_m = a_m_parameter[3]; int hrh_up_ol2_a = a_m_parameter[2]; int hrh_up_ol3_m = a_m_parameter[5]; int hrh_up_ol3_a = a_m_parameter[4]; int hrh_up_ol4_m = a_m_parameter[7]; int hrh_up_ol4_a = a_m_parameter[6]; int hrh_down_ol5_m = a_m_parameter[9]; int hrh_down_ol5_a = a_m_parameter[8]; int hrh_down_ol6_m = a_m_parameter[11]; int hrh_down_ol6_a = a_m_parameter[10]; int hrh_down_ol7_m = a_m_parameter[12]; //V-polar int hrv_up_ol1_m = a_m_parameter[14]; int hrv_up_ol1_a = a_m_parameter[13]; int hrv_up_ol2_m = a_m_parameter[16]; int hrv_up_ol2_a = a_m_parameter[15]; int hrv_up_ol3_m = a_m_parameter[18]; int hrv_up_ol3_a = a_m_parameter[17]; int hrv_up_ol4_m = a_m_parameter[20]; int hrv_up_ol4_a = a_m_parameter[19]; int hrv_down_ol5_m = a_m_parameter[22]; int hrv_down_ol5_a = a_m_parameter[21]; int hrv_down_ol6_m = a_m_parameter[24]; int hrv_down_ol6_a = a_m_parameter[23]; int hrv_down_ol7_m = a_m_parameter[25]; //Attenuators are fixed //H-polar double hrh_1u_att = 15.5; double hrh_1l_att = 15.5; double hrh_2u_att = 15.5; double hrh_2l_att = 15.5; double hrh_3u_att = 15.5; double hrh_3l_att = 15.5; double hrh_4u_att = 15.5; double hrh_4l_att = 15.5; //V-polar double hrv_1u_att = 15.5; double hrv_1l_att = 15.5; double hrv_2u_att = 15.5; double hrv_2l_att = 15.5; double hrv_3u_att = 15.5; double hrv_3l_att = 15.5; double hrv_4u_att = 15.5; double hrv_4l_att = 15.5; //Configure HRS-H Hifi_HIFI_Config_HRS_H_att_lo($BBID,hrs_polarization_h,hrh_1u_att,hrh_1l_att,hrh_2u_att,hrh_2l_att,hrh_3u_att,hrh_3l_att,hrh_4u_att,hrh_4l_att,hrh_up_ol1_m,hrh_up_ol1_a,hrh_up_ol2_m,hrh_up_ol2_a,hrh_up_ol3_m,hrh_up_ol3_a,hrh_up_ol4_m,hrh_up_ol4_a,hrh_down_ol5_m,hrh_down_ol5_a,hrh_down_ol6_m,hrh_down_ol6_a,hrh_down_ol7_m); //delay(hrs_config_delay); // //Configure HRS-V Hifi_HIFI_Config_HRS_V_att_lo($BBID,hrs_polarization_v,hrv_1u_att,hrv_1l_att,hrv_2u_att,hrv_2l_att,hrv_3u_att,hrv_3l_att,hrv_4u_att,hrv_4l_att,hrv_up_ol1_m,hrv_up_ol1_a,hrv_up_ol2_m,hrv_up_ol2_a,hrv_up_ol3_m,hrv_up_ol3_a,hrv_up_ol4_m,hrv_up_ol4_a,hrv_down_ol5_m,hrv_down_ol5_a,hrv_down_ol6_m,hrv_down_ol6_a,hrv_down_ol7_m); delay(hrs_config_delay); // //Now Configure blocks HRS_config_resol_fm(band,hrs_mode); } //HIFI-COP-2.1-DipCal2 procedure Diplexer_calibration_hotcold_COP_proc_ops { string band = "3" in ["3","4","6","7"]; // HIFI mixer band }{ // //Get the list of frequencies to be used for the scan string tab = "configdipcalib_" + band + ".config"; int total = table_size(tab); double[] freq = []; string[] subband = []; for(int j = 1 .. total) { freq[j] = dlookup(tab,"" + j,"frequency"); subband[j] = slookup(tab,"" + j,"subband"); //Check whether this combination of band+freq is allowed in the current CUS Check_Band_vs_Freq_proc_fm(subband[j],freq[j]); } string current_subband = "0"; //Start loop on diplexer scans for(int i = 1 .. total) { // //First check whether one needs to switch on another LO band if(subband[i] != current_subband) { LCU_switchon_proc_fm(subband[i]); //Wait an extra delay of 1 min for short term stabilization delay(60); current_subband = subband[i]; } Diplexer_calibration_hotcold_proc_fm(subband[i],freq[i]); } // } // Get actual frequency throw best suited for the LO band double procedure GetTrueFsThrow { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency string throwstring = "small-negative"; // Frequency throw identifier }{ // perform lookup double[] throw = CalibrationReader("fsthrows",[throwstring],band,lo_freq); return throw[0]; } // // Chopper scan without spectra, block block Chopper_scan_nospectra_fm HIFI 3261 { string band = "1a"; // HIFI band double chopper_pos_min = -7.0; //minimum chopper position double chopper_pos_max = 8.0; //maximum chopper position int n_steps = 300; //number of steps }{ Start_block(); // int steps = 0; int steps_done = 0; int steps_wanted = n_steps; if(steps_wanted < 1) { steps_wanted = 1; } double chopper_pos = 0.0; double stepsize = 0.0; if(steps_wanted > 1) { stepsize = (chopper_pos_max - chopper_pos_min) / (double(steps_wanted) - 1.0); } //Move first half way to the first scanned position to //avoid hitting the end stop double intermediate_chopper_pos = (chopper_pos_max + chopper_pos_min) / 2.0; intermediate_chopper_pos = Check_Chopper_Prime_Redundant(intermediate_chopper_pos); HIFI_CPR_Chopper_Rot_proc_fm(intermediate_chopper_pos); //Rotate chopper Hifi_HIFI_non_periodic_hk_FCU(); //To get sent voltage delay(1); // while(steps_done < steps_wanted) { steps = steps_wanted - steps_done; if(steps > n_steps) { steps = n_steps; } chopper_pos = chopper_pos_min + double(steps_done) * stepsize; if(chopper_pos > 8.5) { chopper_pos = 8.5; //Cannot go over 8.5 Volts } // chopper_pos = Check_Chopper_Prime_Redundant(chopper_pos); HIFI_CPR_Chopper_Rot_proc_fm(chopper_pos); //Rotate chopper Hifi_HIFI_non_periodic_hk_FCU(); //To get sent voltage delay(1); steps_done = steps_done + 1; } } // FPU settling time for a mixer band change, procedure procedure FPU_Settling_time_proc_fm { string band_1 = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string band_2 = "2a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band int int_time1 = 3600; //Integration time after first tuning int int_time2 = 600; //Integration time after first and second switch double lo_freq_1 = 500.0; //LO frequency in sub-band a double lo_freq_2 = 700.0; //LO frequency in sub-band b string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ // //Get cold position {double,string}[] result_d = ConfigurationReader("name_confilfpu",["chop_cold"],band_1,0.0); double chop = result_d[0]{0}; // //WBS calibration if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band_1); } //Set up mixer for lo_freq_1 Init_MSA_fm(band_1,"CLOSE",lo_freq_1,"ON"); FPU_Settling_time_first_tuning_fm(band_1,int_time1,lo_freq_1,backend); // Init_MSA_fm(band_2,"CLOSE",lo_freq_2,"ON"); FPU_Settling_time_second_tuning_fm(band_2,int_time2,lo_freq_2,backend); // Init_MSA_fm(band_1,"CLOSE",lo_freq_1,"ON"); FPU_Settling_time_third_tuning_fm(band_1,int_time2,lo_freq_1,backend); // } ///////////////////////////////////////////////////////////////// // Procedure to compute detailed timing for a // Spectral Scan Load-Chop observing mode // // We assume that each telescope motion is related to an // instrument calibration. // {{int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int},{int,double,double[],int[][],bool,double[],int,bool}} procedure SScanLoadChop_pre_timing { string band = "4a"; // HIFI band double lo_freq_low = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz int redundancy = 4; // Frequency scan redundancy {double,double} eff_resolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_chop_on = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles per frequency and pointing int n_chop_off = 1 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles on OFF int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int n_cycles = 1 in [1,600]; // Number of half OFF-ON-ON-OFF cycles at one frequency int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Create composite readout structure for backends {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Get frequency grid characteristic parameters {int,double,double[],int[][],int,bool} fqparms = MakeFreqGrid(band,lo_freq_low,lo_freq_up,redundancy,0.0,n_freq_point); double reffreq = fqparms{1}; double[] freqgrid = fqparms{2}; int[][] grouporder = fqparms{3}; // Process tuning level grid double[][] levelgrid = GetSScanLevelGrid(band,wbs1,wbs2,freqgrid,fqparms{0},grouporder); {bool,double[]} targets = TargetLevels(band,reffreq,levelgrid); bool retuning = targets{0}; double[] targetgrid = targets{1}; string reftarget = ""; if(retuning) { reftarget = "sscan_normal"; } {int,double,double[],int[][],bool,double[],int,bool} spectralparms = {fqparms{0},reffreq,freqgrid,grouporder,retuning,targetgrid,fqparms{4},fqparms{5}}; ////////////////////////////////////////////////////////////////////// // Compute load integration time int loadlength = duration(SScanLoadMeasurement(band,reffreq,reffreq,true,eff_resolution{0},data_time,backendreadoutparms)); int readoutdead = SlowChopReadoutDelay(band,reffreq,backendreadoutparms); loadlength = loadlength + readoutdead; int load_spacing = CheckedLoadSpacing(load_interval - loadlength,8); int jitterdead = GetMaxTimeJitter(band,reffreq); // Integration time per frequency and pointing int on_inttime = 2 * n_chop_on * data_time; int off_inttime = 2 * n_chop_off * data_time_off; // Duration of initial set up // Staying at the same frequency makes no sense here. // First frequency point double runningfreq = freqgrid[grouporder[1][0]]; // determine exact duration only in case of full commanding if(docommands) { int initlength = duration(HIFIInitObs()); initlength = initlength + duration(TuneHIFI(band,runningfreq,hrs1,hrs2,wbs1{0},wbs2{0},"sscan_normal")); // Add time for HK readout int hkduration = HkReadoutTime(band,reffreq,backendreadoutparms,false); initlength = initlength + hkduration; } else { initlength = GetRoughInitLength(band,runningfreq,false); } initlength = initlength + loadlength; // Tuning delays int bigtunestep = duration(HIFIRetuneFreq(band,reffreq,reftarget)); // Correct for variation within the band int tunediff = ComputeLOTimeDifference(band,lo_freq_low,lo_freq_up,reffreq); bigtunestep = bigtunestep + tunediff; // As step within a group could be faster than a large step if(n_freq_point > 1) { int smallstep = duration(HIFIChangeFreq(band,reffreq)); } else { smallstep = bigtunestep; } // For double phases I can use the added jitterdead in both phases for tune int auxtunestep = bigtunestep - jitterdead; int halftunestep = (auxtunestep + 1) / 2; // Telescope pointing int on_pointing = n_freq_point * on_inttime + (n_freq_point - 1) * smallstep + halftunestep + jitterdead; int off_pointing = off_inttime + halftunestep + jitterdead; // Check load_interval allowance int scan_time = 2 * imax(on_pointing,off_pointing); if(scan_time > load_spacing) { SError("Load interval of " + load_interval + "s is exceeded by " + n_chop_on * n_freq_point + " chop cycles."); } // Estimate of the load-cycles to issue a representative // telescope command if(n_cycles > 1) { // How often do I have to perform a load slew int n_loadinterval = imax(load_interval / scan_time,1); // fit with n_cycles n_loadinterval = imin(n_loadinterval,n_cycles); n_loadinterval = IMultiple(n_loadinterval,n_cycles); } else { n_loadinterval = 1; } // recompute load length during slews in case of short integrations // This regime must be maintained in the post_timing if(n_loadinterval <= 1) { loadlength = duration(SScanLoadMeasurement(band,reffreq,reffreq,false,eff_resolution{0},data_time,backendreadoutparms)); loadlength = loadlength + readoutdead; } // No dangling needed in this mode - we stop halftunelength before telescope int dangling = 0; bool end_load_on = false; bool end_load_off = false; // Return all the times needed for telescope call and post_timing processing return {{on_inttime,off_inttime,on_pointing,off_pointing,loadlength,auxtunestep,load_spacing,n_loadinterval,n_chop_on,n_chop_off,data_time,data_time_off,end_load_on,end_load_off,initlength,dangling},spectralparms}; } // Chopper scan without spectra, procedure // Look at effective current in function of commanded chopper position procedure Chopper_scan_nospectra_proc { string band = "1a"; // HIFI band //Setting file double chopper_pos_min = -7.0; //minimum chopper position double chopper_pos_max = 8.0; //maximum chopper position int n_steps = 300; //number of steps }{ // Chopper_scan_nospectra_fm(band,chopper_pos_min,chopper_pos_max,n_steps); // } // Broadcast OBSID block BroadcastOBSID_no_hk_request HIFI 902 { }{ //These are ILT-EGSE commands, not ruled by the 2TC/sec. //HifiIltEgse_PDU_set_OBS_ID($OBSID); //HifiIltEgse_PDU_set_BB_ID($BBID); //delay(1); //HifiIltEgse_FPU_set_OBS_ID($OBSID); //HifiIltEgse_FPU_set_BB_ID($BBID); //delay(1); //SpireIltEgse_QCC_SETOBSID($OBSID); //SpireIltEgse_QCC_SETBBID($BBID); //delay(1); Hifi_HIFI_Set_OBS_ID($BBID,$OBSID); //Hifi_HIFI_non_periodic_hk_FCU(); delay(1); } // Detector heater control block Heater_fm HIFI 3240 { string band = "1a"; }{ //Start_block(); //Get name of FPU configuration file {double,string}[] result_d = ConfigurationReader("name_confilfpu",["normal_heater_time_h","normal_heater_time_v","heater_delay_h","heater_delay_v","magnet_current_max_h","magnet_current_max_v"],band,0.0); double normal_heater_time_h = result_d[0]{0}; double normal_heater_time_v = result_d[1]{0}; int heater_delay_h = iround(result_d[2]{0}); int heater_delay_v = iround(result_d[3]{0}); //Magnets need to be switched to 0 prior to the deflux Hifi_HIFI_CH1_MX_MG_C($BBID,0.0); Hifi_HIFI_CV1_MX_MG_C($BBID,0.0); delay(1); // mois_tmcheck("In the 2 seconds following the upcoming TC, parameter HF_AH1_DHTR_C should increase in the vicinity of 17mA, then drop to its initial value."); Hifi_HIFI_HF_CH1_DHTR_C($BBID,normal_heater_time_h); delay(iceil(normal_heater_time_h / 1000.0) + 1); // //Extra delay for cooling down temperature: will be included in the V-mixer delay //delay(heater_delay_h); mois_tmcheck("In the 2 seconds following the upcoming TC, parameter HF_AV1_DHTR_C should increase in the vicinity of 17mA, then drop to its initial value."); Hifi_HIFI_HF_CV1_DHTR_C($BBID,normal_heater_time_v); delay(iceil(normal_heater_time_v / 1000.0) + 1); //Extra delay for cooling down temperature: both mixers cool down together delay(heater_delay_v); // //Set back magnet to nominal //First set magnets to max. double magnet_current_max_h = result_d[4]{0}; double magnet_current_max_v = result_d[5]{0}; Hifi_HIFI_CH1_MX_MG_C($BBID,magnet_current_max_h); Hifi_HIFI_CV1_MX_MG_C($BBID,magnet_current_max_v); delay(1); //Nominal values //Need a representative frequency: take keyfreq //At that stage, band 8 needs to be treated as band 3 to solve SPR-2316 if(band == "8") { band = "3a"; } double[] result = CalibrationReader("name_keyfreq",["keyfreq"],band,0.0); double lo_freq = result[0]; // result_d = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); double magnetcurrent_H = result_d[0]{0}; double magnetcurrent_V = result_d[1]{0}; Hifi_HIFI_CH1_MX_MG_C($BBID,magnetcurrent_H); Hifi_HIFI_CV1_MX_MG_C($BBID,magnetcurrent_V); delay(1); } ///////////////////////////////////////////////////////////////// // get reference frequency, resolution, redundancy {{bool,int,double[],bool[]},{bool,int,double[],bool[]}} procedure GetSpectralScanHRS { int redundancy = 4; // Redundancy of overall spectral scan string band = "4a"; // HIFI band }{ string calibfile = "spectralscan_hrs"; string sredun = "" + redundancy; // Use generic reader double[] hrsset = SpectralScanReader("fscanhrs",["resolution","hrs1_offset","hrs2_offset"],band,redundancy); int hrsresol = iround(hrsset[0]); double hrs1_offset = hrsset[1]; double hrs2_offset = hrsset[2]; // Fill into normal structure double[][] hrspositions = SpreadHRS(band,[hrsresol,hrsresol],[hrs1_offset,hrs2_offset]); {bool,int,double[],bool[]} hrs1 = {true,hrsresol,hrspositions[0],[true,true,true,true]}; {bool,int,double[],bool[]} hrs2 = {true,hrsresol,hrspositions[1],[true,true,true,true]}; return {hrs1,hrs2}; } //Check consistency between band and frequency inputs //Should be invoked at the beginning of every mode ! bool procedure Check_Band_vs_WarmKeyFreq_proc_fm { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency }{ bool go_ahead_warm = true; //For LOU FM warm operations, only 1 freq allowed per band //This frequency is tabulated as keyfreqwarm double[] result_d = CalibrationReader("name_keyfreq",["keyfreqwarm"],band,0.0); double lo_freq_keywarm = result_d[0]; double margin = 0.24; //margin allowed for FSW in all bands but 4 if(band == "4a" || band == "4b") { margin = 1.0; } if(lo_freq < lo_freq_keywarm - margin || lo_freq > lo_freq_keywarm + margin) { error("LO frequency not in list of allowed frequencies for warm operations in band " + band); go_ahead_warm = false; } //} return go_ahead_warm; } ////////////////////////////////////////////////////////////////////// // Procedure to display performance parameters of the observing mode procedure SScanDBS_performance { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz int nfreq = 4; // Number of frequency points per IF bool dsb = true; // Both sidebands covered {double,double} eff_resolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz {double,double,double,double,double} noisevalues = {1.0,1.0,1.0,1.0,0.0}; // Noise values from noisecomputer int totaltime = 200; // Total observing time int allsteps = 4; // Total number of frequency pointing periods int freqsteps = 4; // Total number of frequencies double avnumchop = 1.0; // Average number of chop cycles per frequency double tscan = 60.0; // Total average duration of one cycle {double,double,double} tact = {10.0,4.9,0.05}; // Field of actual dead and integration times }{ double inttimeperphase = tact{1}; // Actual integration time in one phase // Get performance of ideal instrument for comparison {int,double,double,double,double,double} idealvalues = IdealInstrument(band,lo_freq,eff_resolution,totaltime); // Use DSB noise for long spctral scans if(dsb) { double idealnoiselsb = idealvalues{1} * idealvalues{1}; double idealnoiseusb = idealvalues{3} * idealvalues{3}; double idealnoise = idealnoiselsb * idealnoiseusb / (idealnoiselsb + idealnoiseusb); } else { idealnoise = idealvalues{1} * idealvalues{1}; } double obsnoise = noisevalues{0} * noisevalues{0}; // rescale for range coverage double accumulation = double(freqsteps) / double(nfreq); idealnoise = idealnoise * accumulation; double efficiency = idealnoise / obsnoise; // Compute the actual integration time double maxsteps = max(double(freqsteps),double(allsteps)); double posinttime = maxsteps * inttimeperphase * 2.0 * avnumchop; int instrumenttime = iceil(double(allsteps) * tscan); // Check total integration time double timeefficiency = 2.0 * posinttime / double(totaltime); // Noise contribution double relnoise = noisevalues{4} / (1.0 + noisevalues{4}); // General messages PerformanceMessages(band,lo_freq,totaltime,posinttime,posinttime,timeefficiency,efficiency,relnoise,dsb); } //Slow chopped hotcold, block block Hot_cold_slowchop_fm HIFI 3224 { string band = "1a"; int integ_time = 8; //Total integration time for delay computation string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4,etc string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast }{ //Start_block(); //Rotate chopper: assume we come from M3: no rotation as this is done in the slowchop_spectro //Chopper_Rotation_proc_fm(band,"chop_M3_ang","chop_hot_ang"); //Fetch respective chopper angles {double,string}[] result = ConfigurationReader("name_confilfpu",["chop_hot","chop_cold"],band,0.0); double chop_hot = result[0]{0}; double chop_cold = result[1]{0}; // //Compute data-rate double[] rates = ILT_datarate_proc_fm(band,backend,"slowchop",integ_time); //Take spectrum // set data rates non_ess_hk_data_rate(rates[2] / 1024.0); data_rate(rates[0] / 1024.0); // HIFI_Spectr_slow_chop_proc_fm(chop_hot,chop_cold); Apply_Slow_Chop_delay(integ_time,band,backend); delay(1); // reset data rates non_ess_hk_data_rate(rates[1] / 1024.0); data_rate(0.0); } // Get frequency resolution needed to measure standing wave pattern // in chop measurements double procedure GetChopSWResolution { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency }{ double[] dead = CalibrationReader("chopswresolution",["resolution"],band,lo_freq); return dead[0]; } //Procedure checking whether commanded voltage is in the acceptable range double procedure Check_Chopper_Range { double chopper_angle = 0.0; //prime or redundant chopper voltage }{ //Check prime or redundant status {double,string}[] result_d = ConfigurationReader("name_chopper",["prime_or_redundant","prime_endstop_min","prime_endstop_max","red_endstop_min","red_endstop_max"],"0",0.0); double chop = chopper_angle; double prime_endstop_min = result_d[1]{0}; double prime_endstop_max = result_d[2]{0}; double red_endstop_min = result_d[3]{0}; double red_endstop_max = result_d[4]{0}; // //Checks the chopper angle is within the ranges if(result_d[0]{1} == "prime") { if(chop > prime_endstop_max || chop < prime_endstop_min) { error("The chopper voltage (requested is " + chop + " V) in " + result_d[0]{1} + " mode has to be between " + prime_endstop_min + " and " + prime_endstop_max + " V."); } } if(result_d[0]{1} == "redundant") { if(chop > red_endstop_max || chop < red_endstop_min) { error("The chopper voltage (requested is " + chop + " V) in " + result_d[0]{1} + " mode has to be between " + red_endstop_min + " and " + red_endstop_max + " V."); } } return chop; } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the observing mode procedure JupiterDBS_commanding { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // chunk size int n_seq = 1; // Number of continuous chop cycles int n_load = 0; // additional load measurements in one pointing phase int n_loadinterval = 10; // number of nods before a load measurement bool end_load = false; // Need for load after each pointing phase bool final_load = false; // Need for final load measurement int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,20,1,21,0]; // Timing of the observation from telescope int loadlength = 21; // Load duration int shiftlength = 10; // Shift of the loop start relative to the pointing }{ // Auxiliary variables // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time int tnodslew = telescopetimes[2]; // slew dead time between points //////////////////////////////////////////////////////////////////////// // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // // Clustering is currently not implemented in MPS - switched off here int clustered = 0; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] rates = dataparms{1}; int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; bool runintostate = false; while(state[0] >= 0) { if(runintostate) { state = next_state_no_check(); } else { state = next_state(); } if(state[0] == 1) { // Initialization if(clustered != 1) { HIFIInitObs(); TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"jupiter"); } delay(tinitslew - (time() - startobs) - loadlength + shiftlength - hkduration); // First load measurement HIFISetHK("normal",false); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); if(shiftlength > 0) { runintostate = true; } else { runintostate = false; } } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 3) { // First nodding position HIFIConfigureSlowChopIntegration(data_time,n_seq,band,lo_freq,backendreadoutparms); // Loop for load cycles for(int i1 = 1 .. n_load) { HIFISlowChopOnIntegration(data_time,n_seq,band,lo_freq,rates); // Perform load calibration delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); HIFIConfigureSlowChopIntegration(data_time,n_seq,band,lo_freq,backendreadoutparms); } // Last cycle - no load HIFISlowChopOnIntegration(data_time,n_seq,band,lo_freq,rates); // Second phase in first nod position // occurs for even cycle numbers runintostate = false; if(state[2] % 2 == 0) { if(end_load) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); runintostate = true; } } else { // A nod slew follows - active HK if not used by load measurement if(state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } } if(state[0] == 7) { // second nod position HIFIConfigureSlowChopIntegration(data_time,n_seq,band,lo_freq,backendreadoutparms); // Loop for load cycles for(int i2 = 1 .. n_load) { // Use asymmetric scheme now to minimize setup uncertainties HIFISlowChopOffIntegration(data_time,n_seq,band,lo_freq,rates); // Perform load calibration delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); HIFIConfigureSlowChopIntegration(data_time,n_seq,band,lo_freq,backendreadoutparms); } // Last cycle - no load HIFISlowChopOffIntegration(data_time,n_seq,band,lo_freq,rates); // First phase in second nod position // occurs for odd cycle numbers runintostate = false; if(state[2] % 2 == 1) { if(end_load) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); runintostate = true; } } else { // A nod slew follows - active HK if not used by load measurement if(state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } } if(state[0] == 9) { // Load nod delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); runintostate = false; } if(state[0] == 5) { delay(readoutdead); if(final_load) { // Perform final load measurement // ( Does not occur if end_load is set) LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } runintostate = false; HIFICloseObs(); } } } //TM to control heater values of LOU, block block HL_heater_block_fm HIFI 3615 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band. ALL does all bands and all multipliers string context = "nominal" in ["nominal","stby"]; //whether heater applies to stby or nominal context }{ double[] cresult = CalibrationReader("name_loheater",["heater_nominal","heater_stby"],band,0.0); double hifi_HL_heater = cresult[0]; if(context == "stby") { hifi_HL_heater = cresult[1]; } Hifi_HIFI_HL_heater($BBID,hifi_HL_heater); } //Check frequencies are not separated by more than one index procedure Check_FSW_index_proc_fm { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq_1 = 500.0; //LO frequency FSW1 double lo_freq_2 = 501.0; //LO frequency FSW2 }{ //Fetch LO parameters string name_confindex = "name_confindex_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_confindex = "name_confindex_b"; } // {double,string}[] result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq_1); int freq_nx_1 = ifloor(result[0]{0}); result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq_2); int freq_nx_2 = ifloor(result[0]{0}); // if(abs(double(freq_nx_1 - freq_nx_2)) > 1.0) { error("The frequencies are separated by more than 1 index. Please reduce the throw."); } } ////////////////////////////////////////////////////////////////////////// // special setup using the new frequency calibration - to be removed again ////////////////////////////////////////////////////////////////////////// // Procedure for zero and comb measurement // Collects all common parts for LoadMeasurement and DoubleLoadMeasurement // procedure ZeroCombMeasurement_FCal { string band = "4a"; // HIFI band (needed to estimate stabilization) double lo_freq = 978200.0; // LO frequency int used_datatime = 4; // time between subsequent data readouts in load {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // Readout parameters for HRS1,HRS2, WBS1,WBS2 }{ // Usage of WBS bool wbs1used = backendreadoutparms{2}{0}; bool wbs2used = backendreadoutparms{3}{0}; // Zero and Comb measurement is only used in WBS observations if(wbs1used || wbs2used) { // Now start the zero-comb measurement int danglingreadout = WBS_Zero_FCal(band,lo_freq); // Add possible delay needed before next zero measurement if(used_datatime < danglingreadout) { delay(danglingreadout - used_datatime); } } } //General LO configuration command block HIFI_Configure_LCU_block_fm HIFI 3617 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency int freq_nx = 0; // HL_freq_nx int lsu_main = 0; // HL_LSU_main int lsu_offset = 0; // HL_LSU_offset int d2_step = 1; // HL_D2_step double plevel_v = 0.0; double m1_v = 9.0; double m2_v = -2.0; double m3_v = 0.0; double gate1_v = -2.5; double gate2_v = -2.5; double drain1_v = 2.8; string curlim1_v = "1.4"; double drain2_v = 2.6; string curlim2_v = "1.4"; int macro_checksum = 0; // HL_macro_checksum int config_lo_delay = 6; }{ //Check that Vd2 is within the blue limits drain2_v = Check_BLUE_LIMIT_D2_proc_fm(band,lo_freq,drain2_v); // //Start_block(); // //Execute configuration //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Conf_safe_LCU_ch1a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "1b") { //Band 1b Hifi_HIFI_Conf_safe_LCU_ch1b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "2a") { //Band 2a Hifi_HIFI_Conf_safe_LCU_ch2a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "2b") { //Band 2b Hifi_HIFI_Conf_safe_LCU_ch2b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "3a") { //Band 3a Hifi_HIFI_Conf_safe_LCU_ch3a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "3b") { //Band 3b Hifi_HIFI_Conf_nom_LCU_ch3b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "4a") { //Band 4a Hifi_HIFI_Conf_safe_LCU_ch4a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "4b") { //Band 4b Hifi_HIFI_Conf_safe_LCU_ch4b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "5a") { //Band 5a Hifi_HIFI_Conf_nom_LCU_ch5a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "5b") { //Band 5b Hifi_HIFI_Conf_nom_LCU_ch5b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "6a") { //Band 6a Hifi_HIFI_Conf_nom_LCU_ch6a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "6b") { //Band 6b Hifi_HIFI_Conf_nom_LCU_ch6b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "7a") { //Band 7a Hifi_HIFI_Conf_nom_LCU_ch7a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "7b") { //Band 7b Hifi_HIFI_Conf_nom_LCU_ch7b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } // delay(config_lo_delay); // //Store settings into available register //HIFI_HL_store_tm_proc_fm(); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } {int,double,double,double,double,double} obs HifiPointModePositionSwitch { string modeName = "pos"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,5]; // data dump interval limited by the data rates int n_int_on = 3 in [2,1800]; // number of data dumps for integration per phase int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF cycles int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode OpenMessages("HIFI Single Point - Position Switch",{data_time,0,n_int_on,0,0,0,0,0,n_cycles,load_interval}); // Call first part of the timing computer {int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int} pre_timing = PositionSwitch_pre_timing(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {double,double} refPosition = {raoff,decoff}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,int,int,int,int,int,int} tpar = PositionSwitch_telescope(naifid,onPosition,refPosition,band,lo_freq,pre_timing,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = nodding_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},true); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int},double,double} post_timing = PositionSwitch_post_timing(pre_timing,telescopetimes,n_cycles); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = PositionSwitch_telescope(naifid,onPosition,refPosition,band,lo_freq,post_timing{1},n_cycles); // Call telescope command telescopetimes = nodding_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},true); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{4}; int n_loadinterval = post_timing{1}{7}; bool final_load = post_timing{1}{12}; double tscan = post_timing{2}; double tdead = post_timing{3}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { PositionSwitch_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,startobs,telescopetimes,n_loadinterval,loadlength,final_load); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument double tdead_tot = PositionSwitch_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = PositionSwitch_noisecomputer(band,lo_freq,effResolution,oneGHzReference,n_cycles,tscan,tdead_tot); // Evaluate performance PositionSwitch_performance(band,lo_freq,effResolution,noisevalues,timeTaken,n_cycles,tscan,tdead_tot); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // Stability test, procedure // Measurement of external cold only procedure Proc_stability_extcold { string band = "1a"; // HIFI band int n = 100; //Number of load pairs to be measured string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int integ_time = 4; //Total integration time in sec. to be set at end of test string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string obsmode = "fastchop" in ["fastchop","tp"]; //Whether to use tp or fastchop double chop_phase = 1.0 in [0.2,2.0]; // Chop phase length }{ // Chopper_Rotation_block_fm(band,"chop_hot_ang","chop_M3_ang"); //Look at M3 // //WBS calibration if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band); WBS_tune_proc_fm(band); } if(backend == "hrs" || backend == "both" || backend == "hrsFast") { //Configure and tune backends HRS_config_block_fm(band,hrs_mode); HRS_tune_block_fm(band); } // //Configure spectrometers integration: done later //Configure_Spectrometer_proc_fm(band,4,hrs_mode,backend); //2 sec. integration // Stability_extcold_fm(band,n,integ_time,backend,hrs_mode,obsmode,chop_phase); //Configure spectrometers integration back to default Configure_Spectrometer_proc_fm(band,4,hrs_mode,backend); } //////////////////////////////////// // Frequency switch observing mode without baseline calibration // // All properties inherited from the load-chop mode // // This whole implementation is highly speculative as we have no experience // with frequency switch measurements yet. // {int,double,double,double,double,double} obs HifiPointProcFSwitchNoRef { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rates int n_cycles = 2 in [1,3600]; // number of half nu1-nu2-nu2-nu1 cycles on ON int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Single Point - Frequency Switch noRef",{data_time,0,0,0,0,0,0,0,n_cycles,load_interval}); // Two cases: fine pointing or position switch // Call first part of the timing computer {int,int,int,int,int,int,bool,int,int} pre_timing_f = FSwitchNoRef_pre_timing(band,lo_freq,freq_throw,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_cycles,load_interval,docommands); // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,double,double,int} tpar_f = Fine_telescope(naifid,onPosition,band,lo_freq,pre_timing_f); // Dummy call to spacecraft command int[] telescopetimes = basic_fine_pointing(false,tpar_f{0},tpar_f{1},tpar_f{2},tpar_f{3},tpar_f{4},tpar_f{5},tpar_f{6},tpar_f{7},tpar_f{8},tpar_f{9}); // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,bool,int,int},double,double} post_timing_f = SingleChopNoRef_post_timing(pre_timing_f,telescopetimes); // Now the actual observation starts // Prepare telescope command tpar_f = Fine_telescope(naifid,onPosition,band,lo_freq,post_timing_f{1}); // Call telescope command telescopetimes = basic_fine_pointing(true,tpar_f{0},tpar_f{1},tpar_f{2},tpar_f{3},tpar_f{4},tpar_f{5},tpar_f{6},tpar_f{7},tpar_f{8},tpar_f{9}); // Consistency check int totaltime = post_timing_f{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following ////////////////////////////////////////////////////////////////////// // standard parameters for fine pointing int loadlength = post_timing_f{1}{2}; int n_per_on = post_timing_f{1}{4}; int n_load_on = post_timing_f{1}{5}; bool end_load_on = post_timing_f{1}{6}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands ////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { FSwitchNoRef_commanding(band,lo_freq,freq_throw,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_per_on,n_load_on,end_load_on,startobs,telescopetimes,loadlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double} tact = SingleChop_deadtimes("fs",band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_per_on); double tscan = 2.0 * (tact{1} + tact{2}); double tdead = 2.0 * tact{2}; // // Call noise computer {double,double,double,double,double} noisevalues = FSwitchNoRef_noisecomputer(band,lo_freq,effResolution,oneGHzReference,n_per_on * (n_load_on + 1),tscan,tdead); // Evaluate performance SingleChopNoRef_performance(band,lo_freq,effResolution,noisevalues,timeTaken,n_per_on * (n_load_on + 1),true,tscan,tdead); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // LCU configuration AT START-UP into NOMINAL mode, procedure // This version assumes cold FPU but warm LO without attenuators // It ensures the right frequency is picked up for a given band procedure LCU_switchon_proc_aot { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978.2; // LO frequency in GHz }{ // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlo = "name_configlo_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] result_d = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,0.0); double gate1_v = result_d[0]; double gate2_v = result_d[1]; double drain1_v = result_d[2]; double drain2_v = result_d[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1_v = result[0]{1}; string curlim2_v = result[1]{1}; // result = ConfigurationReader("name_delays",["switch_on_delay","config_lo_delay"],band,lo_freq); int switch_on_delay = iround(result[0]{0}); int config_lo_delay = iround(result[1]{0}); // result_d = CalibrationReader("name_lcu_safe_values",["d2_v"],band,0.0); drain2_v = result_d[0]; // //Recovey from potential failure mode Set_LO_Nominal_block_aot(); // //Send command: expect that we have already switched to NOMINAL //We set D2 to best guess and wait some time to stabilize chain temperature HIFI_Configure_LCU_block_aot(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum,switch_on_delay); // //TM page dump and error flag clearance now contained in the above block //Set heater to their switch-on value HL_heater_block_aot(band,"nominal"); } ////////////////////////////////////////////////////////////////////////// // Procedure to generate the telescope command for the DBS cross observing mode // // As I have to set up the nodding pattern by hand, the cross must be // defined in instrument coordinates - implies further restrictions // {int,int,int,string,int,double,double,bool,double,double,double,double[],double[],int[],double,double,int,int,int,int,int,int} procedure DBSCross_telescope { int naifid = 0; // Tracing object ID {double,double} mapcenter = {0.0,0.0}; // Coordinates of the center of the map double stepsize = 0.0050; // Distance between subsequent points in the raster line int npoints = 10; // Number of horizontal points string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz string throw = ""; // Identifier for chop throw, empty is standard {int,int,int,int,int,int,int,int,int,int,int,int,int} timing = {4,10,4,21,1,1800,0,10,1,1,1,50,0}; // full timing parameter list int n_cycles = 1; // Number of half OFF-ON-ON-OFF pointing cycles }{ // Assign values int pointing = timing{1}; int loadlength = timing{3}; int holdlength = timing{4}; int n_loadinterval = timing{7}; int n_pointsperscan = timing{10}; int initlength = timing{11}; int dangling = timing{12}; // Create variables for telescope command string ib = GetBoresight(band,lo_freq,true); // A change of ra-dec depending on naifid may be needed double ra = mapcenter{0}; double dec = mapcenter{1}; // Pattern angle and throw of the chopper direction // The nodding angle should always be parallel to the chopper double[] chopper = GetSkyChopThrow(band,lo_freq,throw); double nodlength = chopper[0]; double pattnod = chopper[1]; nodlength = max(nodlength * 3600.0,2.0); // Map in instrument coordinates here to allow addition // (nod is always in instrument coordinates by default) bool fixed = false; double patt = pattnod; // Map parameters double d1 = stepsize * 3600.0; double d2 = d1; // Create first array of relative coordinates double[] xoff = []; double[] yoff = []; double x0 = -double(npoints - 1) / 2.0 * d1; double y0 = -double(npoints - 1) / 2.0 * d2; for(int i1 = 0 .. npoints - 1) { xoff[i1] = x0 + double(i1) * d1; yoff[i1] = 0.0; } // Currently the center point is observed twice - this may change for(int i2 = 0 .. npoints - 1) { xoff[i2 + npoints] = 0.0; yoff[i2 + npoints] = y0 + double(i2) * d2; } int numscans = length(xoff) / n_pointsperscan; // Initialization int icount = 0; int ioff = 0; int bphase = 0; double[] yarr = []; double[] zarr = []; int[] tp = []; // Now turn into array of pointings to be used if(n_pointsperscan > 1) { // Nodding OF raster int knod = 0; int nnod = 1; for(int i_cycle = 0 .. n_cycles - 1) { for(int i_scan = 0 .. numscans - 1) { for(int phasecount = 0 .. 1) { bphase = (bphase + phasecount) % 2; for(int i_point = 0 .. n_pointsperscan - 1) { // Go to second nod only in B phases zarr[icount] = xoff[ioff] + double(bphase) * nodlength; yarr[icount] = yoff[ioff]; tp[icount] = pointing; icount = icount + 1; ioff = ioff + 1; } // Get points the second time in second phase ioff = ioff + (phasecount - 1) * n_pointsperscan; } } // End of map ioff = 0; } // Consistency check if(length(yarr) != 4 * npoints * n_cycles) { CError("Custom map point number does not cover requested cross."); } // Treat all load slews as holds int nload = 0; int nhold = 2 * n_loadinterval * n_pointsperscan; // no hold if period too long if(nhold > 4 * npoints * n_cycles) { nhold = 0; } } else { // Nodding IN raster knod = 1; nnod = n_cycles; for(int ipoint2 = 0 .. numscans - 1) { zarr[ipoint2] = xoff[ipoint2]; yarr[ipoint2] = yoff[ipoint2]; tp[ipoint2] = pointing; } // Treat load slew either as load or as hold depending on n_cycles if(n_loadinterval > n_cycles) { nload = 0; nhold = n_loadinterval / n_cycles; // no hold if period too long if(nhold > numscans) { nhold = 0; } } else { nload = n_loadinterval; nhold = 0; } } // Check parameter compatibility with pointing command for parameters // which are no direct input parameters if(pointing < 10) { SError("Pointing phase length too short. Increase the number of integrations."); } if(length(yarr) > 3000) { IError("Map too large for cross mode. Reduce the number of points."); } if(nodlength > 960.0) { IError("Nodding length too long. Choose a smaller chop throw."); } // repetition at multiple frequencies not yet implemented: int trep = 0; int n_repeat = 0; // return parameters in required order return {initlength,0,dangling,ib,naifid,ra,dec,fixed,patt,0.0,0.0,yarr,zarr,tp,pattnod,nodlength,nnod,knod,loadlength,nload,holdlength,nhold}; } ////////////////////////////////////////////////////////////////////////////// // routines needed for IST, but not part of observing modes ////////////////////////////////////////////////////////////////////////////// //Set HIFI to standby II - laser status handled by configwbs.config //It will switch off LO and let in into stanby. Lasers and HBB kept ON obs HifiEngSetIntoStandby_II { }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(HifiIntoStandby_II()); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // ON integration HifiIntoStandby_II(); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } // // Magnet current scan, slow, block // IF power as function of magnet current block Magnet_scan_slow_fm HIFI 3271 { string band = "1a"; // HIFI band double magnet_current_min_h = -15.0; //minimum magnet current H double magnet_current_max_h = 10.0; //maximum magnet current H double magnet_current_min_v = -15.0; //minimum magnet current V double magnet_current_max_v = 10.0; //maximum magnet current V int n_steps = 100; //number of steps int integ_time = 4; //Total integration time in sec.: at least 2sec ! double lo_freq = 522.0; //LO frequency string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast int tune_target_magnet = 40 in [10,85]; //Target WBS illumination percentage during magnet tuning double shapiro_bias = 1.8; //Shapiro Mixer bias, same used for both polarization }{ Start_block(); {double,string}[] result = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,0.0); double magnetcurrent_max_h = result[0]{0}; double magnetcurrent_max_v = result[1]{0}; //We use special biasing to evidence the minima in the magnet scan result = ConfigurationReader("name_confilmix",["bias4magn_h","bias4magn_v"],band,lo_freq); double bias_h = shapiro_bias; //result[0]{0}; double bias_v = shapiro_bias; //result[1]{0}; Mixerbias(bias_h,bias_v); // int steps = 0; int steps_done = 0; double step_duration = 0.1; int steps_wanted = n_steps; if(steps_wanted < 1) { steps_wanted = 1; } double magnet_current_h = 0.0; double stepsize_h = 0.0; double magnet_current_v = 0.0; double stepsize_v = 0.0; if(steps_wanted > 1) { stepsize_h = (magnet_current_max_h - magnet_current_min_h) / (double(steps_wanted) - 1.0); stepsize_v = (magnet_current_max_v - magnet_current_min_v) / (double(steps_wanted) - 1.0); } // //Set magnet to maximum to avoid hysteresis Set_Magnet_current_proc_fm(magnetcurrent_max_h,magnetcurrent_max_v); //For band5, wait another 5 sec here if(band == "5a" || band == "5b") { delay(5); } // //Set magnets to starting value to do backend tuning Set_Magnet_current_proc_fm(magnet_current_max_h,magnet_current_max_v); //For band5, wait another 10 sec here if(band == "5a" || band == "5b") { delay(10); } // if(backend == "both" || backend == "wbs") { Hifi_HIFI_Tune_WBS($BBID,tune_target_magnet); //Get delay result = ConfigurationReader("name_delays",["wbs_tune_delay"],band,0.0); delay(iround(result[0]{0})); // } if(backend == "both" || backend == "hrs") { Hifi_HIFI_Tune_HRS($BBID); //Get delay result = ConfigurationReader("name_delays",["hrs_tune_delay"],band,0.0); delay(iround(result[0]{0})); // } // //Start scan: from max. to min. magnet downward. while(steps_done < steps_wanted) { steps = steps_wanted - steps_done; if(steps > n_steps) { steps = n_steps; } magnet_current_h = magnet_current_max_h - double(steps_done) * stepsize_h; magnet_current_v = magnet_current_max_v - double(steps_done) * stepsize_v; Set_Magnet_current_proc_fm(magnet_current_h,magnet_current_v); // HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // steps_done = steps_done + 1; } } // WBS attenuator tuning specific for spurious tests, procedure // Both polarizations are treated procedure WBS_tune_spurious_proc_fm { string band = "1a"; // HIFI band }{ // {double,string}[] result_d = ConfigurationReader("name_configwbs",["tune_target_spurious"],band,0.0); int tune_target_spurious = iround(result_d[0]{0}); // //Now tune attenuators. WBS_tune_block_fm(band,tune_target_spurious); // } // Third part of WBS FM functional test, block // Check effect of attenuators for laser 1 block FT_WBS_att_fm HIFI 3701 { string band = "1a"; // HIFI band int integ_time = 4; //Total integration time in sec. string laser_H = "Laser1" in ["Laser1","Laser2"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2"]; //WBS-V laser to be set ON string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); // //Set zero On Hifi_HIFI_Single_cmd($BBID,"HWH_ZERO_ON"); Hifi_HIFI_Single_cmd($BBID,"HWV_ZERO_ON"); delay(1); // //Initial configuration: overall attenuator set to max, indiv. to min. //H-Polarization // {double,string}[] result = ConfigurationReader("name_configwbs",["hwh_heater","hwh_latchup_s","hwh_att_in"],band,0.0); string hwh_laser1_s = "OFF"; string hwh_laser2_s = "OFF"; if(laser_H == "Laser1") { hwh_laser1_s = "ON"; } if(laser_H == "Laser2") { hwh_laser2_s = "ON"; } int hwh_heater = iround(result[0]{0}); string hwh_latchup_s = result[1]{1}; int hwh_att_band4 = 0; int hwh_att_band3 = 0; int hwh_att_band2 = 0; int hwh_att_band1 = 0; int hwh_att_in = iround(result[2]{0}); // //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); // result = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result[0]{0}); delay(wbs_config_delay); //Wait for configuration to be applied // //V-Polarization // result = ConfigurationReader("name_configwbs",["hwv_heater","hwv_latchup_s","hwv_att_in"],band,0.0); string hwv_laser1_s = "OFF"; string hwv_laser2_s = "OFF"; if(laser_V == "Laser1") { hwv_laser1_s = "ON"; } if(laser_V == "Laser2") { hwv_laser2_s = "ON"; } int hwv_heater = iround(result[0]{0}); string hwv_latchup_s = result[1]{1}; int hwv_att_band4 = 0; int hwv_att_band3 = 0; int hwv_att_band2 = 0; int hwv_att_band1 = 0; int hwv_att_in = iround(result[2]{0}); // //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // //Wait delay to allow all setting to be configured delay(wbs_config_delay); //Wait for configuration to be applied //Perform first COMB // Hifi_HIFI_Single_cmd($BBID,"HWH_COMB_ON"); Hifi_HIFI_Single_cmd($BBID,"HWV_COMB_ON"); delay(1); // HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // // //Change attenuators: main att. -2dB while //subband attenuator +2dB: result should be unchanged int att_change = 2; hwh_att_band4 = att_change; hwh_att_band3 = att_change; hwh_att_band2 = att_change; hwh_att_band1 = att_change; hwh_att_in = hwh_att_in - att_change; hwv_att_band4 = att_change; hwv_att_band3 = att_change; hwv_att_band2 = att_change; hwv_att_band1 = att_change; hwv_att_in = hwv_att_in - att_change; // //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); delay(wbs_config_delay); //Wait for configuration to be applied // // //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // //Wait delay to allow all setting to be configured delay(wbs_config_delay); //Wait for configuration to be applied // //Perform second COMB // HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // // //Switch off zero and comb Hifi_HIFI_Single_cmd($BBID,"HWH_COMB_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWV_COMB_OFF"); delay(1); Hifi_HIFI_Single_cmd($BBID,"HWH_ZERO_OFF"); Hifi_HIFI_Single_cmd($BBID,"HWV_ZERO_OFF"); delay(1); //Set att. to max. WBS_config_proc_max_att_w_laser_fm(band,laser_H,laser_V); // } // WBS latchup configuration, block block WBS_set_Latchup_block_fm HIFI 3697 { string band = "1a"; // HIFI band string latchup_mode = "low" in ["high","low"]; //latchup level: level1 = low, level2 = high string laser_H = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-H laser to be set ON: Laser1 or Laser2 string laser_V = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-V laser to be set ON: Laser1 or Laser2 }{ //Start_block(); //H-Polarization // {double,string}[] result_d = ConfigurationReader("name_configwbs",["hwh_laser1_s","hwh_laser2_s","hwh_heater","hwh_latchup_s","hwh_att_band4_comb","hwh_att_band3_comb","hwh_att_band2_comb","hwh_att_band1_comb","hwh_att_in_comb"],band,0.0); string hwh_laser1_s = "OFF"; string hwh_laser2_s = "OFF"; if(laser_H == "Laser1") { hwh_laser1_s = "ON"; } if(laser_H == "Laser2") { hwh_laser2_s = "ON"; } int hwh_heater = iround(result_d[2]{0}); string hwh_latchup_s = "Level1"; //result_d[3]{1}; if(latchup_mode == "high") { hwh_latchup_s = "Level2"; } int hwh_att_band4 = iround(result_d[4]{0}); int hwh_att_band3 = iround(result_d[5]{0}); int hwh_att_band2 = iround(result_d[6]{0}); int hwh_att_band1 = iround(result_d[7]{0}); int hwh_att_in = iround(result_d[8]{0}); // result_d = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result_d[0]{0}); // //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); // //delay(wbs_config_delay); //Wait for configuration to be applied // //V-Polarization // result_d = ConfigurationReader("name_configwbs",["hwv_laser1_s","hwv_laser2_s","hwv_heater","hwv_latchup_s","hwv_att_band4_comb","hwv_att_band3_comb","hwv_att_band2_comb","hwv_att_band1_comb","hwv_att_in_comb"],band,0.0); string hwv_laser1_s = "OFF"; string hwv_laser2_s = "OFF"; if(laser_V == "Laser1") { hwv_laser1_s = "ON"; } if(laser_V == "Laser2") { hwv_laser2_s = "ON"; } int hwv_heater = iround(result_d[2]{0}); string hwv_latchup_s = "Level1"; //result_d[3]{1}; if(latchup_mode == "high") { hwv_latchup_s = "Level2"; } int hwv_att_band4 = iround(result_d[4]{0}); int hwv_att_band3 = iround(result_d[5]{0}); int hwv_att_band2 = iround(result_d[6]{0}); int hwv_att_band1 = iround(result_d[7]{0}); int hwv_att_in = iround(result_d[8]{0}); // //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // delay(wbs_config_delay); //Wait for configuration to be applied // } // Mirror an angular direction double procedure MirrorDirection { double angle = 0.0; // Original angle }{ double fullcircle = 360.0; return (angle + fullcircle * 0.5) % fullcircle; } //General script to read TM1, TM2,etc, block block LCU_Read_TM_pages_block_fm HIFI 3668 { }{ //Get various TM pages. This will clear error flags too Hifi_HIFI_LCU_all_tuning_hk(); delay(2); // } //Stopmode procedure StopMode_Gascell { }{ {double,string}[] result = ConfigurationReader("name_lastobsid",["last_obsid_current"],"0",0.0); //These are ILT-EGSE commands, not ruled by the 2TC/sec. //HifiIltEgse_GAS_set_BB_ID(0); //HifiIltEgse_GAS_set_OBS_ID(iround(result[0]{0})); //delay(1); } //////////////////////////////////////// // Standing wave analysis, procedure // This is like a radiometry: 4 spectra procedure Standing_wave_fm { string band = "1a"; // HIFI band int integ_time = 4; //Total integration time in sec. string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast double[] lo_freq_input = [500.0,500.15,0.02]; //Start, end and step lo_freq for the LO scan }{ //WBS calibration and backend tuning if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_config_block_fm(band); WBS_calib_fm(band); WBS_tune_stndwave_proc_fm(band); } if(backend == "hrs" || backend == "both") { HRS_config_block_fm(band,hrs_mode); HRS_tune_block_fm(band); } // //Configure spectrometers integration //1. Total power mode (i.e. stability not an issue): for bands 1-5 // int[] res = [0,0]; int total_time = 0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { res = Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); total_time = res[0] * res[1]; // //2. for bands 6-7 use freq. switch, i.e. slow chop } else { //Configure spectrometers integration after tuning for chopmode res = Configure_Spectrometer_freq_switching_proc_fm(band,integ_time * 2,hrs_mode,backend); total_time = res[0] * res[1]; } // //Loop on LO frequencies. It is assumed that the LO is tuned at the middle frequency of the scan double lo_freq_ref = (lo_freq_input[0] + lo_freq_input[1]) / 2.0; double lo_freq = lo_freq_input[0]; // while(lo_freq <= lo_freq_input[1]) { // //1. Total power mode (i.e. stability not an issue): for bands 1-5 // if ((band != "6a") && (band != "6b") && (band != "7a") && (band != "7b")) { //Set synthesizer to new LO freq. LCU_config_nominal_proc_fm(band,lo_freq); // //First internal loads Hot_cold(band,hrs_mode,backend,res[0] * res[1],"tp",0,0); //Then external loads //Hot_cold_external(band,res[0]*res[1],backend); // } else { // //2. for bands 6-7 use freq. switch, i.e. slow chop // //FSW is done between lo_freq_ref and current lo_freq // //Tune to the two frequencies // //FSW1 // LCU_config_nominal_FSW_proc_fm(band,lo_freq_ref,(lo_freq+lo_freq_ref)/2.); // //Additional command to store into LCU // Hifi_HIFI_HL_store_tm($BBID); // delay(1); // // // //FSW2 // LCU_config_nominal_FSW_proc_fm(band,lo_freq,(lo_freq+lo_freq_ref)/2.); // //Additional command to store into LCU // Hifi_HIFI_HL_store_tm($BBID); // delay(1); // // // //Start FSW integration on HBB (contains rotation to load) // Hot_spectra_FSW_fm(band,total_time,backend); // //Start FSW integration on CBB (contains rotation to load) // Cold_spectra_FSW_fm(band,total_time,backend); // } // //Increase lo_freq lo_freq = lo_freq + lo_freq_input[2]; } } ///////////////////////////////////////////////////////////////// // Derived parameters // Procedure used by the spectral scan sequencer to compute the // maximum frequency group length int procedure GetSpectralScanGroupLength { string band = "4a"; // HIFI band double lo_freq_low = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz int redundancy = 4; // Frequency scan redundancy }{ // Get frequency grid characteristic parameters {double,int,double} gfref = GetFReference(band,lo_freq_low,lo_freq_up); double reffreq = gfref{0}; int stdredun = gfref{1}; double stdstep = gfref{2}; int increment = stdredun / redundancy; // Compute group length double central_freq = 0.5 * (lo_freq_low + lo_freq_up); double nocaliblen = GetFNoCalibLength(band,central_freq); int grouplen = ifloor(nocaliblen / (stdstep * double(increment)) + 1.0); return grouplen; } ///////////////////////////////////////////////////////////////// // Spectral scan in load chop without OFF calibration // // Implemented as procedure returning time and noise levels for HSPOT {int,double,double,double,double,double} obs HifiSScanProcLoadChopNoRef { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz int redundancy = 4 in [1,12]; // Frequency scan redundancy {double,double} effResolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz bool wbs1Used = true; // whether WBS1 is used bool wbs2Used = true; // whether WBS2 is used /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_cycles = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles per frequency and pointing int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Spectral Scan - Load Chop noRef",{data_time,0,0,0,0,0,0,n_freq_point,n_cycles,load_interval}); // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,redundancy,wbs1Used,wbs2Used,data_time); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; ////////////////////////////////////////////////////////////////////// // Call first part of the timing computer {{int,int,int,int,int,int,bool,int,int},{int,double,double[],int[][],bool,double[],int,bool}} pre_timing = SScanLoadChopNoRef_pre_timing(band,lo_freq,lo_freq_up,redundancy,effResolution,hr1,hr2,wb1,wb2,data_time,n_cycles,n_freq_point,load_interval,docommands); // frequency parameters int groupnumber = pre_timing{1}{0}; double reffreq = pre_timing{1}{1}; double[] freqgrid = pre_timing{1}{2}; int[][] grouporder = pre_timing{1}{3}; bool retuning = pre_timing{1}{4}; double[] targetlevels = pre_timing{1}{5}; int nfreq_if = pre_timing{1}{6}; bool dsb = pre_timing{1}{7}; ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,double,double,int} tpar = Fine_telescope(naifid,onPosition,band,reffreq,pre_timing{0}); // Dummy call to spacecraft command int[] telescopetimes = basic_fine_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9}); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,bool,int,int},double,double} post_timing = SScanChopNoRef_post_timing(pre_timing{0},telescopetimes); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = Fine_telescope(naifid,onPosition,band,reffreq,post_timing{1}); // Call telescope command telescopetimes = basic_fine_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9}); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following // normal pre_timing values int loadlength = post_timing{1}{2}; int n_per_on = post_timing{1}{4}; int n_load_on = post_timing{1}{5}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { SScanLoadChopNoRef_commanding(band,reffreq,effResolution,hr1,hr2,wb1,wb2,n_freq_point,grouporder,freqgrid,retuning,targetlevels,data_time,n_per_on,n_load_on,groupnumber,startobs,telescopetimes,loadlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double} tact = SingleChop_deadtimes("lchop",band,reffreq,hr1,hr2,wb1,wb2,data_time,n_per_on); double tscan = 2.0 * (tact{1} + tact{2}); double tdead = 2.0 * tact{2}; // // Call noise computer {double,double,double,double,double} noisevalues = SScanChopNoRef_noisecomputer(band,reffreq,nfreq_if,dsb,effResolution,n_per_on * imax(n_load_on,1),false,tscan,tdead); // Evaluate performance SScanChopNoRef_performance(band,reffreq,nfreq_if,dsb,effResolution,noisevalues,timeTaken,n_per_on * imax(n_load_on,1),groupnumber * n_freq_point,false,tscan,tdead); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } //HIFI-COP-2.1-IF-FBk1 obs HifiEng_IF_FBk_COP { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency }{ //General parameters in use int integ_time = 604; string backend = "both"; string[] hrs_mode = ["wb1","wb1"]; //For bands 6 and 7, use wb8 if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { hrs_mode = ["wb8","wb8"]; } // // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(IF_FBk_COP_proc_ops(band,lo_freq,hrs_mode,integ_time,backend)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution IF_FBk_COP_proc_ops(band,lo_freq,hrs_mode,integ_time,backend); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } // WBS configuration with laser choice, procedure // Both polarizations are treated procedure WBS_config_w_laser_and_att_proc_fm { string band = "1a"; // HIFI band string laser_H = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-V laser to be set ON int[] att_h = [7,7,7,7,15]; //User input att. for optimum level H-polar int[] att_v = [7,7,7,7,15]; //User input att. for optimum level V-polar int integ_time = 4; //Total integration time in sec. string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //H-Polarization // {double,string}[] result_d = ConfigurationReader("name_configwbs",["hwh_laser1_s","hwh_laser2_s","hwh_heater","hwh_latchup_s","hwh_att_band4","hwh_att_band3","hwh_att_band2","hwh_att_band1","hwh_att_in"],band,0.0); string hwh_laser1_s = "OFF"; string hwh_laser2_s = "OFF"; if(laser_H == "Laser1") { hwh_laser1_s = "ON"; } if(laser_H == "Laser2") { hwh_laser2_s = "ON"; } int hwh_heater = iround(result_d[2]{0}); string hwh_latchup_s = result_d[3]{1}; int hwh_att_band4 = att_h[3]; int hwh_att_band3 = att_h[2]; int hwh_att_band2 = att_h[1]; int hwh_att_band1 = att_h[0]; int hwh_att_in = att_h[4]; // result_d = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result_d[0]{0}); // //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); // //delay(wbs_config_delay); //Wait for configuration to be applied // //V-Polarization // result_d = ConfigurationReader("name_configwbs",["hwv_laser1_s","hwv_laser2_s","hwv_heater","hwv_latchup_s","hwv_att_band4","hwv_att_band3","hwv_att_band2","hwv_att_band1","hwv_att_in"],band,0.0); string hwv_laser1_s = "OFF"; string hwv_laser2_s = "OFF"; if(laser_V == "Laser1") { hwv_laser1_s = "ON"; } if(laser_V == "Laser2") { hwv_laser2_s = "ON"; } int hwv_heater = iround(result_d[2]{0}); string hwv_latchup_s = result_d[3]{1}; int hwv_att_band4 = att_v[3]; int hwv_att_band3 = att_v[2]; int hwv_att_band2 = att_v[1]; int hwv_att_band1 = att_v[0]; int hwv_att_in = att_v[4]; // //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // delay(wbs_config_delay); //Wait for configuration to be applied // } ////////////////////////////////////// // blocks ////////////////////////////////////// //Upload of LCU safety table, block block LcuSafetyTableUpload_ops HIFI 7900 { string section = "P" in ["P","R"]; int start = 0; // first table entry to upload (count form zero) int count = 0; // maximum number of table lines to upload }{ //StartBlock_ops(); //Check prime or redundant status //{double, string}[] result_d = ConfigurationReader("name_chopper", // ["prime_or_redundant"],"0",0.0); //string section = "P"; //if (result_d[0]{1} == "redundant" ) { // section = "R"; // } // string tab = "LcuSafetyTable_" + section + ".config"; //mois_comment("Uploading LCU safety table " + tab); int total = imin(table_size(tab),start + count); int done = start; int totalline = total - done; mois_comment("The following set of " + iceil(double(totalline) / 25.0) + " TCs will use the Formal Parameter mechanism."); //mois_comment("A total of " + totalline + " lines will be uploaded in " + iceil(double(totalline)/25.) + " calls to the Hifi_HIFI_Configure_LCU_table TC"); int[] allIndices = icolumn(tab,"tableindex"); int[] allValues = icolumn(tab,"value"); int[] index = []; int[] value = []; int next = 0; //while(done < total ) { while(done < total) { for(int i = 0 .. 24) { next = imin(done,total - 1); index[i] = allIndices[next]; value[i] = allValues[next]; done = done + 1; } Hifi_HIFI_Configure_LCU_table($BBID,index[0],value[0],index[1],value[1],index[2],value[2],index[3],value[3],index[4],value[4],index[5],value[5],index[6],value[6],index[7],value[7],index[8],value[8],index[9],value[9],index[10],value[10],index[11],value[11],index[12],value[12],index[13],value[13],index[14],value[14],index[15],value[15],index[16],value[16],index[17],value[17],index[18],value[18],index[19],value[19],index[20],value[20],index[21],value[21],index[22],value[22],index[23],value[23],index[24],value[24]); delay(1); } } // LCU6Lb configuration into SAFE mode, procedure procedure LCU6Lb_config_safe_proc_fm { string band = "6b"; // HIFI band double lo_freq = 1600.0 in [1575.0,1700.0]; //LO frequency }{ error("This module is obsolete: use LCU_config_nominal_proc_fm instead"); } //General script to read TM1, TM2,etc, procedure procedure LCU_Read_TM_pages_proc_fm { }{ //Get various TM pages. This will clear error flags too Hifi_HIFI_LCU_all_tuning_hk(); delay(2); } ////////////////////////////////////////////////////////////////////// // Procedure to perform the noise level evaluation for the observing mode {double,double,double,double,double} procedure PositionSwitch_noisecomputer { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF int n_cycles = 1; // Number of map coverages double tscan = 60.0; // Total average duration of one scan double tdead = 10.0; // Average dead time in one slew }{ double inttime = (tscan - tdead) / 2.0; // Integration time per pointing phase // Get parameters which are needed double tsys = InterpolateTsys(band,lo_freq); double eta_mb = InterpolateCoupling(band,lo_freq); double[] gssb = InterpolateGssb(band,lo_freq); // Get the drift parameters to compute the drift noise double[] allanparms = InterpolateSpecAllan(band,lo_freq,oneGHzReference); // rescale to frequency resolution double alpha = allanparms[1]; double binningexp = 1.0 / allanparms[2]; double allan_time_lores = allanparms[0] * pow(1.0 / eff_resolution{1},binningexp); double allan_time_hires = allanparms[0] * pow(1.0 / eff_resolution{0},binningexp); // Get actual noise // This is returned twice: for both limiting resolutions double systemnoise_lores = TwoPhaseNoise(inttime / allan_time_lores,[tdead / allan_time_lores,alpha]); double systemnoise_hires = TwoPhaseNoise(inttime / allan_time_hires,[tdead / allan_time_hires,alpha]); double noiseratio = TwoPhaseNoiseRatio(inttime / allan_time_lores,[tdead / allan_time_lores,alpha]); // Compute total double sideband noise double dsbnoise_lores = tsys * sqrt(systemnoise_lores / (eff_resolution{1} * 1000000.0 * double(n_cycles) * tscan)); double dsbnoise_hires = tsys * sqrt(systemnoise_hires / (eff_resolution{0} * 1000000.0 * double(n_cycles) * tscan)); // Translate to the main beam scale, correct for eta_mb // (This is typically not done at ground based telescopes, // but leads often to problems there - to be discussed.) dsbnoise_lores = dsbnoise_lores / eta_mb; dsbnoise_hires = dsbnoise_hires / eta_mb; // Get single sideband noise equivalent double usbnoise_lores = dsbnoise_lores / gssb[0]; double usbnoise_hires = dsbnoise_hires / gssb[0]; double lsbnoise_lores = dsbnoise_lores / gssb[1]; double lsbnoise_hires = dsbnoise_hires / gssb[1]; // Return noise values and the maximum ratio of drift to radiometric noise return {usbnoise_lores,usbnoise_hires,lsbnoise_lores,lsbnoise_hires,noiseratio}; } // LCU3a configuration and tuning, procedure procedure LCU3a_config_tune_proc_fm { string band = "3a"; // HIFI band double lo_freq = 810.0 in [807.0,848.0]; //LO frequency double drain_2_factor = 100.0; //Percentage factor of the targetted drain voltage }{ error("This module is obsolete: use LO_tuning_block_fm instead"); } //HIFI-FCP-HC1: chopper health check#3 obs HifiEng_Chopper_FT3_COP { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Chopper_FT3_COP_proc_ops(prime_or_redundant)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Chopper_FT3_COP_proc_ops(prime_or_redundant); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //The blocks //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! /////////////////////////////////////////////////// //This block is obsolete. It remains here as //a placeholder for the BBID use. // Single integration with no change of setups,block //block Total_power_integration_block_fm HIFI 3630 { // }{ // } // Take total power spectra, block block Spectro_total_power_block_fm HIFI 3606 { string band = "1a"; // HIFI band int[] timing_parms = [4,1]; //single readout time in sec. and n_wbs_start string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); int integ_time = timing_parms[0] * timing_parms[1]; //Compute data-rate double[] rates = ILT_datarate_proc_fm(band,backend,"tp",integ_time); //Take spectrum // set data rates non_ess_hk_data_rate(rates[2] / 1024.0); data_rate(rates[0] / 1024.0); // HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // // reset data rates non_ess_hk_data_rate(rates[1] / 1024.0); data_rate(0.0); } // OBS SFT, block block OBS_SFT_block_ops HIFI 7926 { }{ StartBlock_ops(); //Check PM memory: this is for OBS5.4.0 int check_start = 0x5500; int check_end = 0x17d0b; int check_crc = 0x31a0; mois_step("Check PM memory"); Hifi_HIFI_check_PM_memory(check_start,check_end,check_crc); delay(3); mois_tmcheck("No error packet should have been generated"); // //Set Housekeeping rate to 1/sec mois_step("Set HK rate to 1/sec"); string hk_rate = "1_pkt_per_s"; Hifi_HIFI_Housekeeping_on("1_pkt_per_s","ON","ON","ON","ON","ON","ON"); delay(1); mois_tmcheck("Verify that HIFI telemetry packets (3,25,1025) - HIFI_PERIODIC_HK - are arriving every 1 second."); // mois_step("Run HIFI_enable_time_verify"); Hifi_HIFI_enable_time_verify(); delay(1); //Simulate science: are the spectrometers automatically configured ? mois_step("Simulate spectroscopy measurement"); Hifi_HIFI_simulate_science(); delay(30); mois_tmcheck("Verify that HIFI telemetry packets (21,1) are coming in."); //Should abort the above mois_step("Abort spectroscopy measurement started previously"); Hifi_HIFI_abort_spectroscopy(); delay(1); mois_tmcheck("Verify that HIFI telemetry packets (21,1) are not arriving anymore"); } // upload of memory patch table, block //Prime/Redundant is handled with the CUS table block LcuMemoryPatchUpload_ops HIFI 7902 { string section = "P" in ["P","R"]; }{ StartBlock_ops(); // //{int, int[]}[] runs = LcuGetMemoryRuns_ops( section); {int,int[]}[] runs = LcuGetMemoryRuns(section,1); int runcount = length(runs); if(runcount > 50) { error("LCU memory patch has more than 50 lines. This will not fit in the procedure."); } if(runcount != 0) { mois_comment("Upload of EFFECTIVE patch will be complete in " + runcount + " Hifi_HIFI_load_LCU TC call(s)"); } else { mois_comment("No patch uploaded because memory patch file is empty"); } for(int i = 0 .. runcount - 1) { {int}[] par = []; int[] values = runs[i]{1}; int count = length(values); for(int j = 0 .. count - 1) { par[j] = {values[j]}; } int crc = checksum("short",values); Hifi_HIFI_load_LCU(runs[i]{0},count,par,crc); delay(2); } //Complement the number of TCs sent to reach the fixed TC pattern needed for TPF if(runcount != 0) { int nb_TC_needed = 50; //Foresee as much as possible int remaining_TC = nb_TC_needed - runcount; mois_comment("The following " + remaining_TC + " TCs are dummy repetition of the first patch line"); //Compute parameters for constant inputs values = runs[0]{1}; count = length(values); for(int jj = 0 .. count - 1) { par[jj] = {values[jj]}; } crc = checksum("short",values); for(int ii = 1 .. remaining_TC) { Hifi_HIFI_load_LCU(runs[0]{0},count,par,crc); delay(2); } } else { //empty patch } // } //HIFI vector scan, block for experts: allow all vector scan parameters as user input //Check vector scan with some default parameters block Vector_scan_EXPERT_w_M1_block_fm HIFI 3771 { string band = "7b" in ["7b","7b"]; // HIFI band double lo_freq = 1890.0; //LO frequency double step_drain2_v = 0.05; //D2_V steps during vector scan int nsteps = 10; //Number of steps. Should not be larger than 10 double step_time = 1.0; //In seconds. double drain2_v_start = 1.5; //Starting D2_V in vector scan double m1 = -7.0; //M1 multiplier voltage }{ //Clear potential failure mode Set_LO_Nominal_proc_fm(); // //Start_block(); //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = m1; //result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; //double drain2_v_start = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlcu,["drain2_v"],band,lo_freq); double drain2_safe = result[0]{0}; // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // result = ConfigurationReader(name_configlotune,["step_drain2_v","nsteps","step_time"],band,lo_freq); //double step_drain2_v = result[0]{0}; //int nsteps = iround(result[1]{0}); //double step_time = result[2]{0}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // //Load vector scan //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Load_vector_safe_1a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "1b") { //Band 1b Hifi_HIFI_Load_vector_safe_1b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2a") { //Band 2a Hifi_HIFI_Load_vector_safe_2a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2b") { //Band 2b Hifi_HIFI_Load_vector_safe_2b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3a") { //Band 3a Hifi_HIFI_Load_vector_safe_3a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3b") { //Band 3b Hifi_HIFI_Load_vector_nom_3b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "4a") { //Band 4a Hifi_HIFI_Load_vector_safe_4a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "4b") { //Band 4b Hifi_HIFI_Load_vector_safe_4b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "5a") { //Band 5a Hifi_HIFI_Load_vector_nom_5a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "5b") { //Band 5b Hifi_HIFI_Load_vector_nom_5b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6a") { //Band 6a Hifi_HIFI_Load_vector_nom_6a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6b") { //Band 6b Hifi_HIFI_Load_vector_nom_6b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7a") { //Band 7a Hifi_HIFI_Load_vector_nom_7a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7b") { //Band 7b Hifi_HIFI_Load_vector_nom_7b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } // //delay(1); //Execute vector scan Hifi_HIFI_vector_scan($BBID); double time_needed = double(nsteps) * step_time; delay(iround(time_needed + 2.0 + 0.5)); //0.5s added for completion of load_vector //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } // procedure called to get the instrument into standby // with WBS lasers Off and HBB ON procedure HifiIntoStandby_I { }{ //FPU stand-by with HBB On Init_MSA_aot("0","CLOSE",0.0,true,"ON"); //WBS stand-by with laser OFF WBS_standby_block_aot("OFF"); //HRS should already have max att. and locked LO //done during the power-on., or via StandbyII } //LO enable in manual commanding mode HifiManCmd_LO_enable { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! }{ mois_comment("Procedure to enable the LOU S/S"); StartMode_block_ops(); // mois_step("Enable LOU"); LCU_enable_all_bands_block_fm(); // StopMode_block_ops(); // -> to issue last obsd/bbid } // HIFI goto SAFE, block // block HIFI_goto_SAFE_block_fm HIFI 3920 { }{ Start_block(); Hifi_HIFI_goto_safe(); {double,string}[] result = ConfigurationReader("name_delays",["stdby_delay","wbs_config_delay","hrs_config_delay","config_fpu_delay"],"0",0.0); delay(iround(result[0]{0} + result[1]{0} + result[2]{0} + result[3]{0})); } // LCU configuration with no retune, block // Uses best guess D2 voltage from configlcu table block LCU_config_nominal_noretune_block_fm HIFI 3614 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency double lo_freq_ref = 500.0; //LO frequency }{ //Fetch LO parameters string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlcutune = "name_configlcutune_b"; } //Get index of frequency used to get D2_v {double,string}[] result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq_ref); int freq_nx_ref = ifloor(result[0]{0}); // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Check frequency indices don't differ by more than 1 if(abs(double(freq_nx) - double(freq_nx_ref)) > 1.0) { error("The command HIFI_Conf_f_LCU_noretune is used with frequencies whose indices differ by more than 1 (" + lo_freq + " GHz and " + lo_freq_ref + " GHz)."); } //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; // //Use accurate AOT delay for LO tuning double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq_ref); double tune_range = 0.1; result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lo_freq_ref); double v_d2 = result[0]{0}; double drain2_max = min(v_d2 * (1.0 + tune_range / 2.0),drain2_bluemax); double[] cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq_ref); double drain2_safe = cresult[0]; result = ConfigurationReader("name_delays",["lock_lo_delay","vd2_rampup_speed"],band,lo_freq); //Added 5s: SPR-2598 int config_lo_delay = iceil(result[0]{0} + (drain2_max - drain2_safe) / result[1]{0}) + 15; //Send command Hifi_HIFI_Conf_f_LCU_noretune($BBID,freq_nx,lsu_main,lsu_offset); // delay(config_lo_delay); message(config_lo_delay); } // LCU1a configuration into SAFE mode, procedure procedure LCU1a_config_safe_proc_fm { string band = "1a"; // HIFI band double lo_freq = 500.0 in [488.0,552.0]; //LO frequency }{ error("This module is obsolete: use LCU_config_nominal_proc_fm instead"); } ////////////////////////////////////////////////////////////////////////// // Procedure to generate the telescope command for the DBS raster observing mode {int,int,int,string,int,double,double,bool,double,double,double,int,int,double,double,int,int,int,double,double,int,int,int,double,double,int,int,int,int} procedure DBSRaster_telescope { int naifid = 0; // Tracing object ID {double,double} mapcenter = {0.0,0.0}; // Coordinates of the center of the map {double,double} linedistance = {0.0050,0.0050}; // Distance between subsequent rows double stepsize = 0.0050; // Distance between subsequent points in the raster line int nlines_tot = 1; // Number of rows in the map; int npoints = 10; // Number of points per row string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz string throw = ""; // Identifier for chop throw, empty is standard {int,int,int,int,int,int,int,int,int,int,int,int,int} timing = {4,10,4,21,1,1800,0,10,1,1,1,50,0}; // full timing parameter list int n_cycles = 1; // Number of half OFF-ON-ON-OFF pointing cycles }{ // Assign values int pointing = timing{1}; int loadlength = timing{3}; int holdlength = timing{4}; int n_loadinterval = timing{7}; int initlength = timing{11}; int dangling = timing{12}; // Create variables for telescope command string ib = GetBoresight(band,lo_freq,true); // A change of ra-dec depending on naifid may be needed double ra = mapcenter{0}; double dec = mapcenter{1}; double patt = AngleFromVector(linedistance); patt = RotateRight(patt); // Pattern angle and throw of the chopper direction // The nodding angle should always be parallel to the chopper double[] chopper = GetSkyChopThrow(band,lo_freq,throw); double nodlength = chopper[0]; double pattnod = chopper[1]; nodlength = max(nodlength * 3600.0,2.0); // Map always in sky coordinates, // (nod is always in instrument coordinates by default) bool fixed = true; // Map parameters double rowstep = 0.5 / 3600.0; double d1 = double(iceil(stepsize / rowstep)) * rowstep * 3600.0; double linestep = 0.5 / 3600.0; double d2 = AngleVectorLength(linedistance); d2 = double(iceil(d2 / linestep)) * linestep * 3600.0; // Exception for the "impossible" case of spacings below 2arcsec d1 = max(d1,2.0); d2 = max(d2,2.0); // Treat load slew either as load or as hold depending on n_cycles if(n_loadinterval > n_cycles) { int nload = 0; int nhold = n_loadinterval / n_cycles; // no hold if period too long if(nhold > npoints * nlines_tot) { nhold = 0; } } else { nload = n_loadinterval; nhold = 0; } // Check parameter compatibility with pointing command for parameters // which are no direct input parameters if(pointing < 10) { SError("Pointing phase length too short. Increase the number of integrations."); } if(nodlength > 960.0) { IError("Nodding length too long. Choose a smaller chop throw."); } if(d1 > 480.0) { IError("Raster point spacing too coarse. Increase the sampling."); } if(d2 > 480.0) { IError("Raster line spacing too coarse. Increase the sampling."); } // repetition at multiple frequencies not yet implemented: int trep = 0; int n_repeat = 1; // parameters for OFF position - not used int koff = 0; int toff = 0; double raoff = 0.0; double decoff = 0.0; // return parameters in required order return {initlength,0,dangling,ib,naifid,ra,dec,fixed,patt,0.0,0.0,npoints,nlines_tot,d1,d2,pointing,holdlength,nhold,pattnod,nodlength,n_cycles,koff,toff,raoff,decoff,n_repeat,trep,loadlength,nload}; } // WBS attenuator tuning specific for spurious tests, procedure // Both polarizations are treated procedure WBS_tune_stndwave_proc_fm { string band = "1a"; // HIFI band }{ // {double,string}[] result_d = ConfigurationReader("name_configwbs",["tune_target_spurious"],band,0.0); int tune_target_spurious = iround(result_d[0]{0}); // //Now tune attenuators. WBS_tune_block_fm(band,tune_target_spurious); // } ///////////////////////////////////////////////////////// // WBS configuration with maximum attenuation, block // Laser can be chosen block WBS_config_max_att_w_laser_block_fm HIFI 3641 { string band = "1a"; // HIFI band string laser_H = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-V laser to be set ON }{ //Start_block(); //H-Polarization // {double,string}[] result_d = ConfigurationReader("name_configwbs",["hwh_laser1_s","hwh_laser2_s","hwh_heater","hwh_latchup_s"],band,0.0); string hwh_laser1_s = "OFF"; string hwh_laser2_s = "OFF"; if(laser_H == "Laser1") { hwh_laser1_s = "ON"; } if(laser_H == "Laser2") { hwh_laser2_s = "ON"; } int hwh_heater = iround(result_d[2]{0}); string hwh_latchup_s = result_d[3]{1}; int hwh_att_band4 = 7; int hwh_att_band3 = 7; int hwh_att_band2 = 7; int hwh_att_band1 = 7; int hwh_att_in = 15; // result_d = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result_d[0]{0}); //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); //delay(wbs_config_delay); //V-Polarization //Get configuration parameters // result_d = ConfigurationReader("name_configwbs",["hwv_laser1_s","hwv_laser2_s","hwv_heater","hwv_latchup_s"],band,0.0); string hwv_laser1_s = "OFF"; string hwv_laser2_s = "OFF"; if(laser_V == "Laser1") { hwv_laser1_s = "ON"; } if(laser_V == "Laser2") { hwv_laser2_s = "ON"; } int hwv_heater = iround(result_d[2]{0}); string hwv_latchup_s = result_d[3]{1}; int hwv_att_band4 = 7; int hwv_att_band3 = 7; int hwv_att_band2 = 7; int hwv_att_band1 = 7; int hwv_att_in = 15; //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // //Wait delay to allow all setting to be configured delay(wbs_config_delay); } //////////////////////////////////// // OTF observing mode // // Return time and noise levels {string,double,double}[] procedure HifiMappingProcOTFSequencerInit { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source double raoff = 0.0; // RA coordinate of the OFF position double decoff = 0.0; // DEC coordinate of the OFF position {double,double} lineDistance = {0.0050,0.0050}; // Distance between subsequent rows int nlines = 1 in [1,240]; // Number of rows in the map double stepsize = 0.0050 in [0.0,0.13333]; // Distance between subsequent points in the OTF line int npoints = 10 in [1,720]; // Number of data dumps per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,5]; // chunk size given by the data rates and optimum speed int n_int_on = 1 in [1,1800]; // Supersamplingfactor int n_linesperscan = 1 in [1,32]; // Number of lines between two OFFs int n_switch_off = 3 in [1,3600]; // Number of data dumps for the OFF integration time int n_cycles = 1 in [1,1200]; // Number of map coverages int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // limits from noise section // Get the drift parameters to compute the drift noise // System Allan variance double[] allanparms = InterpolateSpecAllan(band,lo_freq,oneGHzReference); // rescale to frequency resolution double alpha = allanparms[1]; double binningexp = 1.0 / allanparms[2]; double allan_time_lores = allanparms[0] * pow(1.0 / effResolution{1},binningexp); // Compute derived quantities int main_phase = iceil(0.3 * allan_time_lores); // How many lines could we do at most using datalimit? int n_linesperscan_guess = main_phase / datalimit + 1; n_linesperscan_guess = imax(n_linesperscan_guess * n_linesperscan_guess / npoints,1); // restrict the scan size if(nlines == 1 && n_linesperscan_guess > 1) { n_linesperscan_guess = 2; } else { n_linesperscan_guess = IMultiple(n_linesperscan_guess,nlines); n_linesperscan_guess = imin(n_linesperscan_guess,nlines); } int n_linesperscan_range = 1 - n_linesperscan_guess; if(n_linesperscan_range == 0) { n_linesperscan_range = 1; } double n_pointsperscan = double(n_linesperscan * npoints); // Compute back int int_time_guess = imax(main_phase / iceil(sqrt(n_pointsperscan)),datalimit); int data_time_guess = imin(5,int_time_guess); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } int n_int_on_guess = imax(int_time_guess / data_time_guess,1); int n_int_on_range = 1 - n_int_on_guess; if(n_int_on_range == 0) { n_int_on_range = 1; } // OFF integration int n_switch_off_guess = ifloor(double(n_int_on) * 0.67 * sqrt(n_pointsperscan)); int n_switch_off_range = n_switch_off_guess / 3; if(n_switch_off_range == 0) { n_switch_off_range = 1; } // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"n_int_on",double(n_int_on_guess),double(n_int_on_range)},{"n_linesperscan",double(n_linesperscan_guess),double(n_linesperscan_range)},{"n_switch_off",double(n_switch_off_guess),double(n_switch_off_range)}]; return retvalues; } // Interpolate differential load chop Allan time and exponent double[] procedure InterpolateSpecLChopAllan { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency bool subband = false; // 1GHz bandwith reference instead of full IF }{ // subband is not used yet double[] allan = CalibrationReader("loadchop_Allan",["spec_Allan_time","spec_Allan_exp","spec_binning_exp"],band,lo_freq); return allan; } ///////////////////////////////////////////////////////////////// // Procedure to compute detailed timing for a // Spectral Scan DBS observing mode // // We currently assume that each nodding motion is related to an // instrument calibration. This may be an efficiency limitation if // more calibration measurements are needed. Then the loop sequence // should be changed. // // This implementation assumes that the whole scan can be performed // with a single pointing command. If the system temperature varies // too much so that it cannot be compensated by a slight change of // the redundancy, the scan has to be split into several calls of this // mode. // {{int,int,int,int,int,int,int,int,int,bool,int,int,int},{int,double,double[],int[][],bool,double[],int,bool}} procedure SScanDBS_pre_timing { string band = "4a"; // HIFI band double lo_freq_low = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz int redundancy = 4; // Frequency scan redundancy {double,double} eff_resolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_chop = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per frequency and pointing int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int n_cycles = 1 in [1,600]; // Number of half OFF-ON-ON-OFF cycles at one frequency int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Create composite readout structure for backends {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // First check the group length // The frequency group length is given by n_freq_point. // It is derived in the sequencer using // GetFNoCalibLength(band,ref_freq); // For n_cycles>1 it has to be unity, everything else is rejected // We rely on the sequencer to determine the best group length if(n_cycles > 1 && n_freq_point > 1) { SError("Only frequency group length 1 allowed for cycle numbers > 1."); } // Get frequency grid characteristic parameters {int,double,double[],int[][],int,bool} fqparms = MakeFreqGrid(band,lo_freq_low,lo_freq_up,redundancy,0.0,n_freq_point); double reffreq = fqparms{1}; double[] freqgrid = fqparms{2}; int[][] grouporder = fqparms{3}; // Process tuning level grid double[][] levelgrid = GetSScanLevelGrid(band,wbs1,wbs2,freqgrid,fqparms{0},grouporder); {bool,double[]} targets = TargetLevels(band,reffreq,levelgrid); bool retuning = targets{0}; double[] targetgrid = targets{1}; string reftarget = ""; if(retuning) { reftarget = "sscan_normal"; } // Collect all frequency information in a tuple {int,double,double[],int[][],bool,double[],int,bool} spectralparms = {fqparms{0},reffreq,freqgrid,grouporder,retuning,targetgrid,fqparms{4},fqparms{5}}; ////////////////////////////////////////////////////////////////////// // Get timing within the normal DBS observations // Compute load integration time int loadlength = duration(SScanLoadMeasurement(band,reffreq,reffreq,true,eff_resolution{0},data_time,backendreadoutparms)); int readoutdead = SlowChopReadoutDelay(band,reffreq,backendreadoutparms); loadlength = loadlength + readoutdead; int load_spacing = CheckedLoadSpacing(load_interval - loadlength,8); int jitterdead = GetMaxTimeJitter(band,reffreq); // Integration time per frequency and pointing int inttime = 2 * n_chop * data_time; int readouttime = data_time; // Duration of initial set up // Staying at the same frequency makes no sense here. // First frequency point double runningfreq = freqgrid[grouporder[0][0]]; // determine exact duration only in case of full commanding if(docommands) { int initlength = duration(HIFIInitObs()); initlength = initlength + duration(TuneHIFI(band,runningfreq,hrs1,hrs2,wbs1{0},wbs2{0},"sscan_normal")); // Add time for HK readout int hkduration = HkReadoutTime(band,reffreq,backendreadoutparms,false); initlength = initlength + hkduration; } else { initlength = GetRoughInitLength(band,runningfreq,false); } initlength = initlength + loadlength; // Tuning delays int bigtunestep = duration(HIFIRetuneFreq(band,reffreq,reftarget)); // Correct for variation within the band int tunediff = ComputeLOTimeDifference(band,lo_freq_low,lo_freq_up,reffreq); bigtunestep = bigtunestep + tunediff; if(n_freq_point > 1) { int smallstep = duration(HIFIChangeFreq(band,reffreq)); } else { smallstep = bigtunestep; } // For double phases I can use the added jitterdead in both phases for tune int halftunestep = (bigtunestep - jitterdead + 1) / 2; // Check load_interval allowance int scan_time = 2 * inttime + bigtunestep; if(scan_time > load_spacing) { SError("Load interval of " + load_interval + "s is exceeded by " + n_chop + " chop cycles."); } // Rough estimate of the pointing time to issue a representative // telescope command if(n_cycles > 1) { // How often do I have to perform a load slew int n_loadinterval = imax(load_interval / scan_time,1); // fit with n_cycles n_loadinterval = imin(n_loadinterval,n_cycles); n_loadinterval = IMultiple(n_loadinterval,n_cycles); // Pointing time int pointing = inttime + jitterdead; } else { n_loadinterval = 1; pointing = n_freq_point * inttime + (n_freq_point - 1) * smallstep + halftunestep + jitterdead; } int n_bchop = n_chop; // recompute load length during slews in case of short integrations // This regime must be maintained in the post_timing if(n_loadinterval <= 1) { loadlength = duration(SScanLoadMeasurement(band,reffreq,reffreq,false,eff_resolution{0},data_time,backendreadoutparms)); loadlength = loadlength + readoutdead; } // No dangling needed in this mode - we stop halftunelength before telescope int dangling = 0; bool end_load = false; // Return all the times needed for telescope call and post_timing processing return {{inttime,pointing,readouttime,loadlength,jitterdead,load_spacing,bigtunestep,n_loadinterval,n_bchop,end_load,smallstep,initlength,dangling},spectralparms}; } ///////////////////////////////////////////////////////////////// // Fast-chop spectral scan observing modes // {string,double,double}[] procedure HifiSScanProcFastDBSSequencerInit { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz int redundancy = 4 in [1,12]; // Frequency scan redundancy {double,double} effResolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool wbs1Used = true; // whether WBS1 is used bool wbs2Used = true; // whether WBS2 is used /* Sequence parameters */ int data_time = 10 in [4,80]; // data dump interval int n_int_on = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_switch_on = 1 in [1,1800]; // number of data transfer cycles per pointing int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int n_cycles = 1 in [1,600]; // Number of half OFF-ON-ON-OFF cycles at one frequency int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,redundancy,wbs1Used,wbs2Used,data_time / 2); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hr1{0},hr1{1},hr1{3}},{hr2{0},hr2{1},hr2{3}},wb1,wb2}; // Get frequency grid characteristic parameters {double,int,double} gfref = GetFReference(band,lo_freq,lo_freq_up); double reffreq = gfref{0}; int stdredun = gfref{1}; double stdstep = gfref{2}; int increment = stdredun / redundancy; // allowed group size double nocaliblen = GetFNoCalibLength(band,reffreq); int n_freq_point_guess = ifloor(nocaliblen / (stdstep * double(increment)) + 1.0); int n_freq_point_range = 1 - n_freq_point_guess; if(n_freq_point_range == 0) { n_freq_point_range = 1; } // Now general part of DBS modes // Get the drift parameters to compute the drift noise // spectral scans always use the full bandwidth for reference bool narrowReference = false; {double,double} phaselengths = DBSPhaseLengths(band,reffreq,effResolution,continuumDetection,narrowReference); // Compute derived quantities // Top down approach here int main_phase = iceil(phaselengths{0}); // Arbitrary selection of data_time int data_time_guess = 20; // remaining part for n_switch int n_switch_on_guess = main_phase / (n_freq_point_guess * data_time_guess) + 1; data_time_guess = main_phase / (n_freq_point_guess * n_switch_on_guess); // Check with data rate {int,double[]} dataparms = DataTaking(backendreadoutparms,8); int datalimit = 2 * dataparms{0}; if(data_time_guess < datalimit) { data_time_guess = datalimit; n_switch_on_guess = 1; } int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } // Chop phase length double phase_min = min(max(phaselengths{1},0.15),1.5); int n_int_on_guess = ifloor(double(data_time_guess) / (2.0 * phase_min)); int n_int_on_range = -n_int_on_guess / 2; if(n_int_on_range == 0) { n_int_on_range = 1; } // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"n_int_on",double(n_int_on_guess),double(n_int_on_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)},{"n_freq_point",double(n_freq_point_guess),double(n_freq_point_range)}]; return retvalues; } // FPU Standby with HBB On, block block Band0_hbb_on_fm HIFI 3298 { string band = "0"; // HIFI band string chop_loop = "CLOSE"; // Chopper Loop status }{ Start_block(); //Get parameters {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,0.0); int band_nb = iround(result_d[0]{0}); // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,0.0); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // string chop_sine_s = "ON"; // string chop_loop = "CLOSE" ; result_d = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current_on"],band,0.0); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // double calibcurrent = result_d[7]{0}; // result_d = ConfigurationReader("name_confilfpu",["bias_standby_h","diplexer_standby_h","bias_standby_v","diplexer_standby_v","diplex_h_ctrl_mode","diplex_v_ctrl_mode","chop_M3right"],band,0.0); // double bias_H = result_d[0]{0}; double diplex_H = result_d[1]{0}; double bias_V = result_d[2]{0}; double diplex_V = result_d[3]{0}; int diplex_h_ctrl_mode = iround(result_d[4]{0}); int diplex_v_ctrl_mode = iround(result_d[5]{0}); // //Retrieve magnets Magnet are so far at maximum value. Now set to nominal double magnetcurrent_H = result_d[1]{0}; double magnetcurrent_V = result_d[4]{0}; // if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilfpu",["magnet_standby_h","magnet_standby_v"],band,0.0); magnetcurrent_H = result_d[0]{0}; magnetcurrent_V = result_d[1]{0}; } // result_d = ConfigurationReader("name_chopper",["chop_startup_cold"],band,0.0); if(chop_loop == "OPEN") { result_d = ConfigurationReader("name_chopper",["chop_startup_warm"],band,0.0); } double chopper = result_d[0]{0}; //For this configuration we won't convert prime chopper voltage into redundant voltage //Just checking we are in range. //chopper = Check_Chopper_Prime_Redundant(chopper); chopper = Check_Chopper_Range(chopper); // // //Switch on upconverter, assuming chopper and mixers are also ON Hifi_HIFI_Configure_FCU_Power($BBID,"ON","ON","ON","ON","ON"); // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result_d = ConfigurationReader("name_delays",["config_fpu_delay"],band,0.0); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // } // Interpolate differential total power sky chop Allan time and exponent double[] procedure InterpolateTpChopAllan { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency bool subband = false; // 1GHz bandwith reference instead of full IF }{ // subband is not used yet double[] allan = CalibrationReader("chop_Allan",["tp_Allan_time","tp_Allan_exp","tp_binning_exp"],band,lo_freq); return allan; } //Test CSS-IEGSE link during IST block HIFI_CcsHanderTestBB HIFI 3698 { int cmdCnt = 1; }{ for(int k = 1 .. cmdCnt) { //IstCcsEgse_YC00X962(2,[{1},{2}]); delay(1); } } //HIFI vector scan, block //Check vector scan from safe to values close to BLUE MAX block Vector_scan_w_M1M2D2_block_fm HIFI 3973 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency double m1 = -5.0; //M1 value double m2 = -10.0; //M2 value double vd2_min = 1.8; //Min Vd2 over the scan (max is bluemax) }{ //Clear potential failure mode Set_LO_Nominal_proc_fm(); // //Start_block(); //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = m1; //result[1]{0}; double m2_v = m2; //result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v_start = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); double drain2_safe = cresult[0]; drain2_v_start = vd2_min; //drain2_safe; // double drain2_max = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // result = ConfigurationReader(name_configlotune,["nsteps","step_time"],band,lo_freq); int nsteps = iround(result[0]{0}); double step_drain2_v = -1.0 * (drain2_max - drain2_v_start) / double(nsteps - 1); drain2_v_start = drain2_max; double step_time = 1.0; //result[1]{0}; // //Preliminary configuration at high Vd2 // //Compute config_lo_delay: new approach: use ramp-up time result = ConfigurationReader("name_delays",["lock_lo_delay","vd2_rampup_speed"],band,lo_freq); int config_lo_delay = iceil(result[0]{0} + (drain2_v_start - drain2_safe) / result[1]{0}); //Old approach: fixed delay //result = ConfigurationReader("name_delays", // ["config_lo_delay"],band, lo_freq); //int config_lo_delay = iround(result[0]{0}); // //Send command HIFI_Configure_LCU_proc_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,macro_checksum,config_lo_delay); // //Load vector scan //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Load_vector_safe_1a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "1b") { //Band 1b Hifi_HIFI_Load_vector_safe_1b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2a") { //Band 2a Hifi_HIFI_Load_vector_safe_2a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2b") { //Band 2b Hifi_HIFI_Load_vector_safe_2b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3a") { //Band 3a Hifi_HIFI_Load_vector_safe_3a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3b") { //Band 3b Hifi_HIFI_Load_vector_nom_3b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "4a") { //Band 4a Hifi_HIFI_Load_vector_safe_4a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "4b") { //Band 4b Hifi_HIFI_Load_vector_safe_4b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "5a") { //Band 5a Hifi_HIFI_Load_vector_nom_5a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "5b") { //Band 5b Hifi_HIFI_Load_vector_nom_5b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6a") { //Band 6a Hifi_HIFI_Load_vector_nom_6a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6b") { //Band 6b Hifi_HIFI_Load_vector_nom_6b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7a") { //Band 7a Hifi_HIFI_Load_vector_nom_7a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7b") { //Band 7b Hifi_HIFI_Load_vector_nom_7b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } // //delay(1); //Execute vector scan Hifi_HIFI_vector_scan($BBID); double time_needed = double(nsteps) * step_time; delay(iround(time_needed + 2.0 + 0.5)); //0.5s added for completion of load_vector //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } // Recalculate and verify LCU memory checksum block LcuChecksumRecalc_fm HIFI 3904 { }{ Start_block(); string section = GetLcuSection(); int expected_sum = ilookup("LcuChecksumTable.config",section,"normal"); // initial install of default safe table - simulate transition to normal Hifi_HIFI_LCU_Single($BBID,"HL_DEF_SAFE"); delay(1); //Stop LCU HK collection - see SPR-1679 //Get applicable HK rate {double,string}[] result_d = ConfigurationReader("name_delays",["hk_rate"],"0",0.0); string hk_rate = result_d[0]{1}; Hifi_HIFI_Housekeeping_on(hk_rate,"ON","OFF","ON","ON","ON","ON"); delay(1); Hifi_HIFI_check_LCU_memory($BBID,3000,expected_sum); //add 2sec to the initial 4sec - SPR-1744 delay(6); //Restore HK Hifi_HIFI_Housekeeping_on(hk_rate,"ON","ON","ON","ON","ON","ON"); delay(1); } //HIFI-COP-3-FTP obs HifiEng_FT_pumped_COP { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band }{ //General parameters in use int integ_time = 4; string backend = "both"; string[] hrs_mode = ["wb1","wb1"]; //For bands 6 and 7, use wb8 if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { hrs_mode = ["wb8","wb8"]; } // // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(FT_pumped_COP_proc_ops(band,integ_time,backend,hrs_mode)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution FT_pumped_COP_proc_ops(band,integ_time,backend,hrs_mode); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } // Diplexer calibration for a given mixer band // uses a list of pre-defined frequencies where to measure // the diplexer scan. procedure Diplexer_survey_proc_COP { string band = "3a" in ["3a","3b","4a","4b","6a","6b","7a","7b"]; // HIFI band }{ // //Get the list of frequencies to be used for the scan string tab = "config_dipscan_COP.config"; double bandnb = GetBandCode(band); double lofreqlow = dlookup(tab,"" + iceil(bandnb),"lofreqlow"); double lofreqhigh = dlookup(tab,"" + iceil(bandnb),"lofreqhigh"); double lofreqstep = dlookup(tab,"" + iceil(bandnb),"lofreqstep"); // LCU_switchon_proc_fm(band); //Wait an extra delay of 1 min for short term stabilization delay(60); // //Start loop on diplexer scans double current_LO = lofreqlow; bool endreached = false; //Loop on key frequencies per LO band while(current_LO <= lofreqhigh && endreached == false) { Check_Band_vs_Freq_proc_fm(band,current_LO); //Configure FPU at that frequency Init_MSA_HBB_fm(band,"CLOSE",current_LO,"ON"); //Perform LO tuning at that frequency //This needs to be done at 0.6mV bias due to Imix target LO_tuning_block_fm(band,current_LO); // //Prepare for diplexer scan //In case of band 6 or 7, use special biases if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { {double,string}[] result = ConfigurationReader("name_confilfpu",["bias_dipscan_h","bias_dipscan_v","bias_max_h","bias_max_v"],band,current_LO); //First go to 4mV Mixerbias_block_fm(result[2]{0},result[3]{0}); //Then to 3mV Mixerbias_block_fm(result[0]{0},result[1]{0}); } // //Perform diplexer scan at that frequency and M1 setting double diplexer_current_min_h = -2.24; double diplexer_current_max_h = 2.24; double diplexer_current_step = -0.073; //i.e. approx 4.48/61 int n_steps = 61; double stepTime = 0.1; // Scan_diplexer_block_fm(band,diplexer_current_max_h,diplexer_current_max_h,diplexer_current_step,n_steps,stepTime); // //Check last LO freq done if(current_LO == lofreqhigh && endreached == false) { endreached = true; } //Increase LO freq: truncate if step too high current_LO = current_LO + lofreqstep; if(current_LO > lofreqhigh && endreached == false) { current_LO = lofreqhigh; } // } //Close-off loop //In case of band 6 or 7,go back to nominal values if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { result = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,current_LO); //First go to 4mV Mixerbias_block_fm(result[0]{0},result[1]{0}); //Then to nominal result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,current_LO); Mixerbias_block_fm(result[0]{0},result[1]{0}); } } // Set the whole instrument to standby I mode // This only switches the lasers off // Will keep the HBB on mode HifiManCmd_HIFI_standbyII_to_standbyI { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! string laser_H = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2","Lasers_off"]; //WBS-V laser to be set ON string chopper_loop = "OPEN" in ["OPEN","CLOSE"]; //chopper loop status string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ Mode_status_check_standby_II(laser_H,laser_V,chopper_loop,"down",prime_or_redundant); mois_comment("Set HIFI to standby mode I with chopper loop " + chopper_loop); StartMode_block_ops(); //WBS stand-by with lasers off mois_step("Switch WBS-H and WBS-V lasers OFF"); WBS_standby_block_ops("0","Lasers_off","Lasers_off"); // StopMode_block_ops(); Mode_status_check_standby_I(chopper_loop,"up",prime_or_redundant); } // BLOCK : Functional Test No 2 (HRS Sine Internal Test) block HRS_functional_test_No_2_Sine_block_fm HIFI 3620 { string band = "1a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code for both polarizations int integ_time = 4; //Total integration time in sec. string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); //Fill in block parameter names for each mode - consequence of SPR-0198 string[] hrs_blocks_sine_ultra = ["sine_ultra","sine_ultra","sine_ultra","sine_ultra","sine_ultra","sine_ultra","sine_ultra","sine_ultra"]; string[] hrs_blocks_sine_wide = ["sine_wide","sine_wide","sine_wide","sine_wide","sine_wide","sine_wide","sine_wide","sine_wide"]; string[] hrs_blocks_sine_low = ["sine_hilonom","low","sine_low","low_nominal","sine_low_nom","low","sine_low","high_nominal_low"]; string[] hrs_blocks_sine_nom = ["sine_hilonom","high_nominal","high_nominal","low_nominal","sine_low_nom","high_nominal","high_nominal","high_nominal_low"]; string[] hrs_blocks_sine_high = ["sine_hilonom","high_nominal","high_nominal","high","high","high_nominal","high_nominal","high_nominal_low"]; // Configure spectroscopy Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); // // Configure LO and attenuators //============================= HRS_config_att_lo_fm(band,hrs_mode); // // Loops on the different configurations of the HRS //====================================== //Calls the 5 modes to be checked //sine_ultra Hifi_HIFI_Config_HRS_H_blocks($BBID,hrs_blocks_sine_ultra[0],hrs_blocks_sine_ultra[1],hrs_blocks_sine_ultra[2],hrs_blocks_sine_ultra[3],hrs_blocks_sine_ultra[4],hrs_blocks_sine_ultra[5],hrs_blocks_sine_ultra[6],hrs_blocks_sine_ultra[7]); //delay(1); Hifi_HIFI_Config_HRS_V_blocks($BBID,hrs_blocks_sine_ultra[0],hrs_blocks_sine_ultra[1],hrs_blocks_sine_ultra[2],hrs_blocks_sine_ultra[3],hrs_blocks_sine_ultra[4],hrs_blocks_sine_ultra[5],hrs_blocks_sine_ultra[6],hrs_blocks_sine_ultra[7]); delay(1); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // //sine_wide Hifi_HIFI_Config_HRS_H_blocks($BBID,hrs_blocks_sine_wide[0],hrs_blocks_sine_wide[1],hrs_blocks_sine_wide[2],hrs_blocks_sine_wide[3],hrs_blocks_sine_wide[4],hrs_blocks_sine_wide[5],hrs_blocks_sine_wide[6],hrs_blocks_sine_wide[7]); //delay(1); Hifi_HIFI_Config_HRS_V_blocks($BBID,hrs_blocks_sine_wide[0],hrs_blocks_sine_wide[1],hrs_blocks_sine_wide[2],hrs_blocks_sine_wide[3],hrs_blocks_sine_wide[4],hrs_blocks_sine_wide[5],hrs_blocks_sine_wide[6],hrs_blocks_sine_wide[7]); delay(1); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // //sine_low Hifi_HIFI_Config_HRS_H_blocks($BBID,hrs_blocks_sine_low[0],hrs_blocks_sine_low[1],hrs_blocks_sine_low[2],hrs_blocks_sine_low[3],hrs_blocks_sine_low[4],hrs_blocks_sine_low[5],hrs_blocks_sine_low[6],hrs_blocks_sine_low[7]); //delay(1); Hifi_HIFI_Config_HRS_V_blocks($BBID,hrs_blocks_sine_low[0],hrs_blocks_sine_low[1],hrs_blocks_sine_low[2],hrs_blocks_sine_low[3],hrs_blocks_sine_low[4],hrs_blocks_sine_low[5],hrs_blocks_sine_low[6],hrs_blocks_sine_low[7]); delay(1); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // //Sine_nominal Hifi_HIFI_Config_HRS_H_blocks($BBID,hrs_blocks_sine_nom[0],hrs_blocks_sine_nom[1],hrs_blocks_sine_nom[2],hrs_blocks_sine_nom[3],hrs_blocks_sine_nom[4],hrs_blocks_sine_nom[5],hrs_blocks_sine_nom[6],hrs_blocks_sine_nom[7]); //delay(1); Hifi_HIFI_Config_HRS_V_blocks($BBID,hrs_blocks_sine_nom[0],hrs_blocks_sine_nom[1],hrs_blocks_sine_nom[2],hrs_blocks_sine_nom[3],hrs_blocks_sine_nom[4],hrs_blocks_sine_nom[5],hrs_blocks_sine_nom[6],hrs_blocks_sine_nom[7]); delay(1); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // //Sine_high Hifi_HIFI_Config_HRS_H_blocks($BBID,hrs_blocks_sine_high[0],hrs_blocks_sine_high[1],hrs_blocks_sine_high[2],hrs_blocks_sine_high[3],hrs_blocks_sine_high[4],hrs_blocks_sine_high[5],hrs_blocks_sine_high[6],hrs_blocks_sine_high[7]); //delay(1); Hifi_HIFI_Config_HRS_V_blocks($BBID,hrs_blocks_sine_high[0],hrs_blocks_sine_high[1],hrs_blocks_sine_high[2],hrs_blocks_sine_high[3],hrs_blocks_sine_high[4],hrs_blocks_sine_high[5],hrs_blocks_sine_high[6],hrs_blocks_sine_high[7]); delay(1); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // } {int,double,double,double,double,double} obs HifiPointModeFastDBS { string modeName = "dbs"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 10 in [4,80]; // data dump interval int n_int_on = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_switch_on = 1 in [1,1800]; // number of data transfer cycles per pointing int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode OpenMessages("HIFI Single Point - DBS fastChop",{data_time,0,n_switch_on,n_int_on,0,0,0,0,n_cycles,load_interval}); // Call first part of the timing computer {int,int,int,int,int,int,int,int,int,bool,int,int,int} pre_timing = FastDBS_pre_timing(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_switch_on,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,int,int,int,int,int,int} tpar = DBS_telescope(naifid,onPosition,band,lo_freq,"",pre_timing,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = nodding_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},false); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,bool,int,int,int},bool,double,double} post_timing = DBS_post_timing(pre_timing,telescopetimes,n_cycles); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = DBS_telescope(naifid,onPosition,band,lo_freq,"",post_timing{1},n_cycles); // Call telescope command telescopetimes = nodding_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},false); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{3}; int n_load = post_timing{1}{6}; int n_loadinterval = post_timing{1}{7}; int n_seq = post_timing{1}{8}; bool end_load = post_timing{1}{9}; int shiftlength = post_timing{1}{10}; bool final_load = post_timing{2}; double tscan = post_timing{3}; double tdead = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { FastDBS_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_seq,n_load,n_loadinterval,end_load,final_load,startobs,telescopetimes,loadlength,shiftlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double} tact = FastDBS_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_seq,n_load,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = DBS_noisecomputer(band,lo_freq,effResolution,continuumDetection,oneGHzReference,n_cycles,tscan,tact); // Evaluate performance DBS_performance(band,lo_freq,effResolution,noisevalues,timeTaken,n_cycles,n_seq * n_int_on * (n_load + 1),tscan,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // LCU configuration AT START-UP into NOMINAL mode, procedure // Uses SFT approach with old 5 TM TC call procedure LCU_switchon_proc_sft { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band }{ //Clear potential failure mode Set_LO_Nominal_block_fm(); // //We use a constant frequency for each band, regardless of the input double lo_freq = 0.0; double[] result_d = CalibrationReader("name_keyfreq",["keyfreq","midfreq","keyfreqwarm","keyfreq_dummy"],band,0.0); lo_freq = result_d[0]; //this is for cold operations // lo_freq = result_d[2]; //this is for warm operations // lo_freq = result_d[3]; //this is for dummy operations ////FM_CUS_11.5: replace keyfreq by the only allowed frequency for warm IST //For band 7b, 1723.5 may be problematic. Take mid freq. instead //if (band == "7b") { // lo_freq = result_d[1]; // } // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_confindex = "name_confindex_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlcutune = "name_configlcutune_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1_v = result[0]{1}; string curlim2_v = result[1]{1}; // result = ConfigurationReader("name_delays",["switch_on_delay","config_lo_delay"],band,lo_freq); int switch_on_delay = iround(result[0]{0}); int config_lo_delay = iround(result[1]{0}); // cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); drain2_v = cresult[0]; //Send command: expect that we have already switched to NOMINAL //We set D2 to best guess and wait some time to stabilize chain temperature HIFI_Configure_LCU_block_sft(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum,switch_on_delay); // //Set heater to their switch-on value HL_heater_block_fm(band,"nominal"); } // LCU configuration AT START-UP into NOMINAL mode, procedure procedure LCU_switchon_w_D2_proc_fm { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency double drain2_v = 1.4; //Drain2 voltage in V }{ //Clear potential failure mode Set_LO_Nominal_block_fm(); // //We use a constant frequency for each band, regardless of the input double[] result_d = CalibrationReader("name_keyfreq",["keyfreq","midfreq","keyfreqwarm","keyfreq_dummy"],band,0.0); lo_freq = result_d[0]; //this is for cold operations // lo_freq = result_d[2]; //this is for warm operations // lo_freq = result_d[3]; //this is for dummy operations ////FM_CUS_11.5: replace keyfreq by the only allowed frequency for warm IST //For band 7b, 1723.5 may be problematic. Take mid freq. instead //if (band == "7b") { // lo_freq = result_d[1]; // } // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; //double drain2_v_start = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1_v = result[0]{1}; string curlim2_v = result[1]{1}; // result = ConfigurationReader("name_delays",["switch_on_delay"],band,lo_freq); int switch_on_delay = iround(result[0]{0}); // //Send command: expect that we have already switched to NOMINAL //Contrary to QM, the channel is automatically switched ON HIFI_Configure_LCU_block_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum,switch_on_delay); // //Set heater to their switch-on value HL_heater_block_fm(band,"nominal"); } // Get maximum commanding time jitter which has to be added as margin int procedure GetMaxTimeJitter { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency }{ double[] dead = CalibrationReader("timejitter",["timejitter"],band,lo_freq); return iceil(dead[0]); } // IV curve with magnets set to 0, block block IVcurve_with_zero_magnet_fm HIFI 3214 { string band = "1a"; }{ //Start_block() ; {double,string}[] result_d = ConfigurationReader("name_confilfpu",["bias_min_h","bias_max_h","bias_steps_h","bias_min_v","bias_max_v","bias_steps_v"],band,0.0); //H polar double bias_min_h = result_d[0]{0}; double bias_max_h = result_d[1]{0}; int steps_h = iround(result_d[2]{0}); //V polar double bias_min_v = result_d[3]{0}; double bias_max_v = result_d[4]{0}; int steps_v = iround(result_d[5]{0}); //Bias to set at end of IVC //Need a representative frequency: take keyfreq double[] result = CalibrationReader("name_keyfreq",["keyfreq"],band,0.0); double lo_freq = result[0]; // result_d = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v","norm_magn_h","norm_magn_v"],band,lo_freq); double bias_h = result_d[0]{0}; double bias_v = result_d[1]{0}; //Magnets are set to 0 double magnetcurrent_h = 0.0; double magnetcurrent_v = 0.0; //The IVCurve is done on the smallest range and the finest step double bias_min = max(bias_min_h,bias_min_v); double bias_max = min(bias_max_h,bias_max_v); int steps = iround(max(double(steps_h),double(steps_v))); // //First set magnets to max. double magnet_current_max_h = 0.0; double magnet_current_max_v = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,0.0); magnet_current_max_h = result_d[0]{0}; magnet_current_max_v = result_d[1]{0}; } Hifi_HIFI_CH1_MX_MG_C($BBID,magnet_current_max_h); Hifi_HIFI_CV1_MX_MG_C($BBID,magnet_current_max_v); delay(1); //Perform IV curve IVcurve(band,bias_min,bias_max,steps,magnetcurrent_h,magnetcurrent_v,bias_h,bias_v); } // HRS partial configuration, procedure // Configures the LO and attenuators with att. input: all the same procedure HRS_config_att_lo_w_att_fm { string band = "1a"; // HIFI band string[] hrs_mode = ["mr","mr"]; //HRS resolution code double new_att = 15.5; //Att. value to apply to all }{ // Fetch HRS configuration parameters //=================================== //H-polar string hrs_filename_h = "name_confighrs_" + hrs_mode[0]; {double,string}[] result = ConfigurationReader(hrs_filename_h,["hrh_switch","hrh_1u_att","hrh_1l_att","hrh_2u_att","hrh_2l_att","hrh_3u_att","hrh_3l_att","hrh_4u_att","hrh_4l_att","hrh_up_ol1","hrh_up_ol2","hrh_up_ol3","hrh_up_ol4","hrh_down_ol5","hrh_down_ol6","hrh_down_ol7"],band,0.0); string hrs_polarization_h = result[0]{1}; double hrsH_ATT_U1 = new_att; double hrsH_ATT_L1 = new_att; double hrsH_ATT_U2 = new_att; double hrsH_ATT_L2 = new_att; double hrsH_ATT_U3 = new_att; double hrsH_ATT_L3 = new_att; double hrsH_ATT_U4 = new_att; double hrsH_ATT_L4 = new_att; double[] hrsH_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; //V-polar string hrs_filename_v = "name_confighrs_" + hrs_mode[1]; result = ConfigurationReader(hrs_filename_v,["hrv_switch","hrv_1u_att","hrv_1l_att","hrv_2u_att","hrv_2l_att","hrv_3u_att","hrv_3l_att","hrv_4u_att","hrv_4l_att","hrv_up_ol1","hrv_up_ol2","hrv_up_ol3","hrv_up_ol4","hrv_down_ol5","hrv_down_ol6","hrv_down_ol7"],band,0.0); string hrs_polarization_v = result[0]{1}; double hrsV_ATT_U1 = new_att; double hrsV_ATT_L1 = new_att; double hrsV_ATT_U2 = new_att; double hrsV_ATT_L2 = new_att; double hrsV_ATT_U3 = new_att; double hrsV_ATT_L3 = new_att; double hrsV_ATT_U4 = new_att; double hrsV_ATT_L4 = new_att; double[] hrsV_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; // result = ConfigurationReader("name_delays",["hrs_config_delay"],band,0.0); int hrs_config_delay = iround(result[0]{0}); //Convert IF frequencies into A and M parameters //Truncate wb or hr keyword: string[] output_hrs_mode = GetHrsMode_proc_fm(hrs_mode); string hrs_mode_h = output_hrs_mode[0]; string hrs_mode_v = output_hrs_mode[1]; // int[] a_m_parameter = ComputeA_M_parameters([hrs_mode_h,hrs_mode_v],hrsH_LO[0],hrsH_LO[1],hrsH_LO[2],hrsH_LO[3],hrsH_LO[4],hrsH_LO[5],hrsH_LO[6],hrsV_LO[0],hrsV_LO[1],hrsV_LO[2],hrsV_LO[3],hrsV_LO[4],hrsV_LO[5],hrsV_LO[6]); //H-polar int hrsH_LO1_M = a_m_parameter[1]; int hrsH_LO1_A = a_m_parameter[0]; int hrsH_LO2_M = a_m_parameter[3]; int hrsH_LO2_A = a_m_parameter[2]; int hrsH_LO3_M = a_m_parameter[5]; int hrsH_LO3_A = a_m_parameter[4]; int hrsH_LO4_M = a_m_parameter[7]; int hrsH_LO4_A = a_m_parameter[6]; int hrsH_LO5_M = a_m_parameter[9]; int hrsH_LO5_A = a_m_parameter[8]; int hrsH_LO6_M = a_m_parameter[11]; int hrsH_LO6_A = a_m_parameter[10]; int hrsH_LO7_M = a_m_parameter[12]; Hifi_HIFI_Config_HRS_H_att_lo($BBID,hrs_polarization_h,hrsH_ATT_U1,hrsH_ATT_L1,hrsH_ATT_U2,hrsH_ATT_L2,hrsH_ATT_U3,hrsH_ATT_L3,hrsH_ATT_U4,hrsH_ATT_L4,hrsH_LO1_M,hrsH_LO1_A,hrsH_LO2_M,hrsH_LO2_A,hrsH_LO3_M,hrsH_LO3_A,hrsH_LO4_M,hrsH_LO4_A,hrsH_LO5_M,hrsH_LO5_A,hrsH_LO6_M,hrsH_LO6_A,hrsH_LO7_M); // //delay(hrs_config_delay); //V-polar int hrsV_LO1_M = a_m_parameter[14]; int hrsV_LO1_A = a_m_parameter[13]; int hrsV_LO2_M = a_m_parameter[16]; int hrsV_LO2_A = a_m_parameter[15]; int hrsV_LO3_M = a_m_parameter[18]; int hrsV_LO3_A = a_m_parameter[17]; int hrsV_LO4_M = a_m_parameter[20]; int hrsV_LO4_A = a_m_parameter[19]; int hrsV_LO5_M = a_m_parameter[22]; int hrsV_LO5_A = a_m_parameter[21]; int hrsV_LO6_M = a_m_parameter[24]; int hrsV_LO6_A = a_m_parameter[23]; int hrsV_LO7_M = a_m_parameter[25]; Hifi_HIFI_Config_HRS_V_att_lo($BBID,hrs_polarization_v,hrsV_ATT_U1,hrsV_ATT_L1,hrsV_ATT_U2,hrsV_ATT_L2,hrsV_ATT_U3,hrsV_ATT_L3,hrsV_ATT_U4,hrsV_ATT_L4,hrsV_LO1_M,hrsV_LO1_A,hrsV_LO2_M,hrsV_LO2_A,hrsV_LO3_M,hrsV_LO3_A,hrsV_LO4_M,hrsV_LO4_A,hrsV_LO5_M,hrsV_LO5_A,hrsV_LO6_M,hrsV_LO6_A,hrsV_LO7_M); // delay(hrs_config_delay); } //HIFI vector scan, block //Check vector scan from safe to values close to BLUE MAX block Vector_scan_BLUE_LIMIT_block_fm HIFI 3672 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency }{ //Clear potential failure mode Set_LO_Nominal_proc_fm(); // //Start_block(); //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v_start = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); double drain2_safe = cresult[0]; drain2_v_start = drain2_safe; // double drain2_max = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // //For bands 1 to 5, scan will be done with increasing drain2 voltages // //For bands 6 to 7, scan will be done with decreasing drain2 voltages: NOT FOR THIS TEST !! if(band == "6a" || band == "7a" || band == "6b" || band == "7b") { //step_drain2_v = -1.0*step_drain2_v; //drain2_v_start = drain2_max; //Also, it probably makes no sense to go down to the safe value drain2_v_start = drain2_safe + 0.45; //i.e. go to 1.7 //Need to check that drain2_v_start has not got above the blue max //If so, the range to scan is not so big so we stick to the safe value //as minimum drain2 for the scan if(drain2_v_start >= drain2_max) { drain2_v_start = drain2_safe; } } // result = ConfigurationReader(name_configlotune,["nsteps","step_time"],band,lo_freq); int nsteps = iround(result[0]{0}); double step_drain2_v = -1.0 * (drain2_max - drain2_v_start) / double(nsteps - 1); drain2_v_start = drain2_max; double step_time = 5.0; //result[1]{0}; // //Preliminary configuration at high Vd2 // //Compute config_lo_delay: new approach: use ramp-up time result = ConfigurationReader("name_delays",["lock_lo_delay","vd2_rampup_speed"],band,lo_freq); int config_lo_delay = iceil(result[0]{0} + (drain2_v_start - drain2_safe) / result[1]{0}); //Old approach: fixed delay //result = ConfigurationReader("name_delays", // ["config_lo_delay"],band, lo_freq); //int config_lo_delay = iround(result[0]{0}); // //Send command HIFI_Configure_LCU_proc_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,macro_checksum,config_lo_delay); // //Load vector scan //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Load_vector_safe_1a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "1b") { //Band 1b Hifi_HIFI_Load_vector_safe_1b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2a") { //Band 2a Hifi_HIFI_Load_vector_safe_2a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2b") { //Band 2b Hifi_HIFI_Load_vector_safe_2b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3a") { //Band 3a Hifi_HIFI_Load_vector_safe_3a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3b") { //Band 3b Hifi_HIFI_Load_vector_nom_3b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "4a") { //Band 4a Hifi_HIFI_Load_vector_safe_4a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "4b") { //Band 4b Hifi_HIFI_Load_vector_safe_4b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "5a") { //Band 5a Hifi_HIFI_Load_vector_nom_5a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "5b") { //Band 5b Hifi_HIFI_Load_vector_nom_5b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6a") { //Band 6a Hifi_HIFI_Load_vector_nom_6a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6b") { //Band 6b Hifi_HIFI_Load_vector_nom_6b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7a") { //Band 7a Hifi_HIFI_Load_vector_nom_7a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7b") { //Band 7b Hifi_HIFI_Load_vector_nom_7b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } // //delay(1); //Execute vector scan Hifi_HIFI_vector_scan($BBID); double time_needed = double(nsteps) * step_time; delay(iround(time_needed + 2.0 + 0.5)); //0.5s added for completion of load_vector //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } // WBS comb, block block WBS_calibration_block_fm HIFI 3796 { }{ //Initial configuration //H-Polarization // {double,string}[] result_d = ConfigurationReader("name_configwbs",["hwh_att_band4_comb","hwh_att_band3_comb","hwh_att_band2_comb","hwh_att_band1_comb","hwh_att_in_comb"],"1a",0.0); int hwh_att_band4 = iround(result_d[0]{0}); int hwh_att_band3 = iround(result_d[1]{0}); int hwh_att_band2 = iround(result_d[2]{0}); int hwh_att_band1 = iround(result_d[3]{0}); int hwh_att_in = iround(result_d[4]{0}); // Hifi_HIFI_WBS_Calibrate($BBID,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); //Apply delay result_d = ConfigurationReader("name_delays",["wbs_new_comb_delay"],"1a",0.0); int wbs_new_comb_delay = iround(result_d[0]{0}); delay(wbs_new_comb_delay); // } // Slow chop integration at source position OFF-ON-ON-OFF... block HIFISlowChopOnIntegration HIFI 6031 { int data_time = 4; // Integration time between two data readouts int n_cycle = 1; // chop cycle number string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double[] rates = [120.0,1.0,2.0]; // Data rates between and during integrations }{ HIFI_Spectr_slow_chop_proc_aot(data_time,n_cycle,band,lo_freq,["chop_M3left","chop_M3right"],rates); } //Generic procedure to launch engineering scan applied to chopper rotation, procedure procedure Engineering_scan_for_chopper_rotation { double targetAngle = 0.0; //Target chopper voltage int milliSecSample = 3; // interval between samples int samplesBefore = 30 in [0,50]; // HIF_N_samples_1 int samplesAfter = 1000 in [0,1000]; // HIF_N_samples_2 }{ // targetAngle = Check_Chopper_Prime_Redundant(targetAngle); HIFI_Chopper_scan_fast_proc_fm(milliSecSample,targetAngle,samplesBefore,samplesAfter); // // delay calculation int nb_HK = 1; //For this TC, the 2 last HK fields are blanked out int millisecondsUsed = 1000 + 10 + milliSecSample * nb_HK * (samplesBefore + samplesAfter); delay(iceil(0.0010 * double(millisecondsUsed))); // } ////////////////////////////////////////////////////////// // Parameter scans //////////////////////////// //LO parameter scan with HotCold measurement procedure LCU_power_scan_with_Tsys { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4 double lo_freq = 500.0; //LO frequency double param_min = 1.0; //Min. of scanned parameter double param_max = 2.0; //Max. of scanned parameter double step_size = 0.1; //Step size string param_name = "D2"; //Code of scanned parameter: M1,M2,G1,G2,D1,D2. int integ_time = 4; //Total integration time in sec. string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Configure and tune backends Chopper_Rotation_block_fm(band,"chop_M3_ang","chop_hot_ang"); // //Configure and tune backends if(backend == "wbs" || backend == "both") { WBS_calib_fm(band); WBS_config_block_fm(band); WBS_tune_proc_fm(band); } if(backend == "hrs" || backend == "both") { HRS_config_block_fm(band,hrs_mode); HRS_tune_block_fm(band); } // //Configure spectrometers integration after tuning int[] res = Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // cresult = CalibrationReader("name_lcu_safe_values",["d1_v","d2_v"],band,lo_freq); double drain1_safe = cresult[0]; double drain2_safe = cresult[1]; // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1_v = result[0]{1}; string curlim2_v = result[1]{1}; // result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); // //First set to nominal values HIFI_Configure_LCU_block_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_safe,curlim1_v,drain2_safe,curlim2_v,macro_checksum,config_lo_delay); // double current_param = param_min; //Loop up on parameter of interest, all other values set to //optimum value at the frequency of interest. while(current_param <= param_max) { //Identify parameter to be scanned. if(param_name == "M1") { m1_v = current_param; } if(param_name == "M2") { m2_v = current_param; } if(param_name == "G1") { gate1_v = current_param; } if(param_name == "G2") { gate2_v = current_param; } if(param_name == "D1") { drain1_v = current_param; } if(param_name == "D2") { drain2_v = current_param; } HIFI_Configure_LCU_block_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum,config_lo_delay); // current_param = current_param + step_size; //Now take HotCold spectrum Hot_cold(band,hrs_mode,backend,res[0] * res[1],"tp",0,0); // } //Back to nominal values result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); plevel_v = result[0]{0}; m1_v = result[1]{0}; m2_v = result[2]{0}; m3_v = result[3]{0}; d2_step = iround(result[4]{0}); // cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); gate1_v = cresult[0]; gate2_v = cresult[1]; drain1_v = cresult[2]; drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); freq_nx = iround(result[0]{0}); //Compute lsu_main and offset resu = ComputeLSU_A_M_R(band,lo_freq); lsu_main = resu[0]; lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); macro_checksum = iround(result[0]{0}); // HIFI_Configure_LCU_block_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum,config_lo_delay); // } // thermal tests block Thermal_warm_fm HIFI 3283 { string band = "1a"; // HIFI band double lo_freq = 522.0; //LO frequency string polar = "H" in ["H","V"]; //Mixer polarization: H or V }{ //Start_block(); //Polarization selection: the unused polar will have parameters kept to 0 double filter_H = 0.0; double filter_V = 0.0; if(polar == "H") { filter_H = 1.0; } else { filter_V = 1.0; } {double,string}[] result_d = ConfigurationReaderWarm("name_confilfpu",["band"],band,lo_freq); int band_nb = iround(result_d[0]{0}); // //Get Targetted values for magnet, mixer bias, heater time and diplexer double[] cresult_d = CalibrationReader("name_configthermal",["dipl_h","magn_h","mbias_h","heat_h","dipl_v","magn_v","mbias_v","heat_v"],band,0.0); double target_dipl_h = cresult_d[0]; double target_magn_h = cresult_d[1]; double target_mbias_h = cresult_d[2]; double target_heat_h = cresult_d[3]; double target_dipl_v = cresult_d[4]; double target_magn_v = cresult_d[5]; double target_mbias_v = cresult_d[6]; double target_heat_v = cresult_d[7]; // int diplex_h_ctrl_mode = 0; //this is HF_CH1_DPFPP1 // double volt_H_FIF_1 = 0.0; double curr_H_FIF_1 = 0.0; double volt_H_FIF_2 = 0.0; double curr_H_FIF_2 = 0.0; // double volt_H_SIF_1 = 0.0; double curr_H_SIF_1 = 0.0; double volt_H_SIF_2 = 0.0; double curr_H_SIF_2 = 0.0; double volt_H_SIF_3 = 0.0; double curr_H_SIF_3 = 0.0; // int diplex_v_ctrl_mode = 0; //this is HF_CV1_DPFPP1 // double volt_V_FIF_1 = 0.0; double curr_V_FIF_1 = 0.0; double volt_V_FIF_2 = 0.0; double curr_V_FIF_2 = 0.0; // double volt_V_SIF_1 = 0.0; double curr_V_SIF_1 = 0.0; double volt_V_SIF_2 = 0.0; double curr_V_SIF_2 = 0.0; double volt_V_SIF_3 = 0.0; double curr_V_SIF_3 = 0.0; // string chop_sine_s = "ON"; string chop_loop = "CLOSE"; result_d = ConfigurationReaderWarm("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3"],band,lo_freq); int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // result_d = ConfigurationReaderWarm("name_confilfpu",["calibrator_current_on"],band,lo_freq); double calibcurrent = result_d[0]{0}; double bias_H = 0.0; double magnetcurrent_H = 0.0; double diplex_H = 0.0; double bias_V = 0.0; double magnetcurrent_V = 0.0; double diplex_V = 0.0; result_d = ConfigurationReaderWarm("name_confilfpu",["chop_cold"],band,lo_freq); double chopper = result_d[0]{0}; chopper = Check_Chopper_Prime_Redundant(chopper); // //Start modification of FPU parameters - This is also the 0 of the test clock //1. Initial configuration with the chopper moving to M3 middle HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // delay(300); // //2. Move diplexer: values depend on frequency //Diplexer is interpolated from a table for Bands 3, 4, 6L and 6H if(band_nb <= 2 || band_nb == 5) { diplex_H = 0.0; //For bands 1, 2 and 5 diplex_V = 0.0; diplex_h_ctrl_mode = 0; diplex_v_ctrl_mode = 0; } else { //Get diplexer currents result_d = ConfigurationReader("name_confilfpu",["diplex_h_ctrl_mode","diplex_v_ctrl_mode"],band,lo_freq); diplex_h_ctrl_mode = iround(filter_H * result_d[0]{0}); diplex_v_ctrl_mode = iround(filter_V * result_d[1]{0}); diplex_H = target_dipl_h * filter_H; diplex_V = target_dipl_v * filter_V; } // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(300); // //3. Do action corresponding to IF2 on: All SIF parameters are set // // result_d = ConfigurationReaderWarm("name_confilfpu",["sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,lo_freq); volt_H_SIF_1 = filter_H * result_d[0]{0}; curr_H_SIF_1 = filter_H * result_d[1]{0}; volt_H_SIF_2 = filter_H * result_d[2]{0}; curr_H_SIF_2 = filter_H * result_d[3]{0}; volt_H_SIF_3 = filter_H * result_d[4]{0}; curr_H_SIF_3 = filter_H * result_d[5]{0}; // result_d = ConfigurationReaderWarm("name_confilfpu",["sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,lo_freq); volt_V_SIF_1 = filter_V * result_d[0]{0}; curr_V_SIF_1 = filter_V * result_d[1]{0}; volt_V_SIF_2 = filter_V * result_d[2]{0}; curr_V_SIF_2 = filter_V * result_d[3]{0}; volt_V_SIF_3 = filter_V * result_d[4]{0}; curr_V_SIF_3 = filter_V * result_d[5]{0}; // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(1200); // //4. Do action corresponding to IF1 on: All FIF parameters are set // result_d = ConfigurationReaderWarm("name_confilfpu",["fif1v_h","fif1c_h","fif2v_h","fif2c_h"],band,lo_freq); volt_H_FIF_1 = filter_H * result_d[0]{0}; curr_H_FIF_1 = filter_H * result_d[1]{0}; volt_H_FIF_2 = filter_H * result_d[2]{0}; curr_H_FIF_2 = filter_H * result_d[3]{0}; // result_d = ConfigurationReaderWarm("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v"],band,lo_freq); volt_V_FIF_1 = filter_V * result_d[0]{0}; curr_V_FIF_1 = filter_V * result_d[1]{0}; volt_V_FIF_2 = filter_V * result_d[2]{0}; curr_V_FIF_2 = filter_V * result_d[3]{0}; // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(1200); // //5. Magnet current to max. if(band_nb <= 5) { result_d = ConfigurationReaderWarm("name_confilfpu",["magnet_current_max_v","magnet_current_max_h"],band,lo_freq); magnetcurrent_H = filter_H * result_d[1]{0}; magnetcurrent_V = filter_V * result_d[0]{0}; // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(5); //Set to targetted values magnetcurrent_H = filter_H * target_magn_h; magnetcurrent_V = filter_V * target_magn_v; // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(600); } // //6. Bias voltage to dedicated value for thermal test bias_H = filter_H * target_mbias_h; bias_V = filter_V * target_mbias_v; // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(600); // //7. Bias voltage back to null bias_H = 0.0; bias_V = 0.0; HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(600); // //8. Magnet current back to null if(band_nb <= 5) { magnetcurrent_H = 0.0; magnetcurrent_V = 0.0; HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(600); } // //9. Do action corresponding to IF1 off: FIF parameters are set to standby // result_d = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],"0",0.0); // volt_H_FIF_1 = result_d[1]{0}; curr_H_FIF_1 = result_d[2]{0}; volt_H_FIF_2 = result_d[3]{0}; curr_H_FIF_2 = result_d[4]{0}; // {double,string}[] result_d2 = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],"0",0.0); // volt_V_FIF_1 = result_d2[0]{0}; curr_V_FIF_1 = result_d2[1]{0}; volt_V_FIF_2 = result_d2[2]{0}; curr_V_FIF_2 = result_d2[3]{0}; // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(1200); // //10. Do action corresponding to IF2 off: SIF parameters are set to standby // volt_H_SIF_1 = result_d[5]{0}; curr_H_SIF_1 = result_d[6]{0}; volt_H_SIF_2 = result_d[7]{0}; curr_H_SIF_2 = result_d[8]{0}; volt_H_SIF_3 = result_d[9]{0}; curr_H_SIF_3 = result_d[10]{0}; // volt_V_SIF_1 = result_d2[4]{0}; curr_V_SIF_1 = result_d2[5]{0}; volt_V_SIF_2 = result_d2[6]{0}; curr_V_SIF_2 = result_d2[7]{0}; volt_V_SIF_3 = result_d2[8]{0}; curr_V_SIF_3 = result_d2[9]{0}; // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(1200); // //11. Diplexer back to null if(band_nb <= 2 || band_nb == 5) { //No action } else { diplex_H = 0.0; diplex_V = 0.0; // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); delay(300); } //12. Check heater current effect on temperature: Let current ON // during the standard deflux time. //We will bias the junction to check when //the heater effect is effective result_d = ConfigurationReaderWarm("name_confilfpu",["bias_very_low_h","bias_very_low_v"],band,lo_freq); bias_H = filter_H * result_d[0]{0}; bias_V = filter_V * result_d[1]{0}; Mixerbias(bias_H,bias_V); // //Get time during which one wants to send the pulse double max_heater_time_h = target_heat_h * 1000.0; //in msec double max_heater_time_v = target_heat_v * 1000.0; //in msec //Start to send the pulse //Comment: Hifi_HIFI_Set_SIS_heaters($BBID,max_heater_time_h,max_heater_time_v); //This command is not yet available, so we use single_commands // if(polar == "H") { Hifi_HIFI_HF_CH1_DHTR_C($BBID,max_heater_time_h); delay(iceil(max_heater_time_h / 1000.0) + 1); } else { Hifi_HIFI_HF_CV1_DHTR_C($BBID,max_heater_time_v); delay(iceil(max_heater_time_v / 1000.0) + 1); } // //13. Heater back to 0: it is done by essence after SIS_heater is complete. //Extra delay to cool down delay(600); // } {string,double,double}[] procedure HifiMappingModeDBSCrossSequencerInit { string modeName = "cross"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_switch_on = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode // inherit from dbs-raster mode {string,double,double}[] retvalues = HifiMappingProcDBSRasterSequencerInit(naifid,ra,dec,{0.0,double(npoints / 2) * stepsize},2,stepsize,npoints,band,lo_freq,effResolution,continuumDetection,oneGHzReference,hrs1,hrs2,wbs1,wbs2,data_time,n_switch_on,n_pointsperscan,n_cycles,load_interval,docommands); return retvalues; } // // Chopper scan, block (IF power as function of chopper position) block Chopper_scan_fm HIFI 3260 { string band = "1a"; // HIFI band double chopper_pos_min = -7.0; //minimum chopper position double chopper_pos_max = 8.0; //maximum chopper position int n_steps = 300; //number of steps int integ_time = 4; //Total integration time in sec.: at least 2sec ! string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string chopmode = "tp" in ["tp","slowchop","fastchop"]; //modulation mode between hot/cold: tp, slowchop, fastchop int n_wbs1 = 20; int n_hrs_trans = 1; bool ref_position = false; //Do we take a reference spectrum every 100sec ? bool shutter_used = false; string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3 double chop_phase = 1.0 in [0.2,2.0]; // Chop phase length }{ Start_block(); // int steps = 0; int steps_done = 0; int steps_wanted = n_steps; if(steps_wanted < 1) { steps_wanted = 1; } double chopper_pos = 0.0; double stepsize = 0.0; if(steps_wanted > 1) { stepsize = (chopper_pos_max - chopper_pos_min) / (double(steps_wanted) - 1.0); } //Move first half way to the first scanned position to //avoid hitting the end stop double intermediate_chopper_pos = (chopper_pos_max + chopper_pos_min) / 2.0; intermediate_chopper_pos = Check_Chopper_Prime_Redundant(intermediate_chopper_pos); HIFI_CPR_Chopper_Rot_proc_fm(intermediate_chopper_pos); //Rotate chopper Hifi_HIFI_non_periodic_hk_FCU(); //To get sent voltage delay(1); // int start_stamp = time(); int elapsed_time = 0; while(steps_done < steps_wanted) { steps = steps_wanted - steps_done; if(steps > n_steps) { steps = n_steps; } chopper_pos = chopper_pos_min + double(steps_done) * stepsize; if(chopper_pos > 8.5) { chopper_pos = 8.5; //Cannot go over 8.5 Volts } //Start scan //If shutter is not used, we chop against the middle of the scan span double chopper_pos_middle = 0.5 * (chopper_pos_min + chopper_pos_max); //If shutter is used, we chop against M3 middle if(shutter_used) { {double,string}[] result_d = ConfigurationReader("name_confilfpu",["chop_M3"],band,0.0); chopper_pos_middle = result_d[0]{0}; } //Acquire spectrum: check which spectroscopic mode in use //Compute data-rate double[] rates = ILT_datarate_proc_fm(band,backend,chopmode,integ_time); //Total power case if(chopmode == "tp") { chopper_pos = Check_Chopper_Prime_Redundant(chopper_pos); HIFI_CPR_Chopper_Rot_proc_fm(chopper_pos); //Rotate chopper Hifi_HIFI_non_periodic_hk_FCU(); //To get sent voltage delay(1); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); //Get spectrum // //Additional delay to work-around problem with SCOS jitter, see SPR-1109 delay(1); //Check whether an additional spectrum on initial position needs to be taken elapsed_time = time() - start_stamp; if(ref_position) { if(elapsed_time >= 100) { chopper_pos_min = Check_Chopper_Prime_Redundant(chopper_pos_min); HIFI_CPR_Chopper_Rot_proc_fm(chopper_pos_min); //Rotate chopper to initial scan position Hifi_HIFI_non_periodic_hk_FCU(); //To get sent voltage delay(1); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); //Get spectrum // start_stamp = time(); } } } if(chopmode == "slowchop") { // set data rates non_ess_hk_data_rate(rates[2] / 1024.0); data_rate(rates[0] / 1024.0); // HIFI_Spectr_slow_chop_proc_fm(chopper_pos_middle,chopper_pos); Apply_Slow_Chop_delay(integ_time,band,backend); //Additional delay to work-around problem with SCOS jitter, see SPR-1109 delay(1); // reset data rates non_ess_hk_data_rate(rates[1] / 1024.0); data_rate(0.0); } if(chopmode == "fastchop") { // set data rates non_ess_hk_data_rate(rates[2] / 1024.0); data_rate(rates[0] / 1024.0); // HIFI_Spectr_fast_chop_proc_fm(chopper_pos_middle,chopper_pos,n_wbs1,n_hrs_trans); Apply_Fast_Chop_delay(integ_time,1,band,backend); //Additional delay to work-around problem with SCOS jitter, see SPR-1109 delay(1); // reset data rates non_ess_hk_data_rate(rates[1] / 1024.0); data_rate(0.0); } // steps_done = steps_done + 1; } } //HIFI-COP-2.3-Param-Scan for total time calculation procedure Parameter_Scan_MOIS_proc_ops { int index = 1 in [1,7]; // Test case index as of config_paramscan_COP.config int phase = 1 in [1,2]; //Measurement phase int integ_time = 4; //Integration time PER PHASE for the Tsys slowchop measurement string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code bool config_only = true; //whether we only configure ("true") or run also Stab and Tsys }{ int start = time(); // //Read all band+param to perform string tab = "config_paramscan_COP.config"; int total = table_size(tab); double lo_freq = dlookup(tab,"" + index,"lofreq"); string band = slookup(tab,"" + index,"band"); double m1_min = dlookup(tab,"" + index,"m1_1"); double m1_max = dlookup(tab,"" + index,"m1_2"); double m1_step = dlookup(tab,"" + index,"m1_step"); double m2_min = dlookup(tab,"" + index,"m2_1"); double m2_max = dlookup(tab,"" + index,"m2_2"); double m2_step = dlookup(tab,"" + index,"m2_step"); double bias_min = dlookup(tab,"" + index,"bias_1"); double bias_max = dlookup(tab,"" + index,"bias_2"); double bias_step = dlookup(tab,"" + index,"bias_step"); double imix_min = dlookup(tab,"" + index,"imix_1"); double imix_max = dlookup(tab,"" + index,"imix_2"); double imix_step = dlookup(tab,"" + index,"imix_step"); double m1 = 0.0; double m2 = 0.0; double bias = 0.0; double imix = 0.0; mois_comment("Parametric scan investigation in band " + band + " at " + lo_freq + " GHz"); mois_comment("Execution of this procedure requires use of dedicated TPF files"); //General parameters for spectroscopy string backend = "both"; string chopmode = "slowchop"; double sampling_rate = 3.0; //Sampling rate: 2 (2 HRS-H + 2 HRS-V), 4 (HRS-H + HRS-V, 2 HRS-H or 2 HRS-V) or 8 (1 HRS-H or 1 HRS-V) Hz double hrs_h_1 = 7.4; //Position in IF of HRS-H sub-band 1 double hrs_h_2 = 7.4; //Position in IF of HRS-H sub-band 2 double hrs_v_1 = 7.4; //Position in IF of HRS-V sub-band 1 double hrs_v_2 = 7.4; //Position in IF of HRS-V sub-band 2 double[] hrs_subband = [hrs_h_1,hrs_h_2,hrs_v_1,hrs_v_2]; string hrs_polarization = "B"; //HRS polarization: selection works only for 4 and 8 Hz int n = 1466; //Switch-on LO mois_step("LO switch-on"); LCU_switchon_proc_fm(band); //Wait an extra delay of 1 min for short term stabilization delay(60); // //FPU configuration mois_step("FPU configuration"); Init_MSA_HBB_fm(band,"CLOSE",lo_freq,"ON"); //Phase 1 measurement: loop on M1 and M2 mois_step("Start loop on multipliers"); string name_configlcu = "name_configlcu_b"; // if(phase == 1) { m1 = m1_min; //Loop on M1 while(m1 <= m1_max) { //Loop on m2: cancelled for the moment - SCR-2460 m2 = m2_min; while(m2 <= m2_max) { // //Implementation of SCR-2460: for the time being, M2 is fixed to its nominal value - no scan {double,string}[] result = ConfigurationReader(name_configlcu,["m2_v"],band,lo_freq); //m2 = result[0]{0}; //Tune LO at standard target LO_tuning_w_M1M2_block_fm(band,lo_freq,m1,m2); message(band + ", " + lo_freq + ", " + m1 + ", " + m2); // if(config_only == false) { //Do stab and Tsys as well //Tsys measurement WBS_calib_fm(band); WBS_tune_proc_fm(band); HRS_config_block_fm(band,["wb1","wb1"]); HRS_tune_block_fm(band); //Configure spectroscopy for slowchop hotcold int[] res = Configure_Spectrometer_hc_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); int total_time = res[0] * res[1]; Hot_cold(band,hrs_mode,backend,total_time,chopmode,0,0); // //HRS fast stability measurment Stability_fast_proc_fm(band,n,hrs_subband,sampling_rate,hrs_polarization); // } m2 = m2 + m2_step; } //end loop m2 m1 = m1 + m1_step; } //end loop M1 } //Phase 2 measurement: loop on bias and Imix if(phase == 2) { //Configure at nominal M1,M2 (i.e. they are in the LCU safety table release) LCU_config_nominal_proc_fm(band,lo_freq); imix = imix_min; //Loop on Imix while(imix <= imix_max) { //Loop on bias bias = bias_min; while(bias <= bias_max) { // //Apply biases //In case of band 6 or 7, go via max first if(band == "7b") { result = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,lo_freq); //First go to 4mV Mixerbias_block_fm(result[0]{0},result[1]{0}); //Then to nominal Mixerbias_block_fm(bias,bias); } // //Tune LO at dedicated target (use of H mixer) LO_tuning_w_targetC_block_fm(imix / 1000.0,band,lo_freq,"H"); // //Tsys measurement WBS_calib_fm(band); WBS_tune_proc_fm(band); HRS_config_block_fm(band,["wb1","wb1"]); HRS_tune_block_fm(band); //Configure spectroscopy for slowchop hotcold res = Configure_Spectrometer_hc_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); total_time = res[0] * res[1]; Hot_cold(band,hrs_mode,backend,total_time,chopmode,0,0); // //HRS fast stability measurment Stability_fast_proc_fm(band,n,hrs_subband,sampling_rate,hrs_polarization); // bias = bias + bias_step; } //end loop bias imix = imix + imix_step; } //end loop imix } } // get backend resolution and effective noise resolution double[] procedure GetBackendResolution { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency int res_mode = 0; // coding for the backend resolution mode }{ if(res_mode < 0 || res_mode > 3) { double[] resol = CalibrationReader("backendresolution",["wbs_resolution","wbs_fluct_ratio"],band,lo_freq); } if(res_mode == 0) { resol = CalibrationReader("backendresolution",["hrs_high_resolution","hrs_fluct_ratio"],band,lo_freq); } if(res_mode == 1) { resol = CalibrationReader("backendresolution",["hrs_normal_resolution","hrs_fluct_ratio"],band,lo_freq); } if(res_mode == 2) { resol = CalibrationReader("backendresolution",["hrs_low_resolution","hrs_fluct_ratio"],band,lo_freq); } if(res_mode == 3) { resol = CalibrationReader("backendresolution",["hrs_wide_resolution","hrs_fluct_ratio"],band,lo_freq); } return resol; } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the DBS raster mode procedure JupiterDBSRaster_commanding { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // chunk size int n_seq = 1; // Number of continuous chop cycles int n_cycles = 1; // Number of half OFF-ON-ON-OFF cycles int n_pointsperscan = 1; // Number of points measured before moving to the second pointing phase int n_loadinterval = 10; // number of nods before a load measurement int n_load = 0; // additional load measurements in one pointing phase bool final_load = false; // Need for final load measurement int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,10,0,10,20,21,0,0,0]; // Timing of the observation from telescope int loadlength = 21; // Load duration bool iscross = false; // Whether we use a cross instead of a raster }{ // Auxiliary variables // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Get all values from the telescope section int tinitslew = telescopetimes[1]; // Initial slew time //////////////////////////////////////////////////////////////////////// // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // // Clustering is currently not implemented in MPS - switched off here int clustered = 0; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] rates = dataparms{1}; int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); // Count phases by hand to allow simultaneous usage by Raster and Cross int iphase = 0; // There is no nod counter in the return values - count this by hand int inod = 0; // Do I have to make loads in short nods and subsequent holds? if(iscross) { bool holdforload = n_pointsperscan > 1; } else { holdforload = n_pointsperscan == 1 && n_loadinterval > n_cycles; } bool isOffAtPoint = false; //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; bool runintostate = false; while(state[0] >= 0) { if(runintostate) { state = next_state_no_check(); } else { state = next_state(); } if(state[0] == 1) { // Initialization if(clustered != 1) { HIFIInitObs(); TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"jupiter"); } delay(tinitslew - (time() - startobs) - loadlength - hkduration); // First load measurement HIFISetHK("normal",false); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); runintostate = false; iphase = iphase + 1; } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 3) { // First nodding position // Check whether we are in a cross mode using computed OFF isOffAtPoint = iscross && inod % 2 == 0; // Configure measurement HIFIConfigureSlowChopIntegration(data_time,n_seq,band,lo_freq,backendreadoutparms); // Loop for load cycles // The use of n_load differs by 1 from the other observing modes here for(int i1 = 1 .. n_load - 1) { if(isOffAtPoint) { HIFISlowChopOffIntegration(data_time,n_seq,band,lo_freq,rates); } else { HIFISlowChopOnIntegration(data_time,n_seq,band,lo_freq,rates); } // Perform load calibration delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); HIFIConfigureSlowChopIntegration(data_time,n_seq,band,lo_freq,backendreadoutparms); } // Last cycle if(isOffAtPoint) { HIFISlowChopOffIntegration(data_time,n_seq,band,lo_freq,rates); } else { HIFISlowChopOnIntegration(data_time,n_seq,band,lo_freq,rates); } // Load measurement if required - time included in pointing if(n_load > 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } // Final point before nod // Special treatment for all cases where load has to be replaced by hold: // n_pointsperscan=1, n_loadinterval > n_cycles if(iphase % n_pointsperscan == 0 && iphase / n_pointsperscan % 2 == 1) { inod = inod + 1; if(holdforload && inod % n_loadinterval == 0 && n_load == 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); runintostate = true; } } else { // keep shift if we come from a holdforload nod, otherwise reset if(!holdforload) { runintostate = false; } } // Update phase counter iphase = iphase + 1; } // Second pointing phase if(state[0] == 7) { // second nod position HIFIConfigureSlowChopIntegration(data_time,n_seq,band,lo_freq,backendreadoutparms); for(int i2 = 1 .. n_load - 1) { HIFISlowChopOffIntegration(data_time,n_seq,band,lo_freq,rates); // Perform load calibration delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); HIFIConfigureSlowChopIntegration(data_time,n_seq,band,lo_freq,backendreadoutparms); } // Last cycle HIFISlowChopOffIntegration(data_time,n_seq,band,lo_freq,rates); // Load measurement if required - time included in pointing if(n_load > 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } // Final point before nod // Special treatment for all cases where load has to be replaced by hold: if(iphase % n_pointsperscan == 0 && iphase / n_pointsperscan % 2 == 1) { inod = inod + 1; if(holdforload && inod % n_loadinterval == 0 && n_load == 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); runintostate = true; } } else { // keep shift if we come from a holdforload nod, otherwise reset if(!holdforload) { runintostate = false; } } // Update phase counter iphase = iphase + 1; } // Load nod if(state[0] == 9) { // Load nod delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); runintostate = false; } // Hold if(state[0] == 6) { // finished shift of instrument operations relative to pointing command runintostate = false; } // Final load if(state[0] == 5) { delay(readoutdead); if(final_load) { // Perform final load measurement LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } runintostate = false; HIFICloseObs(); } } } // Stability test, procedure // Measurement of internal cold in FSW mode // this is the CBB counterpart - no LOU retune involved procedure Proc_stability_freqswitch_COP_CBB { string band = "1a"; // HIFI band double lo_freq = 522.0; //The LO frequency double freq_throw = 50.0; //The frequency throw in MHz int n = 100; //Number of load pairs to be measured string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int integ_time = 4; //Total (co-added) integration time of a phase in sec. string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ // Chopper_Rotation_block_fm(band,"chop_M3_ang","chop_cold_ang"); //Look at M3 // //Tune backends if(backend == "hrs" || backend == "both" || backend == "hrsFast") { HRS_tune_block_fm(band); } if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { //WBS calibration WBS_calib_fm(band); WBS_tune_proc_fm(band); } // Stability_freqswitch_fm(band,n,integ_time,hrs_mode,backend); //Configure spectrometers integration back to default in tp mode Configure_Spectrometer_proc_fm(band,4,hrs_mode,backend); //2 sec. integration } //////////////////////////////////// // Fast chop DBS raster observing mode - special version for Jupiter // // Return time and noise levels {int,double,double,double,double,double} obs HifiMappingProcJupiterFastDBSRaster { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source {double,double} lineDistance = {0.0050,0.0050}; // Distance between subsequent rows int nlines = 1 in [1,100]; // Number of rows in the map double stepsize = 0.0050 in [5.5556E-4,0.13333]; // Distance between subsequent points in the raster line int npoints = 10 in [2,100]; // Number of points per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 10 in [4,80]; // data dump interval int n_int_on = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_switch_on = 1 in [1,1800]; // number of data transfer cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Engineering - Jupiter - DBS Raster Map fastChop",{data_time,0,n_int_on,n_switch_on,0,0,n_pointsperscan,0,n_cycles,load_interval}); // Call first part of the timing computer // Two changes relative to the normal DBS raster // 1) The longer load duration is enforced by zero resolution {double,double} loadResolution = {0.0,effResolution{1}}; // 2) I assume that the tuning duration does not depend on the tuning level // so that the normal pre_timing can be reused. {int,int,int,int,int,int,int,int,int,int,int,int,int} pre_timing = FastDBSRaster_pre_timing(nlines,npoints,band,lo_freq,loadResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_switch_on,n_pointsperscan,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; // Check for NoddingInRaster or NoddingOfRaster int scansize = pre_timing{10}; if(scansize > 1) { {int,int,int,string,int,double,double,bool,double,double,double,int,int,double,double,int,int,double,double,int,int,int,int,int} tmpar = DBSMultiRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",pre_timing,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = nodding_of_raster_pointing(false,tmpar{0},tmpar{1},tmpar{2},tmpar{3},tmpar{4},tmpar{5},tmpar{6},tmpar{7},tmpar{8},tmpar{9},tmpar{10},tmpar{11},tmpar{12},tmpar{13},tmpar{14},tmpar{15},tmpar{16},tmpar{17},tmpar{18},tmpar{19},tmpar{20},tmpar{21},tmpar{22},tmpar{23}); } else { {int,int,int,string,int,double,double,bool,double,double,double,int,int,double,double,int,int,int,double,double,int,int,int,double,double,int,int,int,int} tpar = DBSRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",pre_timing,n_cycles); telescopetimes = nodding_raster_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23},tpar{24},tpar{25},tpar{26},tpar{27},tpar{28}); } ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,int},bool,double,double} post_timing = DBSRaster_post_timing(pre_timing,telescopetimes,nlines,npoints,n_switch_on,n_cycles,load_interval,true); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command if(scansize > 1) { tmpar = DBSMultiRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",post_timing{1},n_cycles); // Call telescope command telescopetimes = nodding_of_raster_pointing(true,tmpar{0},tmpar{1},tmpar{2},tmpar{3},tmpar{4},tmpar{5},tmpar{6},tmpar{7},tmpar{8},tmpar{9},tmpar{10},tmpar{11},tmpar{12},tmpar{13},tmpar{14},tmpar{15},tmpar{16},tmpar{17},tmpar{18},tmpar{19},tmpar{20},tmpar{21},tmpar{22},tmpar{23}); } else { tpar = DBSRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",post_timing{1},n_cycles); telescopetimes = nodding_raster_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23},tpar{24},tpar{25},tpar{26},tpar{27},tpar{28}); } // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{3}; int n_load = post_timing{1}{6}; int n_loadinterval = post_timing{1}{7}; int n_seq = post_timing{1}{8}; int initlength = post_timing{1}{11}; int dangling = post_timing{1}{12}; bool final_load = post_timing{2}; double tscan = post_timing{3}; double tdead = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { JupiterFastDBSRaster_commanding(band,lo_freq,loadResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_seq,n_cycles,scansize,n_loadinterval,n_load,final_load,startobs,telescopetimes,loadlength,false); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double} tact = FastDBSRaster_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_seq,n_load,scansize,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = DBS_noisecomputer(band,lo_freq,effResolution,continuumDetection,oneGHzReference,n_cycles,tscan,tact); // Evaluate performance DBSRaster_performance(band,lo_freq,effResolution,noisevalues,timeTaken,nlines,npoints,n_cycles,n_seq * n_int_on * imax(n_load,1),tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } //Single magnet scan procedure Magnet_scan { string band = "1a"; // HIFI band double magnet_min_h = -10.0; // min magnet current double magnet_max_h = 15.0; // max magnet current int step_count_h = 10; // number of steps double step_duration = 0.1; // step duration double bias_h = 1.8; // bias voltage double magnet_min_v = -10.0; // min magnet current double magnet_max_v = 15.0; // max magnet current int step_count_v = 10; // number of steps double bias_v = 1.8; // bias voltage }{ int nbias = 1; if(step_duration > 0.15) { nbias = 2; } if(step_duration > 0.25) { nbias = 4; } if(step_duration > 0.45) { nbias = 5; } if(step_duration > 0.6) { nbias = 8; } if(step_duration > 0.7) { nbias = 10; } if(step_duration > 1.4) { nbias = 20; } int max_per_command = 40; int maxsteps = max_per_command / nbias; int steps = 0; int steps_done = 0; //We take the finest step possible double magnet_min = max(magnet_min_h,magnet_min_v); double magnet_max = min(magnet_max_h,magnet_max_v); int step_count = iround(max(double(step_count_h),double(step_count_v))); // double step = Stepsize(magnet_min,magnet_max,step_count,"hifi_HIF_mx_mg_step_C"); double margin = Stepmargin(magnet_min,magnet_max,"hifi_HIF_mx_mg_step_C"); int steps_wanted = 1 + iceil((magnet_max - magnet_min) / step); // force the last portion to less than maxsteps if(maxsteps * (steps_wanted / maxsteps) == steps_wanted) { steps_wanted = steps_wanted - 1; } // //Set magnet to maximum to avoid hysteresis {double,string}[] result = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,0.0); double magnet_current_max_h = result[0]{0}; double magnet_current_max_v = result[1]{0}; Hifi_HIFI_CH1_MX_MG_C($BBID,magnet_current_max_h); Hifi_HIFI_CV1_MX_MG_C($BBID,magnet_current_max_v); delay(1); // double magnet_current_h = 0.0; double magnet_current_v = 0.0; int duration_scan = 0; //Start scan: from max. to min. magnet downward. while(steps_done < steps_wanted) { steps = steps_wanted - steps_done; if(steps > maxsteps) { steps = maxsteps; } magnet_current_h = magnet_max_h - double(steps_done) * step; magnet_current_v = magnet_max_v - double(steps_done) * step; Hifi_HIFI_FCU_parameter_scan($BBID,nbias,steps,0.1,bias_h,bias_v,0.0,magnet_current_h,magnet_current_v,step + margin); duration_scan = iceil(double(steps * nbias) * 0.1); delay(duration_scan + 2); steps_done = steps_done + steps; } } // Chopper Response time with all possible combinations, block // Due to current PTV restriction, need to go the starting // position also via an engineering scan TC block Chopper_Response_time_block_COP HIFI 3787 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band int milliSecSample = 3; // interval between samples int samplesBefore = 30 in [0,50]; int samplesAfter = 1000 in [0,1000]; string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ //Start_block(); // //We assume starting from HBB. //1. response time to go from HBB to CBB //Get cold position {double,string}[] result_d = ConfigurationReader("name_confilfpu",["chop_cold"],band,0.0); double targetAngle = result_d[0]{0}; Engineering_scan_for_chopper_rotation_COP(targetAngle,milliSecSample,samplesBefore,samplesAfter,prime_or_redundant); // //2. response time to go from CBB to M3 middle result_d = ConfigurationReader("name_confilfpu",["chop_M3"],band,0.0); targetAngle = result_d[0]{0}; Engineering_scan_for_chopper_rotation_COP(targetAngle,milliSecSample,samplesBefore,samplesAfter,prime_or_redundant); // //3. response time to go from M3 middle to CBB result_d = ConfigurationReader("name_confilfpu",["chop_cold"],band,0.0); targetAngle = result_d[0]{0}; Engineering_scan_for_chopper_rotation_COP(targetAngle,milliSecSample,samplesBefore,samplesAfter,prime_or_redundant); // //4. response time to go from CBB to HBB result_d = ConfigurationReader("name_confilfpu",["chop_hot"],band,0.0); targetAngle = result_d[0]{0}; Engineering_scan_for_chopper_rotation_COP(targetAngle,milliSecSample,samplesBefore,samplesAfter,prime_or_redundant); // //5. response time to go from HBB to M3 left result_d = ConfigurationReader("name_confilfpu",["chop_M3left"],band,0.0); targetAngle = result_d[0]{0}; Engineering_scan_for_chopper_rotation_COP(targetAngle,milliSecSample,samplesBefore,samplesAfter,prime_or_redundant); // //6. response time to go from M3 left to M3 right result_d = ConfigurationReader("name_confilfpu",["chop_M3right"],band,0.0); targetAngle = result_d[0]{0}; Engineering_scan_for_chopper_rotation_COP(targetAngle,milliSecSample,samplesBefore,samplesAfter,prime_or_redundant); // //7. response time to go from M3 right to M3 left result_d = ConfigurationReader("name_confilfpu",["chop_M3left"],band,0.0); targetAngle = result_d[0]{0}; Engineering_scan_for_chopper_rotation_COP(targetAngle,milliSecSample,samplesBefore,samplesAfter,prime_or_redundant); // } //Generic procedure to send chopper angle using the adequate instrument side procedure HIFI_CPR_Chopper_Rot_RAW_proc_fm { int targetAngle = 0; // HF_CPR_Chopper_Rot }{ //check prime or redundant keyword {double,string}[] result_d = ConfigurationReader("name_chopper",["prime_or_redundant"],"0",0.0); if(result_d[0]{1} == "prime") { Hifi_HIFI_P_Chopper_Rot_RAW($BBID,targetAngle); } else { Hifi_HIFI_R_Chopper_Rot_RAW($BBID,targetAngle); } } //LO parameter scan without HotCold measurement //for Band 5a procedure LCU5a_power_scan_without_Tsys { string band = "5a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4 double lo_freq = 1150.0 in [1127.0,1178.0]; //LO frequency double param_min = 1.0; //Min. of scanned parameter double param_max = 2.0; //Max. of scanned parameter double step_size = 0.1; //Step size string param_name = "D2"; //Code of scanned parameter: M1,M2,G1,G2,D1,D2. }{ error("This module is obsolete: use LCU_power_scan_without_Tsys instead"); } // Frequency switch procedure HIFI_Spectr_fswitch_proc_aot { int data_time = 4; // Integration time between two data readouts int n_cycle = 1; // chop cycle number string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double[] rates = [120.0,1.0,2.0]; // Data rates between and during integrations }{ // set data rates non_ess_hk_data_rate(rates[2] / 1024.0); data_rate(rates[0] / 1024.0); // Call command Hifi_HIFI_Spectr_freq_switch($BBID); delay(2 * n_cycle * data_time); // reset data rates non_ess_hk_data_rate(rates[1] / 1024.0); data_rate(0.0); } //Contingency for LOU temp FDIR modification mode HifiManCmd_Dump_7AH_page { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! }{ mois_comment("Procedure to dump the LCU memory at page 7AH"); //StartMode_block_ops(); // mois_step("Send memory dump command"); Dump_7AH_page_block_mois(); // StopMode_block_ops(); // -> to issue last obsd/bbid } //////////////////////////////////// // Fast chop DBS raster - cross observing mode // // Return time and noise levels {int,double,double,double,double,double} obs HifiMappingProcFastDBSCross { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source double stepsize = 0.0050 in [5.5556E-4,0.13333]; // Distance between subsequent points in the two raster lines int npoints = 10 in [2,100]; // Number of points per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 10 in [4,80]; // data dump interval int n_int_on = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_switch_on = 1 in [1,1800]; // number of data transfer cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Mapping - DBS Cross Map fastChop",{data_time,0,n_switch_on,n_int_on,0,0,n_pointsperscan,0,n_cycles,load_interval}); // Call first part of the timing computer {int,int,int,int,int,int,int,int,int,int,int,int,int} pre_timing = FastDBSRaster_pre_timing(2,npoints,band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_switch_on,n_pointsperscan,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,bool,double,double,double,double[],double[],int[],double,double,int,int,int,int,int,int} tpar = DBSCross_telescope(naifid,onPosition,stepsize,npoints,band,lo_freq,"",pre_timing,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = custom_map_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21}); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,int},bool,double,double} post_timing = DBSCross_post_timing(pre_timing,telescopetimes,npoints,n_switch_on,n_cycles,load_interval,true); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = DBSCross_telescope(naifid,onPosition,stepsize,npoints,band,lo_freq,"",post_timing{1},n_cycles); telescopetimes = custom_map_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21}); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{3}; int n_load = post_timing{1}{6}; int n_loadinterval = post_timing{1}{7}; int n_seq = post_timing{1}{8}; int scansize = post_timing{1}{10}; int initlength = post_timing{1}{11}; int dangling = post_timing{1}{12}; bool final_load = post_timing{2}; double tscan = post_timing{3}; double tdead = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { FastDBSRaster_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_seq,n_cycles,scansize,n_loadinterval,n_load,final_load,startobs,telescopetimes,loadlength,true); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double} tact = FastDBSRaster_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_seq,n_load,scansize,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = DBS_noisecomputer(band,lo_freq,effResolution,continuumDetection,oneGHzReference,n_cycles,tscan,tact); // Evaluate performance DBSRaster_performance(band,lo_freq,effResolution,noisevalues,timeTaken,2,npoints,n_cycles,n_seq * n_int_on * imax(n_load,1),tact); // Correct for double counting of central point // The central point is returned only double multiplier = sqrt(0.5); noisevalues{0} = noisevalues{0} * multiplier; noisevalues{1} = noisevalues{1} * multiplier; noisevalues{2} = noisevalues{2} * multiplier; noisevalues{3} = noisevalues{3} * multiplier; noisevalues{4} = noisevalues{4} / multiplier; // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // Needs the chopper in open-loop mode !! block Chopper_openloop_set_block_ops HIFI 7693 { int position = 0 in [0,1]; string prime_or_redundant = "Prime" in ["Prime","Redundant"]; //Prime or Red }{ int rot = 2048 + 70 * position; mois_step("Moving chopper to position " + rot + " in RAW units"); //Prime/Red has no effect on RAW to send, only to the TC name if(prime_or_redundant == "Prime") { Hifi_HIFI_P_Chopper_Rot_RAW($BBID,rot); } else { Hifi_HIFI_R_Chopper_Rot_RAW($BBID,rot); } Hifi_HIFI_non_periodic_hk_FCU(); //To get sent value mois_tmcheck("Check that parameter HF_DPR_CH_ROT is set to " + rot + " in RAW units"); delay(2); } //////////////////////////////////// // Error reporting functions - containing some standard text procedure CError { string errormessage = "Inconsistency detected."; // Error message }{ string fullmessage = "Internal HIFI observing mode error:
" + errormessage + "
Please, report this error together with the AOR file to the " + "Herschel Science Centre Helpdesk."; // To be replaced by a link to the SPR system when this can handle AOR files error(fullmessage); } // Auxiliary routine to check for bad map sizes // procedure CheckReasonableLineNumber { int nlines = 1; // Number of OTF lines in a map bool isOtf = true; // whether this is an OTF of a raster map }{ // Give warning in case of "bad" map sizes // Here is a very bad place to make the test - it should rather go to HSPOT int divisors = 0; int[] divlist = [2,3,4,5]; for(int idiv = 0 .. 3) { if(nlines % divlist[idiv] == 0) { divisors = divisors + 1; } } if(nlines > 10 && divisors < 2 || nlines > 6 && divisors < 1) { if(isOtf) { message("Warning: The map contains " + nlines + " lines. " + "This cannot be split efficiently into equal scans of " + "multiple lines. Try to change your map size.
"); } else { message("Warning: The map contains " + nlines + " points. " + "This cannot be split efficiently into equal scans of " + "multiple points.Try to change your map size.
"); } } } // Chopper Response time with all possible combinations, block // Due to current PTV restriction, need to go the starting // position also via an engineering scan TC block Chopper_Response_time_block_fm HIFI 3687 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band int milliSecSample = 3; // interval between samples int samplesBefore = 30 in [0,50]; int samplesAfter = 1000 in [0,1000]; }{ Start_block(); // //We assume starting from HBB. //1. response time to go from HBB to CBB //Get cold position {double,string}[] result_d = ConfigurationReader("name_confilfpu",["chop_cold"],band,0.0); double targetAngle = result_d[0]{0}; Engineering_scan_for_chopper_rotation(targetAngle,milliSecSample,samplesBefore,samplesAfter); // //2. response time to go from CBB to M3 middle result_d = ConfigurationReader("name_confilfpu",["chop_M3"],band,0.0); targetAngle = result_d[0]{0}; Engineering_scan_for_chopper_rotation(targetAngle,milliSecSample,samplesBefore,samplesAfter); // //3. response time to go from M3 middle to CBB result_d = ConfigurationReader("name_confilfpu",["chop_cold"],band,0.0); targetAngle = result_d[0]{0}; Engineering_scan_for_chopper_rotation(targetAngle,milliSecSample,samplesBefore,samplesAfter); // //4. response time to go from CBB to HBB result_d = ConfigurationReader("name_confilfpu",["chop_hot"],band,0.0); targetAngle = result_d[0]{0}; Engineering_scan_for_chopper_rotation(targetAngle,milliSecSample,samplesBefore,samplesAfter); // //5. response time to go from HBB to M3 left result_d = ConfigurationReader("name_confilfpu",["chop_M3left"],band,0.0); targetAngle = result_d[0]{0}; Engineering_scan_for_chopper_rotation(targetAngle,milliSecSample,samplesBefore,samplesAfter); // //6. response time to go from M3 left to M3 right result_d = ConfigurationReader("name_confilfpu",["chop_M3right"],band,0.0); targetAngle = result_d[0]{0}; Engineering_scan_for_chopper_rotation(targetAngle,milliSecSample,samplesBefore,samplesAfter); // //7. response time to go from M3 right to M3 left result_d = ConfigurationReader("name_confilfpu",["chop_M3left"],band,0.0); targetAngle = result_d[0]{0}; Engineering_scan_for_chopper_rotation(targetAngle,milliSecSample,samplesBefore,samplesAfter); // } // LO settling time for a LO sub-band change, 2nd block // Block for second tuning block LO_Settling_time_second_tuning_fm HIFI 3681 { string band_b = "1b" in ["1b","2b","3b","4b","5b","6b","7b"]; // HIFI band a int int_time2 = 600; //Integration time after first and second switch double lo_freq_b = 600.0; //LO frequency in sub-band b string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); // // //Init and tune of LO: configuration from safe to tuned. LCU_config_nominal_proc_fm(band_b,lo_freq_b); LO_tuning_w_mixerchoice_proc(band_b,lo_freq_b,"H"); // //Configure spectroscopy integration Configure_Spectrometer_proc_fm(band_b,int_time2,["wb1","wb1"],backend); //4 sec. integration //Take series of spectra during int_time2 seconds HIFI_Spectr_total_power_proc_fm(band_b,backend,int_time2); // //Now switch off LO sub-band LCU_switch_off_proc_fm(); } ////////////////////////////////////////////////////////////////////////// // Auxiliary routine to guarantee matching of telescope API with // respect to map sizes and scan velocities // {double,double,int} procedure ValidMapSize { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} linedistance = {0.0050,0.0050}; // Distance between subsequent rows int nlines_tot = 1 in [1,240]; // Number of rows in the map double stepsize = 0.0050 in [0.0,0.13333]; // Distance between subsequent points in the OTF line int npoints_inp = 10 in [1,720]; // Number of data dumps per row int data_time = 4; // readout time }{ // Define maximum reduction - no reduction any more double eps = 1.0; // What is wanted double reqsize = stepsize * double(npoints_inp); // First evaluate valid step size double ratestep = 0.1 / 3600.0; double scanvelocity = stepsize / double(data_time); // Check for too low scanning speeds resulting in a discretization // error larger than half the step size if(scanvelocity < 2.0 * ratestep) { SError("Scan velocity too small for accurate map coverage."); } // Compute actual discretized rate double rate = double(iceil(scanvelocity * eps / ratestep)) * ratestep; double validstepsize = rate * double(data_time); // A message is the only feedback mechanism that we have here. double reldiff = (validstepsize - stepsize) * double(npoints_inp); if(abs(reldiff) > 0.5 * stepsize) { message("OTF readout is adjusted to occur every " + dformat(validstepsize * 3600.0,1) + "'' instead of the requested " + dformat(stepsize * 3600.0,1) + "''.
"); } // 2. step: Extend the npoints number to match the telescope API double rowmin = 20.0 / 3600.0; double rowstep = 5.0 / 3600.0; // Correct for possible 1s jitter, i.e. enlarge stripes int jitterdead = GetMaxTimeJitter(band,lo_freq); double step1s = validstepsize * double(jitterdead) / double(data_time); // Implementation assumes that rowmin is an integer multiple of rowstep if(reqsize > rowmin) { double fullrowlength = double(iceil((reqsize * eps + step1s) / rowstep)) * rowstep; } else { fullrowlength = rowmin; } int npoints = imax(ifloor((fullrowlength - step1s) / validstepsize),2); // Iterate on fullrowlength to avoid overheads double dumpsize = double(npoints) * validstepsize + step1s; if(dumpsize > rowmin) { fullrowlength = double(iceil(dumpsize / rowstep)) * rowstep; } else { fullrowlength = rowmin; } // Message reldiff = fullrowlength - step1s - reqsize; if(abs(reldiff) > 0.5 * stepsize) { message("The length of all OTF stripes is adjusted to cover " + dformat(double(npoints) * validstepsize * 3600.0,1) + "'' instead of the requested " + dformat(reqsize * 3600.0,1) + "''.
"); } // Granularity for d2 // This is duplicated from OTF_telescope double linestep = 0.5 / 3600.0; double d2_req = AngleVectorLength(linedistance); double d2 = double(iceil(d2_req * eps / linestep)) * linestep; // Exception for the "impossible" case of spacings below 2arcsec if(d2 > 0.0) { d2 = max(d2,2.0 / 3600.0); } // Message reldiff = (d2 - d2_req) * double(nlines_tot); if(abs(reldiff) > 0.5 * d2_req) { message("The OTF stripe distance is adjusted to " + dformat(d2 * 3600.0,1) + "'' instead of the requested " + dformat(d2_req * 3600.0,1) + "''.
"); } return {fullrowlength,rate,npoints}; } // Procedure to check whether fast chop frequency is high enough for // HRS internal integration and low enough for mechanical chopper constraints // procedure CheckFastChopFrequency { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz int data_time = 10 in [4,128]; // data dump interval int n_int = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_data = 2; // Integration time counter }{ // Get timing parameters {int,int,int,int,int,int,int,int,int,int,int,int,int} timing = FastConfigureSpectroscopyParams(data_time,n_int,n_data,band,lo_freq,true); int del_wbs = timing{5}; int t_acc_wbs = timing{6}; int t_acc_hrs = timing{7}; // Maximum phase length {double,string}[] result = ConfigurationReader("name_delays",["max_hrs_phase"],band,lo_freq); int max_hrs_phase = iround(result[0]{0}); // Minimum chop phase length int min_wbs_phase = GetMinChopPhaseLength(band,lo_freq); // Checks if(t_acc_wbs + del_wbs < min_wbs_phase) { SError("Chop phases too short for chopper mechanics. Reduce chop frequency."); } if(t_acc_hrs > max_hrs_phase) { SError("Chop phase length too long for HRS. Increase chop frequency."); } } // Function returning generic HRS mode string[] procedure GetHrsMode_proc_ops { string[] input_hrs_mode = ["wb","wb"]; // HRS resolution mode }{ string[] output_hrs_mode = ["wb","wb"]; //Test all possible resolution modes //H-polar if(input_hrs_mode[0] == "hr" || input_hrs_mode[0] == "hr_high" || input_hrs_mode[0] == "hr_low") { output_hrs_mode[0] = "hr"; } if(input_hrs_mode[0] == "mr") { output_hrs_mode[0] = "mr"; } if(input_hrs_mode[0] == "lr") { output_hrs_mode[0] = "lr"; } //V-polar if(input_hrs_mode[1] == "hr" || input_hrs_mode[1] == "hr_high" || input_hrs_mode[1] == "hr_low") { output_hrs_mode[1] = "hr"; } if(input_hrs_mode[1] == "mr") { output_hrs_mode[1] = "mr"; } if(input_hrs_mode[1] == "lr") { output_hrs_mode[1] = "lr"; } // return output_hrs_mode; } //HIFI-COP-3-Tsys procedure Tsys_COP_proc_ops { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band int integ_time = 4; string backend = "both"; string[] hrs_mode = ["wb1","wb1"]; int n_wbs1 = 0; int n_hrs_trans = 0; string chopmode = "slowchop"; }{ // LCU_switchon_proc_fm(band); //Wait an extra delay of 1 min for short term stabilization delay(60); // HRS_config_block_fm(band,hrs_mode); // int[] res = [0,0]; res = Configure_Spectrometer_hc_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); int total_time = res[0] * res[1]; // //Get the list of frequencies to be used for the scan string tab = "config_surveytsys.config"; double bandnb = GetBandCode(band); double lofreqlow = dlookup(tab,"" + iceil(bandnb),"lofreqlow"); double lofreqhigh = dlookup(tab,"" + iceil(bandnb),"lofreqhigh"); double lofreqstep = dlookup(tab,"" + iceil(bandnb),"lofreqstep"); // double current_LO = lofreqlow; bool endreached = false; //Loop on key frequencies per LO band while(current_LO <= lofreqhigh && endreached == false) { // Init_MSA_HBB_fm(band,"CLOSE",current_LO,"ON"); LO_tuning_block_fm(band,current_LO); WBS_calib_fm(band); //Does a magnet tuning: only up to band 5 since band6-7 have no magnets if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { Magnet_tuning_block_fm(band,current_LO,"HRS",40); //for first freq of each LO band, deflux heater if(current_LO == lofreqlow && (band != "5a" || band != "5b")) { //Deflux heaters Heater_cop(band); //Second magnet tuning Magnet_tuning_block_fm(band,current_LO,"HRS",40); } } WBS_tune_proc_fm(band); HRS_tune_block_fm(band); // Hot_cold(band,hrs_mode,backend,total_time,chopmode,n_wbs1,n_hrs_trans); // //Check last LO freq done if(current_LO == lofreqhigh && endreached == false) { endreached = true; } //Increase LO freq: truncate if step too high current_LO = current_LO + lofreqstep; if(current_LO > lofreqhigh && endreached == false) { current_LO = lofreqhigh; } } } // Get dead time for chopper motion on the sky double procedure GetLoadChopDeadTime { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency }{ double[] dead = CalibrationReader("lchop_deadtime",["loadchop"],band,lo_freq); return dead[0]; } ///////////////////////////////////////////////////////////////// // Second step of timing computation after telescope behaviour // is known - Spectral Scan frequency switch observing mode // {int,{int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int},double,double,double} procedure SScanDoubleChop_post_timing { {int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int} pre_timing = {16,16,16,16,21,11,1800,32,2,2,0,0,false,false,50,0}; // pre_timing parameter list int[] telescopetimes = [300,180,20,1,21,0]; int grouplen = 1; // Number of frequencies to group into one cycle int groupnumber = 50; // Total umber of frequency groups int n_cycles = 1; // Number of half OFF-ON-ON-OFF cycles at one frequency }{ // Get all values from the pre_timing section int on_inttime = pre_timing{0}; int off_inttime = pre_timing{1}; int on_pointing = pre_timing{2}; int off_pointing = pre_timing{3}; int loadlength = pre_timing{4}; int auxtunestep = pre_timing{5}; int load_spacing = pre_timing{6}; int n_loadinterval = pre_timing{7}; int n_chop_on = pre_timing{8}; int n_chop_off = pre_timing{9}; int data_time_on = pre_timing{10}; int data_time_off = pre_timing{11}; bool end_load_on = pre_timing{12}; bool end_load_off = pre_timing{13}; int initlength = pre_timing{14}; int dangling = pre_timing{15}; // Get all values from the telescope section int telinit = telescopetimes[1]; // Initial slew time int slewtime = telescopetimes[2]; // Slew time to OFF int longslew = telescopetimes[4]; // Actual slew time for load slew int pointwaittime = telescopetimes[3]; // Idle time between two phases int tend = telescopetimes[5]; // Final deceleration time ////////////////////////////////////////////////////////////////// // Now we start the actual computations // Pointwaittime is used for tuning // In all non-tuning cycles, pointwaittime acts like a longer slew slewtime = slewtime + pointwaittime; longslew = longslew + pointwaittime; // Half tune step has to be rounded up int halftunestep = (auxtunestep + 1) / 2; int effhalftunestep = (auxtunestep - pointwaittime + 1) / 2; int shiftlength = halftunestep - effhalftunestep; // Correct pointing times on_pointing = on_pointing - shiftlength; off_pointing = off_pointing - shiftlength; // Check group length limited by load_interval int scan_time = on_pointing + off_pointing + slewtime; if(scan_time > load_spacing + slewtime && grouplen > 1) { SError("Frequency group length too large for load interval."); } // Compute load cycles and average times if(n_cycles > 1) { // How often do I have to perform a load slew // Never switch between short load and long load here if(n_loadinterval > 1) { int old_n_loadinterval = n_loadinterval; n_loadinterval = imax((load_spacing + slewtime) / scan_time,1); // fit with n_cycles n_loadinterval = imin(n_loadinterval,n_cycles); n_loadinterval = IMultiple(n_loadinterval,n_cycles); if(n_loadinterval <= 1) { n_loadinterval = old_n_loadinterval; } } // Determine need for final load measurement double rest = double(n_cycles * groupnumber % n_loadinterval) + 0.5; bool final_load = rest > 0.5001 * double(n_loadinterval); // part of integrations is added when not needed for tuning int n_add_on = effhalftunestep / (2 * data_time_on); int n_long_on = n_chop_on + n_add_on; int n_add_off = effhalftunestep / (2 * data_time_off); int n_long_off = n_chop_off + n_add_off; // Average times for noise estimate int longint_on = n_long_on * 2 * data_time_on; int longint_off = n_long_off * 2 * data_time_on; int numlong_on = 2 * (n_cycles / 2); double effchop_on = double(numlong_on * n_long_on + (n_cycles * grouplen - numlong_on) * n_chop_on) / double(grouplen * n_cycles); int numlong_off = 2 * ((n_cycles - 1) / 2); double effchop_off = double(numlong_off * n_long_off + (n_cycles - numlong_off) * n_chop_off) / double(n_cycles); int loadpercycle = n_cycles / n_loadinterval; double cycletime = double(on_pointing + off_pointing) + double(loadpercycle * longslew + (n_cycles - loadpercycle) * slewtime) / double(n_cycles); double tscan = (cycletime * double(n_cycles) - double(2 * halftunestep)) / double(n_cycles); // retuning does not increase drift } else { // Determine need for final load measurement if(groupnumber % 2 == 0) { rest = double(off_pointing); } else { rest = double(on_pointing); } final_load = rest > 0.5001 * double(load_spacing); // All cycles have the same length n_long_on = n_chop_on; n_long_off = n_chop_off; // Average times for noise estimate effchop_on = double(n_chop_on); effchop_off = double(n_chop_off); cycletime = double(on_pointing + off_pointing + longslew); tscan = cycletime - double(2 * effhalftunestep); } ////////////////////////////////////////////////////////////////////// // Compute total duration initlength = initlength - effhalftunestep; shiftlength = effhalftunestep; // The initial time is no longer contained in the total time // int totaltime=imax(initlength,telinit); int totaltime = iround(cycletime * double(groupnumber * n_cycles)); // Add dangling load time - this should not occur, just for consistency if(final_load) { dangling = loadlength - shiftlength; } int closelength = duration(HIFICloseObs()); dangling = imax(dangling + closelength - tend,0); // Compute total duration, remove pointwaittime for last slew totaltime = totaltime + dangling - pointwaittime + tend; // show gyro-propagation messages int pointcycle = on_pointing + off_pointing + longslew; GCPMessages(off_pointing,2 * pointcycle,tend); // Return all the times needed in the observing mode modules return {totaltime,{on_inttime,off_inttime,on_pointing,off_pointing,loadlength,shiftlength,load_spacing,n_loadinterval,n_long_on,n_long_off,1,1,final_load,final_load,initlength,dangling},effchop_on,effchop_off,tscan}; } double procedure HotColdRelaxTime { string band = "4a"; // HIFI band (needed to estimate stabilization) double lo_freq = 978200.0; // LO frequency bool wbsused = true; // whether one of the WBS' is used }{ // Dead time given purely by the chopper double relaxtime = GetHotColdDeadTime(band,lo_freq); // Add WBS relaxation if this is used if(wbsused) { // Get the Bragg cell time constant double[] bragg = CalibrationReader("bragg_cell",["bragg_relaxtime"],band,lo_freq); double t_bragg = bragg[0]; // Get the other involved temperatures double tsys = InterpolateTsys(band,lo_freq); {double,double} tloads = LoadTemperatures(band,lo_freq); // Compute involved level difference double hotlevel = tsys + tloads{0}; double coldlevel = tsys + tloads{1}; double difference = (hotlevel - coldlevel) / hotlevel; relaxtime = max(relaxtime,t_bragg * difference); } return relaxtime; } // Get minimum integration time per phase for fast-chop int procedure GetMinChopPhaseLength { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency }{ double[] freq = CalibrationReader("chopfreq",["maxchopfreq"],band,lo_freq); double phaselength = 1000.0 / (2.0 * freq[0]); return iceil(phaselength); } // LCU6Ha configuration into SAFE mode, procedure procedure LCU6Ha_config_safe_proc_fm { string band = "7a"; // HIFI band double lo_freq = 1700.0 in [1700.0,1800.0]; //LO frequency }{ error("This module is obsolete: use LCU_config_nominal_proc_fm instead"); } // Routines for calibration data handling ///////////////////////////////////////////////////////////////// // Generic calibration file reader. This is called by all routines // using calibration parameters. The same approach is used for fixed, // band-dependent and LO frequency dependent quantities. Thus we // can add more calibration information as we obtain it. // double[] procedure CalibrationReader { string topicname = "tsys"; // Name of entry in master file string[] objectnames = ["tsys_h"]; // Names of calibration objects to be read string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency }{ // first step: read master file string calibfile = slookup("calibration_masterfile",topicname,"filename"); int dep = ilookup("calibration_masterfile",topicname,"dependence"); int readnum = length(objectnames); double[] retvalues = []; if(dep == 0) { // Quantity is constant // Read from single file by name for(int i = 1 .. readnum) { retvalues[i - 1] = dlookup(calibfile,objectnames[i - 1],"value"); } } else { if(dep == 1) { // Quantity is band dependent // directly read from file looking up the band for(int k = 1 .. readnum) { retvalues[k - 1] = dlookup(calibfile,band,objectnames[k - 1]); } } else { // Quantity is band and frequency dependent // second step step: band look up, get name of responsible data file string actualfile = slookup(calibfile,band,"filename"); // Now read interpolated value from the data base for(int j = 1 .. readnum) { retvalues[j - 1] = interpolate(actualfile,objectnames[j - 1],lo_freq); } } } return retvalues; } //Integration on Internal hot, block block Hot_spectra_fm HIFI 3223 { string band = "1a"; int integ_time = 4; //Total integration time in sec.: at least 2sec ! string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); //Rotate chopper: assume we come from M3 Chopper_Rotation_proc_fm(band,"chop_M3_ang","chop_hot_ang"); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // } // Initialisation of FPU, block with both MSA in use // It is for cold context ! block Init_MSA_fm HIFI 3200 { string band = "1a"; // HIFI band string chop_loop = "CLOSE"; double lo_freq = 522.0; //LO frequency string hbb_heater = "ON" in ["ON","OFF"]; //hot source on/off }{ //Start_block(); //Get parameters {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,lo_freq); int band_nb = iround(result_d[0]{0}); double diplex_H = 0.0; double diplex_V = 0.0; int diplex_h_ctrl_mode = 0; int diplex_v_ctrl_mode = 0; // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,lo_freq); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // string chop_sine_s = "ON"; // string chop_loop = "CLOSE" ; result_d = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,lo_freq); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // double calibcurrent = result_d[7]{0}; if(hbb_heater == "ON") { result_d = ConfigurationReader("name_confilfpu",["calibrator_current_on"],band,lo_freq); calibcurrent = result_d[0]{0}; } // //Get biases result_d = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); double bias_H = result_d[0]{0}; double bias_V = result_d[1]{0}; //For bands 6 and 7, first set to 4mV if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { result_d = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,lo_freq); bias_H = result_d[0]{0}; bias_V = result_d[1]{0}; } // //Get magnets: not applicable to bands 6 and 7 double magnetcurrent_H = 0.0; double magnetcurrent_V = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,lo_freq); magnetcurrent_H = result_d[0]{0}; magnetcurrent_V = result_d[1]{0}; } //Diplexer is interpolated from a table for Bands 3, 4, 6L and 6H if(band_nb <= 2 || band_nb == 5) { diplex_H = 0.0; //For bands 1, 2 and 5 diplex_V = 0.0; diplex_h_ctrl_mode = 0; diplex_v_ctrl_mode = 0; } else { //Get diplexer currents result_d = ConfigurationReader("name_confilfpu",["diplex_h_ctrl_mode","diplex_v_ctrl_mode"],band,lo_freq); diplex_h_ctrl_mode = iround(result_d[0]{0}); diplex_v_ctrl_mode = iround(result_d[1]{0}); double[] result_dip = Get_Diplexer_setting(band,lo_freq); diplex_H = result_dip[0]; diplex_V = result_dip[1]; } // result_d = ConfigurationReader("name_chopper",["chop_startup_cold"],band,0.0); if(chop_loop == "OPEN") { result_d = ConfigurationReader("name_chopper",["chop_startup_warm"],band,0.0); } double chopper = result_d[0]{0}; //For this configuration we won't convert prime chopper voltage into redundant voltage //Just checking we are in range. //chopper = Check_Chopper_Prime_Redundant(chopper); chopper = Check_Chopper_Range(chopper); // //Switch on upconverter, assuming chopper and mixers are also ON Hifi_HIFI_Configure_FCU_Power($BBID,"ON","ON","ON","ON","ON"); // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result_d = ConfigurationReader("name_delays",["config_fpu_delay"],band,lo_freq); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // //In case of band 6 or 7, bias have been set to 4mV. Now set to nominal if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { {double,string}[] result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); Mixerbias(result[0]{0},result[1]{0}); } // //Magnet are so far at maximum value. Now set to nominal if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); Hifi_HIFI_CH1_MX_MG_C($BBID,result_d[0]{0}); Hifi_HIFI_CV1_MX_MG_C($BBID,result_d[1]{0}); delay(1); } // //Hifi_HIFI_non_periodic_hk_FCU (); } //HIFI-COP-X-IF-FBk-Cal procedure IF_FBk_Cal_COP_proc_ops { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency string[] hrs_mode = ["wb1","wb1"]; int integ_time = 600; string backend = "both"; string chopcase = "dbs" in ["dbs","csa","lsw"]; //chopper delta considered }{ //Switch-off LO LCU_switch_off_block_fm(); // //For LSW string chop1 = "chop_M3"; string chop2 = "chop_cold"; if(chopcase == "dbs") { chop1 = "chop_M3right"; chop2 = "chop_M3left"; } if(chopcase == "csa") { chop1 = "chop_hot"; chop2 = "chop_cold"; } {double,string}[] result_d = ConfigurationReader("name_confilfpu",[chop1,chop2],band,0.0); int[] res = [0,0]; // Init_MSA_HBB_fm(band,"CLOSE",lo_freq,"ON"); //Set magnets to 0 Set_Magnet_current_block_fm(0.0,0.0); //Use high biases result_d = ConfigurationReader("name_confilfpu",["bias_high_resistive_h","bias_high_resistive_v"],band,lo_freq); Mixerbias_block_fm(result_d[0]{0},result_d[1]{0}); WBS_calib_fm(band); WBS_tune_proc_fm(band); HRS_config_block_fm(band,hrs_mode); HRS_tune_block_fm(band); // //Direct long integration res = Configure_Spectrometer_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); result_d = ConfigurationReader("name_confilfpu",[chop1,chop2],band,0.0); Spectro_slow_chop_block_fm(band,[result_d[0]{0},result_d[1]{0}],[integ_time * 2,1],backend); // //Bias to nominal {double,string}[] result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); Mixerbias(result[0]{0},result[1]{0}); //Magnets back to nominal, via max result = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,lo_freq); Set_Magnet_current_proc_fm(result[0]{0},result[1]{0}); result = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); Set_Magnet_current_proc_fm(result[0]{0},result[1]{0}); } // Interpolate coupling of the instrument for the selected frequency double procedure InterpolateCoupling { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency }{ double[] eta = CalibrationReader("efficiency",["eta_mb"],band,lo_freq); return eta[0]; } // WBS laser temperature control switched off, block block Laser_T_check_off_fm HIFI 3705 { }{ Hifi_HIFI_WH_Laser_T_chck_off(); Hifi_HIFI_WV_Laser_T_chck_off(); delay(1); } // SFT: Init of all S/S, procedure // This is for use in dummy (warm) context procedure HIFI_SFT_proc { string band = "1a"; // HIFI band double lo_freq = 500.0; //LO frequency string mixer_polarization = "H" in ["H","V","B"]; //Polarization: H, V or Both string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code string chop_loop = "CLOSE"; //The chopper loop status int integ_time = 4; //Total integration time in sec. string laser_H = "Laser1" in ["Laser1","Laser2"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2"]; //WBS-V laser to be set ON string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ // //Init of instrument: depends on polarization //The chopper will look at a position depending on the test context {double,string}[] result_d = ConfigurationReader("name_chopper",["chop_startup_cold"],band,lo_freq); //{double, string}[] result_d = ConfigurationReaderWarm("name_chopper",["chop_startup_warm"], // band,lo_freq); double chop = result_d[0]{0}; // if(mixer_polarization == "H") { Init_MSA_H_fm(band,chop_loop,lo_freq); //Init_MSA_fm_dummy(band,chop_loop,lo_freq); } if(mixer_polarization == "V") { Init_MSA_V_fm(band,chop_loop,lo_freq); //Init_MSA_fm_dummy(band,chop_loop,lo_freq); } if(mixer_polarization == "B") { Init_MSA_fm(band,chop_loop,lo_freq,"ON"); //Init_MSA_fm_dummy(band,chop_loop,lo_freq); } // //Configure WBS laser according to user inputs. Delays are included //Maximum attenuation is used since it is what is set in the default config file //In fact laser should have been switched on previously for the 2 min. stabilization if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_config_w_laser_block_fm(band,laser_H,laser_V); } if(backend == "hrs" || backend == "both") { HRS_config_max_att_block_fm(band,hrs_mode); } // //Init of LO: configuration. Delays are included Set_LO_Nominal_block_fm(); LCU_switchon_proc_fm(band); // //Configure spectroscopy integration Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); // } //Generic procedure to launch engineering scan applied to chopper rotation, procedure block Engineering_scan_for_diplexer_resp_block_ops HIFI 3951 { int milliSecSample = 3; // interval between samples int samplesBefore = 30 in [0,50]; // HIF_N_samples_1 int samplesAfter = 1000 in [0,1000]; // HIF_N_samples_2 }{ Start_block(); // //H-diplexer - forward motion - read diplexer current Hifi_HIFI_engineering_scan(milliSecSample,0x8c50,0xfff,0xfff,0xcc100000,samplesBefore,samplesAfter); //Compute delay int nb_HK = 1; //For this TC, the 2 last HK fields are blanked out int millisecondsUsed = 1000 + 10 + milliSecSample * nb_HK * (samplesBefore + samplesAfter); delay(iceil(0.0010 * double(millisecondsUsed))); //H-diplexer - reverse motion - read diplexer current Hifi_HIFI_engineering_scan(milliSecSample,0x8c50,0xfff,0xfff,0xcc100fff,samplesBefore,samplesAfter); delay(iceil(0.0010 * double(millisecondsUsed))); //H-diplexer - forward motion - read diplexer voltage Hifi_HIFI_engineering_scan(milliSecSample,0x8c51,0xfff,0xfff,0xcc100000,samplesBefore,samplesAfter); delay(iceil(0.0010 * double(millisecondsUsed))); //H-diplexer - reverse motion - read diplexer voltage Hifi_HIFI_engineering_scan(milliSecSample,0x8c51,0xfff,0xfff,0xcc100fff,samplesBefore,samplesAfter); delay(iceil(0.0010 * double(millisecondsUsed))); // //V-diplexer - forward motion - read diplexer current Hifi_HIFI_engineering_scan(milliSecSample,0x8d50,0xfff,0xfff,0xcd100000,samplesBefore,samplesAfter); delay(iceil(0.0010 * double(millisecondsUsed))); //V-diplexer - reverse motion - read diplexer current Hifi_HIFI_engineering_scan(milliSecSample,0x8d50,0xfff,0xfff,0xcd100fff,samplesBefore,samplesAfter); delay(iceil(0.0010 * double(millisecondsUsed))); //V-diplexer - forward motion - read diplexer voltage Hifi_HIFI_engineering_scan(milliSecSample,0x8d51,0xfff,0xfff,0xcd100000,samplesBefore,samplesAfter); delay(iceil(0.0010 * double(millisecondsUsed))); //V-diplexer - reverse motion - read diplexer voltage Hifi_HIFI_engineering_scan(milliSecSample,0x8d51,0xfff,0xfff,0xcd100fff,samplesBefore,samplesAfter); delay(iceil(0.0010 * double(millisecondsUsed))); // } // FPU Standby with HBB OFF, block block Band0_hbb_off_block_ops HIFI 7299 { string band = "0"; // HIFI band string chop_loop = "CLOSE"; // Chopper Loop status string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ //Get parameters {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,0.0); int band_nb = iround(result_d[0]{0}); // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,0.0); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // string chop_sine_s = "ON"; // result_d = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,0.0); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // double calibcurrent = result_d[7]{0}; // result_d = ConfigurationReader("name_confilfpu",["bias_standby_h","diplexer_standby_h","bias_standby_v","diplexer_standby_v","diplex_h_ctrl_mode","diplex_v_ctrl_mode","chop_M3right"],band,0.0); // double bias_H = result_d[0]{0}; double diplex_H = result_d[1]{0}; double bias_V = result_d[2]{0}; double diplex_V = result_d[3]{0}; int diplex_h_ctrl_mode = iround(result_d[4]{0}); int diplex_v_ctrl_mode = iround(result_d[5]{0}); double chopper = result_d[6]{0}; // //Retrieve magnets. if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilfpu",["magnet_standby_h","magnet_standby_v"],band,0.0); double magnetcurrent_H = result_d[0]{0}; double magnetcurrent_V = result_d[1]{0}; } // //Upconverter: should be kept ON at this stage. No particular action. // if(prime_or_redundant == "Prime") { Hifi_HIFI_P_Configure_FCU($BBID,band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); } else { Hifi_HIFI_R_Configure_FCU($BBID,band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); } // result_d = ConfigurationReader("name_delays",["config_fpu_delay"],band,0.0); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // Hifi_HIFI_non_periodic_hk_FCU(); // mois_tmcheck("Check that parameter HF_APR_CS_C is set to " + calibcurrent + " mA"); mois_tmcheck("Check that parameter HF_DPR_CHLOOP_S is set to " + chop_loop); mois_tmcheck("Check that parameter HF_DPR_CHSINE_S is set to " + chop_sine_s); } bool procedure IntIsContained { int x = 1; // search string int[] lot = [0]; // array to be searched }{ int nlen = length(lot); bool found = false; for(int i = 0 .. nlen - 1) { if(x == lot[i]) { found = true; } } return found; } //Generic procedure to perform fast chopper scan using the adequate instrument side procedure HIFI_Chopper_scan_fast_proc_fm { int milliSecSample = 3; // interval between samples double targetAngle = 0.0; //Target chopper voltage int samplesBefore = 30 in [0,50]; // HIF_N_samples_1 int samplesAfter = 1000 in [0,1000]; // HIF_N_samples_2 }{ //check prime or redundant keyword {double,string}[] result_d = ConfigurationReader("name_chopper",["prime_or_redundant"],"0",0.0); if(result_d[0]{1} == "prime") { Hifi_HIFI_P_Chopper_scan_fast(milliSecSample,targetAngle,samplesBefore,samplesAfter); } else { Hifi_HIFI_R_Chopper_scan_fast(milliSecSample,targetAngle,samplesBefore,samplesAfter); } // } //Notify PDU status OFF, block block HIFI_notify_PDU_status_off_block_fm HIFI 3654 { string status_FCU = "OFF" in ["ON","OFF"]; //Status of FCU string status_LCU = "OFF" in ["ON","OFF"]; //Status of LCU string status_WBSV = "OFF" in ["ON","OFF"]; //Status of WBSV string status_WBSH = "OFF" in ["ON","OFF"]; //Status of WBSH string status_HRSV = "OFF" in ["ON","OFF"]; //Status of HRSV string status_HRSH = "OFF" in ["ON","OFF"]; //Status of HRSH }{ Start_block_no_hk_request(); Hifi_HIFI_notify_PDU_status(status_FCU,status_LCU,status_WBSV,status_WBSH,status_HRSV,status_HRSH); delay(1); } // perform peak-up correction block HifiPeakupCorrection HIFI 6822 { }{ // Perform correction Hifi_HIFI_correction_AOCS($BBID); delay(1); } ///////////////////////////////////////////////////////////////////////////// // The actual commanding procedures // total power procedure HIFI_Spectr_tp_proc_aot { int n_int = 1; // Integration time counter int data_time = 4; // Integration time between two data readouts double[] rates = [120.0,1.0,2.0]; // Data rates between and during integrations }{ // set data rates non_ess_hk_data_rate(rates[2] / 1024.0); data_rate(rates[0] / 1024.0); // Call command Hifi_HIFI_Spectr_total_power($BBID); delay(n_int * data_time); // reset data rates non_ess_hk_data_rate(rates[1] / 1024.0); data_rate(0.0); } //HIFI-COP-1.2-IF_FT procedure IF_FT_COP_proc_ops { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b","8"]; // HIFI band double lo_freq = 500.0; //LO frequency string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ mois_comment("Start of HIFI IF Functional Test for band " + band); mois_comment("Please ensure that instrument was switched on with the " + prime_or_redundant + " unit"); //General parameters in use int integ_time = 4; string backend = "both"; string hbb_heater = "ON"; //hot source on/off string chopper_loop = "CLOSE"; // string chop_startup_prime_red = "chop_startup_cold_prime"; if(prime_or_redundant == "Red") { chop_startup_prime_red = "chop_startup_cold_red"; } {double,string}[] result = ConfigurationReader("name_chopper",[chop_startup_prime_red],"0",0.0); if(chopper_loop == "OPEN") { result = ConfigurationReader("name_chopper",["chop_startup_warm"],"0",0.0); } mois_step("Init of FPU"); Init_MSA_ops(band,chopper_loop,lo_freq,result[0]{0},hbb_heater,prime_or_redundant); mois_tmcheck("Check content of ANDs FCU_H_device, FCU_V_device, FCU_PR_power and FPU_common with HIFI expert"); // //Set mixer bias to 5mV mois_step("Turn on shot noise for band 5 mixers"); result = ConfigurationReader("name_confilfpu",["bias_low_resistive_h","bias_low_resistive_v"],band,0.0); double bias_low_h = result[0]{0}; double bias_low_v = result[1]{0}; //Set magnets to 0 Set_Magnet_current_block_fm(0.0,0.0); mois_tmcheck("Check that parameters HF_AH1_MXMG_C and HF_AV1_MXMG_C are both set to 0 mA"); // Mixerbias(bias_low_h,bias_low_v); mois_tmcheck("Check that parameters HF_AH1_MXBIAS_V and HF_AV1_MXBIAS_V are set to " + bias_low_h + " and " + bias_low_v + " mV respectively"); // mois_step("WBS tuning with Laser 2"); string laser_H = "Laser2"; string laser_V = "Laser2"; WBS_config_w_laser_block_fm(band,laser_H,laser_V); mois_tmcheck("Check that parameters HWH_Laser2_S and HWV_Laser2_S are ON"); WBS_tune_proc_fm(band); HRS_tune_block_fm(band); //To check final attenuator settings Configure_Spectrometer_proc_fm(band,integ_time,["wb1","wb1"],backend); Spectro_total_power_block_fm(band,[integ_time,1],backend); // } ////////////////////////////////////////////////////////////////////////// // Procedure to compute detailed timing of DBS-raster cross observing mode {int,{int,int,int,int,int,int,int,int,int,int,int,int,int},bool,double,double} procedure DBSCross_post_timing { {int,int,int,int,int,int,int,int,int,int,int,int,int} pre_timing = {4,10,4,21,1,1800,0,10,1,1,1,50,0}; // full timing parameter list int[] telescopetimes = [300,180,20,0,21,0,2,10]; int npoints = 10; // Number of points per row int n_chop = 2; // number of half sky1-sky0-sky0-sky1 cycles per pointing int n_cycles = 1; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800; // load period = f(band,lo_freq,eff_resolution{1}) bool fastchop = false; // whether fast-chop is used instead of slow-chop }{ // Get all values from the pre_timing section int inttime = pre_timing{0}; int pointing = pre_timing{1}; int readouttime = pre_timing{2}; int loadlength = pre_timing{3}; int jitterdead = pre_timing{4}; int load_spacing = pre_timing{5}; int n_load = pre_timing{6}; int n_loadinterval = pre_timing{7}; int n_seq = pre_timing{8}; int n_scans = pre_timing{9}; int scansize = pre_timing{10}; int initlength = pre_timing{11}; int dangling = pre_timing{12}; // Get all values from the telescope section int telinit = telescopetimes[1]; // Initial slew time int longslew = telescopetimes[4]; // Actual slew time for load slew int tend = telescopetimes[5]; // Final deceleration time /////////////////////// // Long computation for scansize > 1 to obtain all slew durations {int,int,int} sumslewtimes = GetAllCrossSlewTimes(telescopetimes,scansize,n_cycles); int tinscandead = sumslewtimes{0}; int toutscandead = sumslewtimes{1}; int shortmove = sumslewtimes{2}; // Total number of scans int n_tot = n_scans * n_cycles; // Compute total duration of measurement and average scan length int totalscantime = n_tot * (2 * pointing * scansize) + tinscandead; // approximate scan time for load comparison int scan_time = iceil(double(totalscantime) / double(2 * n_tot)); if(load_spacing > 2 * scan_time) { n_seq = n_chop; pointing = inttime + jitterdead; bool end_load = false; } else { // It could happen that the slew extends the scan too much - catch if(scansize > 1) { SError("Number of points in one scan too large for load period."); } n_load = n_load + 1; n_seq = n_chop / n_load; // adjust pointing time to include load measurements int loadappend = imax(loadlength - shortmove,0); end_load = true; // Computation for slow-chop or fast-chop if(fastchop) { inttime = n_seq * n_load * readouttime; } else { inttime = 2 * n_seq * n_load * readouttime; } pointing = inttime + loadappend + (n_load - 1) * loadlength + jitterdead; } totalscantime = n_tot * (2 * pointing * scansize) + tinscandead + toutscandead; scan_time = iceil(double(totalscantime) / double(2 * n_tot)); // compute the load interval in case of short scan_time n_loadinterval = imax((load_interval - loadlength + longslew) / (2 * scan_time),1); // Special treatment for nodding_IN_raster due to limitations in API // Split into loads per point or per multiple points if(scansize == 1) { int nodtime = tinscandead / n_tot; if(n_loadinterval > n_cycles) { n_loadinterval = n_cycles * (n_loadinterval / n_cycles); n_loadinterval = imin(n_loadinterval,n_tot); // Translate load waiting time into a hold after the point int holdlength = imax(loadlength - nodtime,0); int loadadded = holdlength; int n_long = n_tot / n_loadinterval; } else { // Nodding in raster with loads per point holdlength = 0; loadadded = longslew - nodtime; // compensate counter reset int dangling_period = n_cycles % n_loadinterval; while((dangling_period + n_loadinterval) * 2 * scan_time > load_interval - loadlength + longslew) { n_loadinterval = n_loadinterval - 1; dangling_period = n_cycles % n_loadinterval; } // Consistency check if(n_loadinterval < 1) { CError("Too short load period computed."); } n_long = n_scans * (n_cycles / n_loadinterval); } } else { // Treatment for nodding_OF_raster int minnod = GetMinLoadNod(telescopetimes,scansize,n_cycles,n_loadinterval); holdlength = imax(loadlength - minnod,0); loadadded = holdlength; n_long = n_tot / n_loadinterval; } // Compute total duration of measurement, correct for load nods totalscantime = n_tot * (2 * pointing * scansize) + tinscandead + n_long * loadadded; // Average dead and scan time for drift estimate double tscan = double(totalscantime) / double(n_tot); double tdead = tscan - double(2 * inttime * scansize); // Count integration times of other points of one nod as dead time // Other points in the second nod are excluded from the scan double othertime = double((scansize - 1) * inttime); tdead = tdead + othertime; // Reduce scan time by the other points in the second nod phase tscan = tscan - othertime; // Determine need for final load measurement double rest = double(n_tot % n_loadinterval) + 0.5; bool final_load = rest > 0.5001 * double(n_loadinterval); // Compute total duration // The initial time is no longer contained in the total time // int totaltime=imax(initlength,telinit); int totaltime = totalscantime + toutscandead; // Add dangling load time if not included in pointing // they are mutually exclusive, otherwise the readoutdelay applies if(final_load) { dangling = loadlength; } if(end_load) { dangling = loadlength - loadappend; } int closelength = duration(HIFICloseObs()); dangling = imax(dangling + closelength - tend,0); totaltime = totaltime + dangling + tend; // show gyro-propagation messages // no gyro-propagation for custom_map GCPMessages(0,totalscantime / n_cycles,tend); // Return all the times needed in the observing mode modules return {totaltime,{inttime,pointing,readouttime,loadlength,holdlength,load_spacing,n_load,n_loadinterval,n_seq,n_scans,scansize,initlength,dangling},final_load,tscan,tdead}; } // Single integration with no change of setups, procedure procedure Total_power_integration_proc { string band = "1a"; // HIFI band int integ_time = 4; //Total integration time in sec. }{ error("Procedure Total_power_integration_proc is not used anymore."); } // IV curve, block block IVcurve_defluxed_fm HIFI 3212 { string band = "1a"; }{ //Start_block() ; {double,string}[] result_d = ConfigurationReader("name_confilfpu",["bias_min_h","bias_max_h","bias_steps_h","bias_min_v","bias_max_v","bias_steps_v"],band,0.0); //H polar double bias_min_h = result_d[0]{0}; double bias_max_h = result_d[1]{0}; int steps_h = iround(result_d[2]{0}); //V polar double bias_min_v = result_d[3]{0}; double bias_max_v = result_d[4]{0}; int steps_v = iround(result_d[5]{0}); //Bias to set at end of IVC //Need a representative frequency: take keyfreq double[] result = CalibrationReader("name_keyfreq",["keyfreq"],band,0.0); double lo_freq = result[0]; // result_d = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v","norm_magn_h","norm_magn_v"],band,lo_freq); double bias_h = result_d[0]{0}; double bias_v = result_d[1]{0}; //Fetch magnets only if band is not band6 double magnetcurrent_h = 0.0; double magnetcurrent_v = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { magnetcurrent_h = result_d[2]{0}; magnetcurrent_v = result_d[3]{0}; } //The IVCurve is done on the smallest range and the finest step double bias_min = max(bias_min_h,bias_min_v); double bias_max = min(bias_max_h,bias_max_v); int steps = iround(max(double(steps_h),double(steps_v))); // //First set magnets to max. double magnet_current_max_h = 0.0; double magnet_current_max_v = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,0.0); magnet_current_max_h = result_d[0]{0}; magnet_current_max_v = result_d[1]{0}; } Hifi_HIFI_CH1_MX_MG_C($BBID,magnet_current_max_h); Hifi_HIFI_CV1_MX_MG_C($BBID,magnet_current_max_v); delay(1); //Perform IV curve IVcurve(band,bias_min,bias_max,steps,magnetcurrent_h,magnetcurrent_v,bias_h,bias_v); } // building block to initialize load calibration measurement // and compute main parameters {int,int,bool} block HIFICalInit HIFI 6008 { string band = "4a"; // HIFI band (needed to estimate stabilization) double lo_freq = 978200.0; // LO frequency double deltanu = 1.0; // minimum effective resolution of the calibrated data int data_time = 4; // time between subsequent data readouts }{ // The minimum integration time is given by data_time // However, we introduce an upper limit of 6s here (covers 24bit mode) int used_datatime = imin(data_time,6); // Check whether frequent retuning is needed double[] allan = CalibrationReader("loaddiff_stability",["instable"],band,lo_freq); bool retuning = allan[0] > 0.0; // Compute integration time int min_int_time = LoadIntegrationTime(band,lo_freq,deltanu); if(retuning) { int n_inttime = 2 * iceil(0.5 * double(min_int_time) / double(used_datatime)); } else { n_inttime = 2 * iceil(double(min_int_time) / double(used_datatime)); } // return parameters return {used_datatime,n_inttime,retuning}; } // LCU switch-off, block block LCU_switch_off_block_aot HIFI 6631 { }{ {double,string}[] result = ConfigurationReader("name_delays",["switch_off_delay"],"0",0.0); int switch_off_delay = iround(result[0]{0}); // //Send command: this is the effective switch-off //Hifi_HIFI_Conf_nom_LCU_ch0($BBID); //Removed to fix SPR-2522 // delay(switch_off_delay); // //Set heater to their stby value: should not depend on band HL_heater_proc_aot("1a","stby"); } ///////////////////////////////////////////////////////////////// // Procedure to compute total dead times for the mode // double procedure PositionSwitch_deadtimes { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4 in [1,5]; // data dump interval limited by the data rates int n_int = 3 in [2,1800]; // number of data dumps for integration per phase double tdead = 10.0; // Dead time from telescope }{ ////////////////////////////////////////////////////////////////////// // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Compute parameters for the instrument timing {double,double} tinst = GetInstDeadSlowChop(data_time,n_int,"tp",band,lo_freq,backendreadoutparms); // total dead time in one cycle double tinst_dead = double(data_time * n_int) - tinst{0}; // Total dead time per cycle double tdead_tot = tdead + 2.0 * tinst_dead; return tdead_tot; } //Set HIFI to standby I - lasers are forced to Off. HBB stays ON obs HifiEngSetIntoStandby_I { }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(HifiIntoStandby_I()); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // ON integration HifiIntoStandby_I(); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // The procedures/blocks //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // HRS complete configuration, block // Both polarizations are treated block HRS_config_block_fm HIFI 3632 { string band = "1a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code }{ //Start_block(); // Fetch HRS configuration parameters //=================================== //H-polar string hrs_filename_h = "name_confighrs_" + hrs_mode[0]; {double,string}[] result = ConfigurationReader(hrs_filename_h,["hrh_switch","hrh_1u_att","hrh_1l_att","hrh_2u_att","hrh_2l_att","hrh_3u_att","hrh_3l_att","hrh_4u_att","hrh_4l_att","hrh_up_ol1","hrh_up_ol2","hrh_up_ol3","hrh_up_ol4","hrh_down_ol5","hrh_down_ol6","hrh_down_ol7"],band,0.0); string hrs_polarization_h = result[0]{1}; double hrsH_ATT_U1 = result[1]{0}; double hrsH_ATT_L1 = result[2]{0}; double hrsH_ATT_U2 = result[3]{0}; double hrsH_ATT_L2 = result[4]{0}; double hrsH_ATT_U3 = result[5]{0}; double hrsH_ATT_L3 = result[6]{0}; double hrsH_ATT_U4 = result[7]{0}; double hrsH_ATT_L4 = result[8]{0}; double[] hrsH_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; //V-polar string hrs_filename_v = "name_confighrs_" + hrs_mode[1]; result = ConfigurationReader(hrs_filename_v,["hrv_switch","hrv_1u_att","hrv_1l_att","hrv_2u_att","hrv_2l_att","hrv_3u_att","hrv_3l_att","hrv_4u_att","hrv_4l_att","hrv_up_ol1","hrv_up_ol2","hrv_up_ol3","hrv_up_ol4","hrv_down_ol5","hrv_down_ol6","hrv_down_ol7"],band,0.0); string hrs_polarization_v = result[0]{1}; double hrsV_ATT_U1 = result[1]{0}; double hrsV_ATT_L1 = result[2]{0}; double hrsV_ATT_U2 = result[3]{0}; double hrsV_ATT_L2 = result[4]{0}; double hrsV_ATT_U3 = result[5]{0}; double hrsV_ATT_L3 = result[6]{0}; double hrsV_ATT_U4 = result[7]{0}; double hrsV_ATT_L4 = result[8]{0}; double[] hrsV_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; // result = ConfigurationReader("name_delays",["hrs_config_delay"],band,0.0); int hrs_config_delay = iround(result[0]{0}); //Convert IF frequencies into A and M parameters //Truncate wb keyword: string[] output_hrs_mode = GetHrsMode_proc_fm(hrs_mode); string hrs_mode_h = output_hrs_mode[0]; string hrs_mode_v = output_hrs_mode[1]; // int[] a_m_parameter = ComputeA_M_parameters([hrs_mode_h,hrs_mode_v],hrsH_LO[0],hrsH_LO[1],hrsH_LO[2],hrsH_LO[3],hrsH_LO[4],hrsH_LO[5],hrsH_LO[6],hrsV_LO[0],hrsV_LO[1],hrsV_LO[2],hrsV_LO[3],hrsV_LO[4],hrsV_LO[5],hrsV_LO[6]); //H-polar int hrsH_LO1_M = a_m_parameter[1]; int hrsH_LO1_A = a_m_parameter[0]; int hrsH_LO2_M = a_m_parameter[3]; int hrsH_LO2_A = a_m_parameter[2]; int hrsH_LO3_M = a_m_parameter[5]; int hrsH_LO3_A = a_m_parameter[4]; int hrsH_LO4_M = a_m_parameter[7]; int hrsH_LO4_A = a_m_parameter[6]; int hrsH_LO5_M = a_m_parameter[9]; int hrsH_LO5_A = a_m_parameter[8]; int hrsH_LO6_M = a_m_parameter[11]; int hrsH_LO6_A = a_m_parameter[10]; int hrsH_LO7_M = a_m_parameter[12]; Hifi_HIFI_Config_HRS_H_att_lo($BBID,hrs_polarization_h,hrsH_ATT_U1,hrsH_ATT_L1,hrsH_ATT_U2,hrsH_ATT_L2,hrsH_ATT_U3,hrsH_ATT_L3,hrsH_ATT_U4,hrsH_ATT_L4,hrsH_LO1_M,hrsH_LO1_A,hrsH_LO2_M,hrsH_LO2_A,hrsH_LO3_M,hrsH_LO3_A,hrsH_LO4_M,hrsH_LO4_A,hrsH_LO5_M,hrsH_LO5_A,hrsH_LO6_M,hrsH_LO6_A,hrsH_LO7_M); // //delay(hrs_config_delay); //V-polar int hrsV_LO1_M = a_m_parameter[14]; int hrsV_LO1_A = a_m_parameter[13]; int hrsV_LO2_M = a_m_parameter[16]; int hrsV_LO2_A = a_m_parameter[15]; int hrsV_LO3_M = a_m_parameter[18]; int hrsV_LO3_A = a_m_parameter[17]; int hrsV_LO4_M = a_m_parameter[20]; int hrsV_LO4_A = a_m_parameter[19]; int hrsV_LO5_M = a_m_parameter[22]; int hrsV_LO5_A = a_m_parameter[21]; int hrsV_LO6_M = a_m_parameter[24]; int hrsV_LO6_A = a_m_parameter[23]; int hrsV_LO7_M = a_m_parameter[25]; Hifi_HIFI_Config_HRS_V_att_lo($BBID,hrs_polarization_v,hrsV_ATT_U1,hrsV_ATT_L1,hrsV_ATT_U2,hrsV_ATT_L2,hrsV_ATT_U3,hrsV_ATT_L3,hrsV_ATT_U4,hrsV_ATT_L4,hrsV_LO1_M,hrsV_LO1_A,hrsV_LO2_M,hrsV_LO2_A,hrsV_LO3_M,hrsV_LO3_A,hrsV_LO4_M,hrsV_LO4_A,hrsV_LO5_M,hrsV_LO5_A,hrsV_LO6_M,hrsV_LO6_A,hrsV_LO7_M); // delay(hrs_config_delay); //////////////////////////////////////////////////////////////////// //Now Configure blocks //H-polar result = ConfigurationReader(hrs_filename_h,["hrh_block_1","hrh_block_2","hrh_block_3","hrh_block_4","hrh_block_5","hrh_block_6","hrh_block_7","hrh_block_8"],band,0.0); string hrh_block_1 = result[0]{1}; string hrh_block_2 = result[1]{1}; string hrh_block_3 = result[2]{1}; string hrh_block_4 = result[3]{1}; string hrh_block_5 = result[4]{1}; string hrh_block_6 = result[5]{1}; string hrh_block_7 = result[6]{1}; string hrh_block_8 = result[7]{1}; // Hifi_HIFI_Config_HRS_H_blocks($BBID,hrh_block_1,hrh_block_2,hrh_block_3,hrh_block_4,hrh_block_5,hrh_block_6,hrh_block_7,hrh_block_8); //delay(hrs_config_delay); // //V-polar result = ConfigurationReader(hrs_filename_v,["hrv_block_1","hrv_block_2","hrv_block_3","hrv_block_4","hrv_block_5","hrv_block_6","hrv_block_7","hrv_block_8"],band,0.0); string hrv_block_1 = result[0]{1}; string hrv_block_2 = result[1]{1}; string hrv_block_3 = result[2]{1}; string hrv_block_4 = result[3]{1}; string hrv_block_5 = result[4]{1}; string hrv_block_6 = result[5]{1}; string hrv_block_7 = result[6]{1}; string hrv_block_8 = result[7]{1}; // Hifi_HIFI_Config_HRS_V_blocks($BBID,hrv_block_1,hrv_block_2,hrv_block_3,hrv_block_4,hrv_block_5,hrv_block_6,hrv_block_7,hrv_block_8); // //Wait delay to allow all setting to be configured delay(hrs_config_delay); } // Needs the chopper in open-loop mode !! block Chopper_closed_loop_parameter_check_block_fm HIFI 3695 { }{ Start_block(); //Move chopper to 0V double targetAngle = 0.0; HIFI_CPR_Chopper_Rot_proc_fm(targetAngle); Hifi_HIFI_non_periodic_hk_FCU(); //To get sent voltage delay(1); // //Go to -7.09V and monitor short term stabilisation int milliSecSample = 3; // interval between samples int samplesBefore = 50; int samplesAfter = 1000; targetAngle = -7.09; Engineering_scan_for_closed_loop_scan(targetAngle,milliSecSample,samplesBefore,samplesAfter); // //Monitor chopper position while staying at -7.09V milliSecSample = 10; // interval between samples //This special procedure does not change prime angles into red angles Engineering_scan_for_closed_loop_scan(targetAngle,milliSecSample,samplesBefore,samplesAfter); // //Move chopper to 0V targetAngle = 0.0; HIFI_CPR_Chopper_Rot_proc_fm(targetAngle); Hifi_HIFI_non_periodic_hk_FCU(); //To get sent voltage delay(1); // //Move to -0.37 and monitor short term stabilisation milliSecSample = 3; // interval between samples targetAngle = -0.37; //This special procedure does not change prime angles into red angles Engineering_scan_for_closed_loop_scan(targetAngle,milliSecSample,samplesBefore,samplesAfter); // //Move back to rest position: this one depends on prime/red {double,string}[] result_d = ConfigurationReader("name_chopper",["chop_startup_cold"],"0",0.0); targetAngle = result_d[0]{0}; HIFI_CPR_Chopper_Rot_proc_fm(targetAngle); Hifi_HIFI_non_periodic_hk_FCU(); //To get sent voltage delay(1); } // Compute effective fluctuation bandwidth determining the // radiometric noise from the selected resolution {double,double} procedure EffectiveResolution { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Selected min./max. goal resolution of calibrated data bool resolutionMhz = true; //whether resolution is given in MHz or in km/s bool wbs1used = true; // WBS1 to be used bool wbs2used = true; // WBS2 to be used {bool,int} hrs1 = {true,1}; // {HRS1 to be used, resolution} {bool,int} hrs2 = {true,1}; // {HRS2 to be used, resolution} }{ // translate to Mhz is required double lightspeed = 300000.0; // km/s if(resolutionMhz) { double resol_hi = effResolution{0}; double resol_lo = effResolution{1}; } else { resol_hi = effResolution{0} * lo_freq / lightspeed; resol_lo = effResolution{1} * lo_freq / lightspeed; } // compute fluctuation bandwidth from selected resolution // 1. physical resolutions used // build up list of available resolutions double[] physres_list = [0.0]; double[] fluctratio_list = [0.0]; bool[] ishrs_list = [false]; int n_resol = 0; // WBS if(wbs1used || wbs2used) { double[] res = GetBackendResolution(band,lo_freq,-1); physres_list[n_resol] = res[0]; fluctratio_list[n_resol] = res[1]; ishrs_list[n_resol] = false; n_resol = n_resol + 1; } // resolution order of HRS's if(hrs1{0} && hrs2{0}) { int lores = imax(hrs1{1},hrs2{1}); int hires = imin(hrs1{1},hrs2{1}); if(hires != lores) { res = GetBackendResolution(band,lo_freq,lores); physres_list[n_resol] = res[0]; fluctratio_list[n_resol] = res[1]; ishrs_list[n_resol] = true; n_resol = n_resol + 1; res = GetBackendResolution(band,lo_freq,hires); physres_list[n_resol] = res[0]; fluctratio_list[n_resol] = res[1]; ishrs_list[n_resol] = true; n_resol = n_resol + 1; } else { res = GetBackendResolution(band,lo_freq,lores); physres_list[n_resol] = res[0]; fluctratio_list[n_resol] = res[1]; ishrs_list[n_resol] = true; n_resol = n_resol + 1; } } else { if(hrs1{0}) { res = GetBackendResolution(band,lo_freq,hrs1{1}); physres_list[n_resol] = res[0]; fluctratio_list[n_resol] = res[1]; ishrs_list[n_resol] = true; n_resol = n_resol + 1; } if(hrs2{0}) { res = GetBackendResolution(band,lo_freq,hrs2{1}); physres_list[n_resol] = res[0]; fluctratio_list[n_resol] = res[1]; ishrs_list[n_resol] = true; n_resol = n_resol + 1; } } // Compare with desired resolutions double physres_lo = physres_list[0]; double fluctratio_lo = fluctratio_list[0]; bool ishrs_lo = ishrs_list[0]; double physres_hi = physres_list[0]; double fluctratio_hi = fluctratio_list[0]; bool ishrs_hi = ishrs_list[0]; // go from lowest resolution to highest // get parameters of backend just covering the goal for(int iresol = 1 .. n_resol - 1) { if(resol_hi < physres_list[iresol - 1]) { physres_hi = physres_list[iresol]; fluctratio_hi = fluctratio_list[iresol]; ishrs_hi = ishrs_list[iresol]; } if(resol_lo < physres_list[iresol - 1]) { physres_lo = physres_list[iresol]; fluctratio_lo = fluctratio_list[iresol]; ishrs_lo = ishrs_list[iresol]; } } // Consistency check if(resol_hi < physres_list[n_resol - 1]) { IError("The requested goal resolution cannot be achieved with the" + " selected backend settings. Increase the goal resolution" + " minimum or change the spectrometer settings."); } // Translate into fluctuation bandwidths double effresol_lo = resol_lo + physres_lo * (fluctratio_lo - 1.0); double effresol_hi = resol_hi + physres_hi * (fluctratio_hi - 1.0); // correct for finite HRS efficiency - reduce noise bandwidth double hrseffic = GetHrsEfficiency(band,lo_freq); if(ishrs_hi) { effresol_hi = effresol_hi * (hrseffic * hrseffic); } if(ishrs_lo) { effresol_lo = effresol_lo * (hrseffic * hrseffic); } // return result return {effresol_hi,effresol_lo}; } // Produce array of LO frequencies to be used in frequency clusters double[] procedure GetClusterFrequencies { double lo_freq = 978200.0; // LO frequency in MHz int groupsize = 3; // Number of frequencies in a cluster double freqstep = 120.0; // step size in a frequency cluster }{ // Use the same order as within spectral scan groups int[][] grouporder = GetFrequencyGroupSteps(groupsize); double[] freqs = []; for(int i = 0 .. groupsize - 1) { freqs[i] = lo_freq + freqstep * double(grouporder[1][i] - groupsize / 2); } return freqs; } // LO SFT, following procedure of MPI, procedure // Pre-defined frequencies and Vd2 // It is used for LOU dummy here procedure LO_SFT_proc_fm { string band = "ALL" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b","ALL"]; // HIFI band: ALL or dedicated band }{ //For the chosen band, or all band (if option ALL) // 1. switch on band (with safe d2_v) // 2. configure with dedicated d2_v string[] band_list = ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; int total = 14; if(band != "ALL") { band_list = [band]; total = 1; } // double lo_freq = 0.0; double drain2_v = 0.0; for(int i = 0 .. total - 1) { double[] cresult_d = CalibrationReader("name_keyfreq",["keyfreq","key_d2v_P","key_d2v_R","key_d2v_dummy","keyfreq_dummy","keyfreqwarm"],band_list[i],0.0); lo_freq = cresult_d[0]; //applies to cold LO //lo_freq = cresult_d[4]; //applies to dummy LO //lo_freq = cresult_d[5]; //applies to warm LO //Switch on with safe Vd2 LCU_switchon_proc_fm(band_list[i]); //LO freq and Vd2 to use is embedded in the proc //Wait total of 20 sec. delay(20); //Check what d2_v to use depending on test circumstances drain2_v = cresult_d[1]; //Value for prime case, and fm H/W // {double,string}[] result = ConfigurationReader("name_chopper",["prime_or_redundant","fm_or_dummy"],"0",0.0); // if(result[0]{1} == "redundant") { drain2_v = cresult_d[2]; } if(result[1]{1} == "dummy") { drain2_v = cresult_d[3]; lo_freq = cresult_d[4]; } // LCU_config_nominal_w_D2_proc_fm(band_list[i],lo_freq,drain2_v); } //Switch off LO at end of test only if ALL option selected if(band == "ALL") { LCU_switch_off_block_fm(); } } //Readback of LCU Memory Patch, block block LcuMemoryPatchReadback_ops HIFI 7903 { string section = "P" in ["P","R"]; }{ StartBlock_ops(); // //{int, int[]} [] runs = LcuGetMemoryRuns_ops( section); {int,int[]}[] runs = LcuGetMemoryRuns(section,1); int runcount = length(runs); if(runcount != 0) { for(int i = 0 .. runcount - 1) { int count = length(runs[i]{1}); Hifi_HIFI_dump_memory("LCU",runs[i]{0},count); // delay( iceil( double( count ) *.003 ) ); // 3 msec per word readout // Workaround delay(2 + iceil(double(count) * 0.0030)); // 3 msec per word readout } //Complement the number of TCs sent to reach the fixed TC pattern needed for TPF int nb_TC_needed = 50; int remaining_TC = nb_TC_needed - runcount; mois_comment("The following " + remaining_TC + " TCs are dummy repetition of the first memory dump command"); // for(int ii = 1 .. remaining_TC) { Hifi_HIFI_dump_memory("LCU",runs[0]{0},length(runs[0]{1})); delay(2 + iceil(double(count) * 0.0030)); // 3 msec per word readout } } } // Very fast sampling stability measurement, procedure // Uses only the HRS in wb mode procedure Stability_fast_proc_fm { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band int n = 100; //Number of samples to be measured double[] hrs_subband = [5.0,5.0,5.0,5.0]; //Positions in IF of HRS sub-bands double sampling_rate = 2.0 in [1.0,6.0]; //Sampling rate: 2 (2 HRS-H + 2 HRS-V), 3 (HRS-H + HRS-V), 4 (2 HRS-H or 2 HRS-V) or 6 (1 HRS-H or 1 HRS-V) Hz string hrs_polarization = "H" in ["H","V","B"]; //HRS polarization: selection works only for 4 and 8 Hz }{ //Configure HRS: regardless of selected bands HRS_config_resol_block_fm(band,["wb1","wb1"]); HRS_config_att_lo_w_lo_input_block_fm(band,["wb1","wb1"],hrs_subband); //Tune backend on cold load Chopper_Rotation_block_fm(band,"chop_M3_ang","chop_cold_ang"); //Look at CBB HRS_tune_block_fm(band); //The following will configure spectroscopy and start total power integration Stability_fast_block_fm(band,n,sampling_rate,hrs_polarization); // } // Check whether the input frequencies are allowed procedure CheckLOFrequencies { string band = "4a"; // HIFI band double lo_freq_low = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz }{ {double,double} bandlimits = GetBandLimits(band); if(lo_freq_low < bandlimits{0} || lo_freq_up < lo_freq_low || lo_freq_up > bandlimits{1}) { IError("Frequencies fall outside of the selected LO band."); } } ///////////////////////////////////////////////////////////////////////////// // The tuning blocks // // Initial tuning of the instrument procedure TuneHIFI { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {bool,int,double[],bool[]} hrs1parms = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets,subbands used} {bool,int,double[],bool[]} hrs2parms = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets,subbands used} bool wbs1parms = true; // WBS1 parameter =used bool wbs2parms = true; // WBS2 parameter =used string level = "normal"; // Name of target level }{ // Switch to high HK rate HIFISetHK("fast",true); ConfigureFPU(band,lo_freq,true); ConfigureBackend(band,lo_freq,hrs1parms,hrs2parms); HIFITune(band,lo_freq,hrs1parms{0},hrs2parms{0},wbs1parms,wbs2parms,level); // Switch to standard HK rate HIFISetHK("normal",true); } //////////////////////////////////// // Configuration routines /////////////////////////////////// //Generic procedure to configure the FPU using the adequate instrument side procedure HIFI_Configure_FCU_proc_aot { int band_nb = 0; // HF_CPR_MXBAND int diplex_h_ctrl_mode = 227; // HF_CV1_DPFPP1 double volt_H_FIF_1 = 0.075; // HF_CH2_FIF1_Drain_V double curr_H_FIF_1 = 0.5; // HF_CH2_FIF1_Drain_C double volt_H_FIF_2 = 0.075; // HF_CH2_FIF2_Drain_V double curr_H_FIF_2 = 0.5; // HF_CH2_FIF2_Drain_C double volt_H_SIF_1 = 0.075; // HF_CH2_SIF1_Drain_V double curr_H_SIF_1 = 0.5; // HF_CH2_SIF1_Drain_C double volt_H_SIF_2 = 0.075; // HF_CH2_SIF2_Drain_V double curr_H_SIF_2 = 0.5; // HF_CH2_SIF2_Drain_C double volt_H_SIF_3 = 0.075; // HF_CH2_SIF3_Drain_V double curr_H_SIF_3 = 0.5; // HF_CH2_SIF3_Drain_C int diplex_v_ctrl_mode = 227; // HF_CV1_DPFPP1 double volt_V_FIF_1 = 0.075; // HF_CV2_FIF1_Drain_V double curr_V_FIF_1 = 0.5; // HF_CV2_FIF1_Drain_C double volt_V_FIF_2 = 0.075; // HF_CV2_FIF2_Drain_V double curr_V_FIF_2 = 0.5; // HF_CV2_FIF2_Drain_C double volt_V_SIF_1 = 0.075; // HF_CV2_SIF1_Drain_V double curr_V_SIF_1 = 0.5; // HF_CV2_SIF1_Drain_C double volt_V_SIF_2 = 0.075; // HF_CV2_SIF2_Drain_V double curr_V_SIF_2 = 0.5; // HF_CV2_SIF2_Drain_C double volt_V_SIF_3 = 0.075; // HF_CV2_SIF3_Drain_V double curr_V_SIF_3 = 0.5; // HF_CV2_SIF3_Drain_C string chop_sine_s = "ON" in ["OFF","ON"]; // HF_CPR_CH_SINE_S string chop_loop = "CLOSE" in ["CLOSE","OPEN"]; // HF_CPR_CH_LOOP_S int chop_G1 = 0; // HF_CPR_CHFPG1 int chop_G2 = 0; // HF_CPR_CHFPG2 int chop_Z1 = 0; // HF_CPR_CHFPZ1 int chop_Z2 = 0; // HF_CPR_CHFPZ2 int chop_P2 = 0; // HF_CPR_CHFPP2 double calibcurrent = 0.0; // HF_CPR_Cal_Heater_C double bias_H = 0.0; // HF_CH1_MXBIAS_V double magnetcurrent_H = 0.0; // HF_CH1_MX_MG_C double bias_V = 0.0; // HF_CV1_MXBIAS_V double magnetcurrent_V = 0.0; // HF_CV1_MX_MG_C double chopper = -4.0 in [-8.88,8.5]; // HF_CPR_Chopper_Rot double diplex_H = 0.0; // HF_CH1_DPACT_C double diplex_V = 0.0; // HF_CV1_DPACT_C }{ //check prime or redundant keyword {double,string}[] result_d = ConfigurationReader("name_chopper",["prime_or_redundant"],"0",0.0); if(result_d[0]{1} == "prime") { Hifi_HIFI_P_Configure_FCU($BBID,band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); } else { Hifi_HIFI_R_Configure_FCU($BBID,band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); } // } // HIFI goto SAFE, procedure // procedure HIFI_goto_SAFE_fm { }{ Hifi_HIFI_goto_safe(); {double,string}[] result = ConfigurationReader("name_delays",["stdby_delay","wbs_config_delay","hrs_config_delay","config_fpu_delay"],"0",0.0); delay(iround(result[0]{0} + result[1]{0} + result[2]{0} + result[3]{0})); } ///////////////////////////////////////////////////////////////// // Slow chop dual beam switch observing mode // // Implemented as procedure returning time and noise levels for HSPOT {string,double,double}[] procedure HifiPointProcDBSSequencerInit { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_switch_on = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per pointing int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // Get the drift parameters to compute the drift noise {double,double} phaselengths = DBSPhaseLengths(band,lo_freq,effResolution,continuumDetection,oneGHzReference); // Compute derived quantities int data_time_guess = imin(imax(iceil(phaselengths{1}),datalimit),20); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } int n_switch_on_guess = imax(iceil(phaselengths{0} / (2.0 * double(data_time_guess))),1); int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } // Add pointing requirements condition: >=10s {int,int} new_data_time = MatchMinPointing(data_time_guess,data_time_range,2 * n_switch_on_guess); data_time_guess = new_data_time{0}; data_time_range = new_data_time{1}; // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)}]; return retvalues; } //HIFI-COP-2.1-CPR-RespTime obs HifiEng_Chopper_Response_time_COP { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Chopper_Response_time_COP_proc_ops(prime_or_redundant)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Chopper_Response_time_COP_proc_ops(prime_or_redundant); } if(state[0] == 5) { HIFISetHK("normal",true); StopMode_block_ops(); } } } //////////////////////////////////// // DBS raster observing mode - special version for Jupiter // // Return time and noise levels {int,double,double,double,double,double} obs HifiMappingProcJupiterDBSRaster { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source {double,double} lineDistance = {0.0050,0.0050}; // Distance between subsequent rows int nlines = 1 in [1,100]; // Number of rows in the map double stepsize = 0.0050 in [5.5556E-4,0.13333]; // Distance between subsequent points in the raster line int npoints = 10 in [2,100]; // Number of points per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_switch_on = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Engineering - Jupiter - DBS Raster Map slowChop",{data_time,0,0,n_switch_on,0,0,n_pointsperscan,0,n_cycles,load_interval}); // Call first part of the timing computer // Two changes relative to the normal DBS raster // 1) The longer load duration is enforced by zero resolution {double,double} loadResolution = {0.0,effResolution{1}}; // 2) I assume that the tuning duration does not depend on the tuning level // so that the normal pre_timing can be reused. {int,int,int,int,int,int,int,int,int,int,int,int,int} pre_timing = DBSRaster_pre_timing(nlines,npoints,band,lo_freq,loadResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_switch_on,n_pointsperscan,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; // Check for NoddingInRaster or NoddingOfRaster int scansize = pre_timing{10}; if(scansize > 1) { {int,int,int,string,int,double,double,bool,double,double,double,int,int,double,double,int,int,double,double,int,int,int,int,int} tmpar = DBSMultiRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",pre_timing,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = nodding_of_raster_pointing(false,tmpar{0},tmpar{1},tmpar{2},tmpar{3},tmpar{4},tmpar{5},tmpar{6},tmpar{7},tmpar{8},tmpar{9},tmpar{10},tmpar{11},tmpar{12},tmpar{13},tmpar{14},tmpar{15},tmpar{16},tmpar{17},tmpar{18},tmpar{19},tmpar{20},tmpar{21},tmpar{22},tmpar{23}); } else { {int,int,int,string,int,double,double,bool,double,double,double,int,int,double,double,int,int,int,double,double,int,int,int,double,double,int,int,int,int} tpar = DBSRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",pre_timing,n_cycles); telescopetimes = nodding_raster_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23},tpar{24},tpar{25},tpar{26},tpar{27},tpar{28}); } ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,int},bool,double,double} post_timing = DBSRaster_post_timing(pre_timing,telescopetimes,nlines,npoints,n_switch_on,n_cycles,load_interval,false); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command if(scansize > 1) { tmpar = DBSMultiRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",post_timing{1},n_cycles); // Call telescope command telescopetimes = nodding_of_raster_pointing(true,tmpar{0},tmpar{1},tmpar{2},tmpar{3},tmpar{4},tmpar{5},tmpar{6},tmpar{7},tmpar{8},tmpar{9},tmpar{10},tmpar{11},tmpar{12},tmpar{13},tmpar{14},tmpar{15},tmpar{16},tmpar{17},tmpar{18},tmpar{19},tmpar{20},tmpar{21},tmpar{22},tmpar{23}); } else { tpar = DBSRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",post_timing{1},n_cycles); telescopetimes = nodding_raster_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23},tpar{24},tpar{25},tpar{26},tpar{27},tpar{28}); } // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{3}; int n_load = post_timing{1}{6}; int n_loadinterval = post_timing{1}{7}; int n_seq = post_timing{1}{8}; int initlength = post_timing{1}{11}; int dangling = post_timing{1}{12}; bool final_load = post_timing{2}; double tscan = post_timing{3}; double tdead = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { JupiterDBSRaster_commanding(band,lo_freq,loadResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_seq,n_cycles,scansize,n_loadinterval,n_load,final_load,startobs,telescopetimes,loadlength,false); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double} tact = DBSRaster_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_seq,n_load,scansize,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = DBS_noisecomputer(band,lo_freq,effResolution,continuumDetection,oneGHzReference,n_cycles,tscan,tact); // Evaluate performance DBSRaster_performance(band,lo_freq,effResolution,noisevalues,timeTaken,nlines,npoints,n_cycles,n_seq * imax(n_load,1),tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // FPU settling time for a mixer band change, 1st block // Block for first tuning block FPU_Settling_time_first_tuning_fm HIFI 3683 { string band_1 = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band int int_time1 = 3600; //Integration time after first tuning double lo_freq_1 = 500.0; //LO frequency in sub-band a string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); // //Tune of LO. We must use: configuration from safe to tuned. LCU_config_nominal_proc_fm(band_1,lo_freq_1); LO_tuning_w_mixerchoice_proc(band_1,lo_freq_1,"H"); // //Configure spectroscopy integration Configure_Spectrometer_proc_fm(band_1,int_time1,["wb1","wb1"],backend); //4 sec. integration //Take series of spectra during int_time1 seconds HIFI_Spectr_total_power_proc_fm(band_1,backend,int_time1); // //Now switch off LO sub-band LCU_switch_off_proc_fm(); } // Continuous HIFI integration with given backend settings at source block HIFIContOnIntegration HIFI 6022 { int n_int = 1; // Integration time counter int data_time = 4; // Integration time between two data readouts double[] rates = [120.0,1.0,2.0]; // Data rates between and during integrations }{ HIFI_Spectr_tp_proc_aot(n_int,data_time,rates); } ////////////////////////////////////////////////////////////////////////// // Procedure to compute detailed timing of DBS-raster observing mode {int,int,int,int,int,int,int,int,int,int,int,int,int} procedure FastDBSRaster_pre_timing { int nlines_tot = 1 in [1,100]; // Number of rows in the map int npoints = 10 in [2,100]; // Number of points per row string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 10 in [4,80]; // data dump interval int n_int = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_data = 1 in [1,1800]; // number of data transfer cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // First check validity of frequencies CheckLOFrequencies(band,lo_freq,lo_freq); // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Fixed timings in the fast-chop mode int readouttime = data_time; int load_datatime = GetStdLoadReadout(band,lo_freq); // It should be investigated wehther we can use fast-chop on loads as well // Perform consistency checks int single_data = data_time / 2; // Check chunk size given by the data rates CheckDataTaking(backendreadoutparms,single_data); // Check chopper frequency CheckFastChopFrequency(band,lo_freq,data_time,n_int,n_data); // Is the map size an integer multiple of the scan size? CheckReasonableLineNumber(nlines_tot * npoints,false); int scansize = n_pointsperscan; if(scansize > nlines_tot * npoints) { SError("Scan size exceeds the total map size."); } if(nlines_tot * npoints % scansize != 0) { SError("Map size is no integer multiple of the scan size."); } int n_scans = nlines_tot * npoints / scansize; // Compute parameters for the instrument timing int jitterdead = GetMaxTimeJitter(band,lo_freq); int inttime = readouttime * n_data; // compute load integration time int loadlength = duration(LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms)); int readoutdead = FastChopReadoutDelay(band,lo_freq,backendreadoutparms); loadlength = loadlength + readoutdead; // Duration of initial set up // determine exact duration only in case of full commanding if(docommands) { int initlength = duration(HIFIInitObs()); initlength = initlength + duration(TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal")); // Add time for HK readout int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,true); initlength = initlength + hkduration; } else { initlength = GetRoughInitLength(band,lo_freq,false); } initlength = initlength + loadlength; // compute the load interval in case of short scan_time int scan_time = inttime * scansize; int n_loadinterval = imax(load_interval / scan_time,1); // Special treatment for nodding_raster due to limitations in API // Split into loads per point or per multiple points if(scansize == 1 && n_loadinterval > n_cycles) { n_loadinterval = n_cycles * (n_loadinterval / n_cycles); } n_loadinterval = imin(n_loadinterval,n_cycles * n_scans); // Compare load interval and nodding interval int load_spacing = CheckedLoadSpacing(load_interval - loadlength,8); if(load_spacing < readouttime) { SError("Load period shorter than backend readout period."); } // load measurements within a single point integration int n_load = inttime / load_spacing; if(n_load >= 1 && scansize > 1) { SError("Number of points in one scan too large for load period."); } // Rough estimate of the pointing time - this is corrected // after the evaluation of the telescope command if(load_spacing > 2 * scan_time) { int n_seq = n_data; int pointing = inttime + jitterdead; } else { // It is possible that a single point is short enough, but a scan // too long. Then everything is reduced to a single point. scansize = 1; n_scans = nlines_tot * npoints; n_seq = n_data / (n_load + 1); inttime = n_seq * (n_load + 1) * readouttime; pointing = inttime + (n_load + 1) * loadlength + jitterdead; } // dangling time given by readout dead time int dangling = readoutdead; int holdlength = jitterdead; // Return all the times needed for telescope call and post_timing processing return {inttime,pointing,readouttime,loadlength,holdlength,load_spacing,n_load,n_loadinterval,n_seq,n_scans,scansize,initlength,dangling}; } //Imix characterisation for HEB block HEB_Imix_calibration_block_fm HIFI 3918 { string band = "6a" in ["6a","6b","7a","7b"]; // HIFI band double lo_freq = 1520.0; //LO frequency }{ string tab = "config_HEB_Imix.config"; double bandnb = GetBandCode(band); double lofreq_imixcal = dlookup(tab,"" + iround(bandnb),"frequency"); double idip1 = dlookup(tab,"" + iround(bandnb),"idip1"); double beta = dlookup(tab,"" + iround(bandnb),"beta"); double length_dip = dlookup(tab,"" + iround(bandnb),"length"); int step = ilookup(tab,"" + iround(bandnb),"step"); // //Compute Idip2 according to model double idip2 = min(1.1 * (150.0 / lo_freq) * (180.0 / (3.1415 * beta * length_dip)),2.24); // {double,string}[] result = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,lo_freq); int ivc_step = 40; //Allows one single pass //Loop on diplexer currents double idip = idip1; for(int i = 1 .. step) { Set_Diplexer_current_proc_fm(idip,idip); //IVC between 3.5 and 0.5mV double ivc_start = 3.5; double ivc_end = 0.5; double step_duration = 0.1; double stepsize = Stepsize(min(ivc_start,ivc_end),max(ivc_start,ivc_end),ivc_step - 1,"hifi_HIF_mxbias_step_V"); double margin = Stepmargin(min(ivc_start,ivc_end),max(ivc_start,ivc_end),"hifi_HIF_mxbias_step_V"); Hifi_HIFI_FCU_parameter_scan($BBID,ivc_step,1,step_duration,ivc_start,ivc_start,-1.0 * (stepsize + margin),0.0,0.0,0.0); int duration_ivcurve = iceil(double(ivc_step) * step_duration); delay(duration_ivcurve + 2); //Increase idip idip = double(i) * (idip2 - idip1) / double(step - 1); } } //Slow chop between sky and HBB, block block Sky_Hot_fm_COP HIFI 3929 { string band = "1a"; int integ_time = 4; //Total integration time for delay computation string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4,etc string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast }{ //Fetch respective chopper angles {double,string}[] result = ConfigurationReader("name_confilfpu",["chop_M3","chop_hot"],band,0.0); double chop_M3 = result[0]{0}; double chop_hot = result[1]{0}; // //Compute data-rate double[] rates = ILT_datarate_proc_fm(band,backend,"slowchop",integ_time); //Take spectrum // set data rates non_ess_hk_data_rate(rates[2] / 1024.0); data_rate(rates[0] / 1024.0); // HIFI_Spectr_slow_chop_proc_fm(chop_hot,chop_M3); Apply_Slow_Chop_delay(integ_time,band,backend); // reset data rates non_ess_hk_data_rate(rates[1] / 1024.0); data_rate(0.0); } // Integrate with IF1 off, block // We take 1 spectrum per phase. block Stability_IF_system_fm HIFI 3422 { string band = "1a"; // HIFI band int n = 100; //The number of integrations int integ_time = 4; //Total integration time in sec. to be set at end of test string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code }{ Start_block(); //The system as is should be ready //No use of FPU capabilities. // //Do a long integration: 4 sec. is OK //We implement a special spectroscopy configuration with fixed values Total_power_spectro_for_Stability_proc_fm(band,n,integ_time,backend,hrs_mode); } ////////////////////////////////////////////////////////////////////// // Procedure to display performance parameters of the observing mode procedure SingleChopNoRef_performance { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {double,double,double,double,double} noisevalues = {1.0,1.0,1.0,1.0,0.0}; // Noise values from noisecomputer int totaltime = 200; // Total observing time int n_chop_on = 1; // number of half load-sky-sky-load cycles on ON bool fs = false; // whether frequency switch used double tscan = 10.0; // Total average duration of one scan double tdead = 0.05; // Average dead time in one chop cycle }{ // Get performance of ideal instrument for comparison {int,double,double,double,double,double} idealvalues = IdealInstrument(band,lo_freq,eff_resolution,totaltime); double idealnoise = idealvalues{1} * idealvalues{1}; double obsnoise = noisevalues{0} * noisevalues{0}; double efficiency = idealnoise / obsnoise; // Compute the actual integration time double inttime = (tscan - tdead) / 2.0; double posinttime = double(n_chop_on) * 2.0 * inttime; double posofftime = 0.0; // Check total integration time double timeefficiency = (posinttime + posofftime) / double(totaltime); // Noise contribution double relnoise = noisevalues{4} / (1.0 + noisevalues{4}); // General messages PerformanceMessages(band,lo_freq,totaltime,posinttime,posofftime,timeefficiency,efficiency,relnoise,fs); } ////////////////////////////////////////////////////////////////////// // Determine data readout period and corresponding data rate // External wrapper to determine automatically the WBS bit size {int,double[]} procedure DataTaking { {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // Readout parameters for HRS1,HRS2, WBS1,WBS2 int data_time = 4; // Integration time between two data readouts }{ // 16 bit format for short integrations int wbs16bitlimit = 5; if(data_time <= wbs16bitlimit) { bool mode16bit = true; } else { mode16bit = false; } {int,double[]} dataparms = AllDataRates(backendreadoutparms,data_time,mode16bit); return dataparms; } ///////////////////////////////////////// // Testmodes for handling of LCU safety // tables and memory patches // AdJ - 17-08-2006 // Reviewed on 13-10-2006 to solve SPR 0866 // Reviewed on 06-11-2006 to include memory patching // Reviewed on 20-06-2007 flight procedure limit of 999 command parameters ///////////////////////////////////////// //modes: see fm_testmodes.cus ////////////////////////////////////// // blocks ////////////////////////////////////// //Upload of LCU safety table, block block LcuSafetyTableUpload_fm HIFI 3900 { int start = 0; // first table entry to upload (count from zero) int count = 0; // maximum number of table lines to upload }{ //Start_block(); string section = GetLcuSection(); string tab = "LcuSafetyTable_" + section + ".config"; int total = imin(table_size(tab),start + count); int done = start; if(total > 0) { int[] allIndices = icolumn(tab,"tableindex"); int[] allValues = icolumn(tab,"value"); int[] index = []; int[] value = []; int next = 0; while(done < total) { for(int i = 0 .. 24) { next = imin(done,total - 1); index[i] = allIndices[next]; value[i] = allValues[next]; done = done + 1; } Hifi_HIFI_Configure_LCU_table($BBID,index[0],value[0],index[1],value[1],index[2],value[2],index[3],value[3],index[4],value[4],index[5],value[5],index[6],value[6],index[7],value[7],index[8],value[8],index[9],value[9],index[10],value[10],index[11],value[11],index[12],value[12],index[13],value[13],index[14],value[14],index[15],value[15],index[16],value[16],index[17],value[17],index[18],value[18],index[19],value[19],index[20],value[20],index[21],value[21],index[22],value[22],index[23],value[23],index[24],value[24]); delay(1); } } } //Set DC bias without switching on the chain, block //All input parameters shall be given by the user block Conf_diag_LCU_block_fm HIFI 3662 { string band = "1a" in ["ALL","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double plevel_v = 0.0; // HL_PL_C double m1_v = 0.0; // HL_M1_V double m2_v = 0.0; // HL_M2_V double m3_v = 0.0; // HL_M3_V double gate1_v = 0.0; // HL_Gate1_V double gate2_v = 0.0; // HL_Gate2_V double drain1_v = 0.0; // HL_Drain1_V string curlim1_v = "1.5" in ["1.5","1.3","1.22","1.4"]; // HL_Curlim1 double drain2_v = 0.0; // HL_Drain2_1A_V string curlim2_v = "1.5" in ["1.5","1.3","1.22","1.4"]; // HL_Curlim2 }{ // //Start_block(); // //Execute configuration //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Conf_diag_LCU_ch1a($BBID,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "1b") { //Band 1b Hifi_HIFI_Conf_diag_LCU_ch1b($BBID,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "2a") { //Band 2a Hifi_HIFI_Conf_diag_LCU_ch2a($BBID,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "2b") { //Band 2b Hifi_HIFI_Conf_diag_LCU_ch2b($BBID,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "3a") { //Band 3a Hifi_HIFI_Conf_diag_LCU_ch3a($BBID,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "3b") { //Band 3b Hifi_HIFI_Conf_diag_LCU_ch3b($BBID,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "4a") { //Band 4a Hifi_HIFI_Conf_diag_LCU_ch4a($BBID,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "4b") { //Band 4b Hifi_HIFI_Conf_diag_LCU_ch4b($BBID,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "5a") { //Band 5a Hifi_HIFI_Conf_diag_LCU_ch5a($BBID,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "5b") { //Band 5b Hifi_HIFI_Conf_diag_LCU_ch5b($BBID,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "6a") { //Band 6a Hifi_HIFI_Conf_diag_LCU_ch6a($BBID,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "6b") { //Band 6b Hifi_HIFI_Conf_diag_LCU_ch6b($BBID,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "7a") { //Band 7a Hifi_HIFI_Conf_diag_LCU_ch7a($BBID,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } if(band == "7b") { //Band 7b Hifi_HIFI_Conf_diag_LCU_ch7b($BBID,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v); } // {double,string}[] result = ConfigurationReader("name_delays",["config_lo_delay"],"0",0.0); int config_lo_delay = iround(result[0]{0}); delay(config_lo_delay); // } ///////////////////////////////////////////////////////////////// // Procedure to compute total dead times for the mode // {double,double,double} procedure SScanDBS_deadtimes { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int grouplen = 1; // Number of frequency steps per nodding phase int data_time = 4; // chunk size int n_bchop = 1; // Normal number of chop cycles per frequency and pointing int n_long = 1; // Chop cycles per frequency and pointing without retuning int n_cycles = 1; // Number of half OFF-ON-ON-OFF cycles at one frequency double avnumchop = 1.0; // Average number of chop cycles per frequency double tdead = 10.0; // Dead time from telescope }{ ////////////////////////////////////////////////////////////////////// // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Compute parameters for the instrument timing in normal phases {double,double} tinst = GetInstDeadSlowChop(data_time,2 * n_long,"chop",band,lo_freq,backendreadoutparms); // dead time double tdeadint = double(data_time * 2 * n_long) - tinst{0}; // subtract dead times in switches // keep dead times between A-A and B-B in total dead time tdeadint = tdeadint - double(n_long) * tinst{1}; // treat integration times of other frequencies as dead time double tdeadother = double(data_time * 4 * n_long); // Store double tswitch = tinst{1}; // Integration time double tphaseint = tinst{0}; // Correcton in case of cycles with shorter integrations if(n_cycles > 1) { tinst = GetInstDeadSlowChop(data_time,2 * n_bchop,"chop",band,lo_freq,backendreadoutparms); // dead time double tdeadshort = double(data_time * 2 * n_bchop) - tinst{0}; // subtract dead times in switches tdeadshort = tdeadshort - double(n_bchop) * tinst{1}; // weigh tdeadint = (tdeadint * double(n_cycles - 1) + tdeadshort) / double(n_cycles); tphaseint = (tphaseint * double(n_cycles - 1) + tinst{0}) / (2.0 * avnumchop * double(n_cycles)); tdeadother = (tdeadother * double(n_cycles - 1) + double(data_time * 4 * n_bchop)) / double(n_cycles); } else { tphaseint = tphaseint / (2.0 * avnumchop); } // Total dead time per cycle double tdead_tot = tdead + 2.0 * tdeadint; // Add integration times of other frequencies as dead time tdead_tot = tdead_tot + double(grouplen - 1) * tdeadother; return {tdead_tot,tphaseint,tswitch}; } //HIFI LO tuning, block //Target current in entered as input parameter block LO_tuning_w_targetC_block_fm HIFI 3628 { double target_current = 1.0; //Target mixer current string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency string mixer_polarization = "H" in ["H","V"]; //The polarization to be used for the tuning }{ //Clear potential failure mode Set_LO_Nominal_proc_fm(); // //Start_block(); {double,string}[] result = ConfigurationReader("name_confpolar4lotune",[band],band,lo_freq); //mixer_polarization = result[0]{1}; //Get target mixer current: from input // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; name_configlcutune = "name_configlcutune_b"; } // result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // result = ConfigurationReader(name_configlotune,["step_drain2_v","nsteps","step_time"],band,lo_freq); double step_drain2_v = result[0]{0}; int nsteps = iround(result[1]{0}); double step_time = result[2]{0}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // //Adjust scan cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); double drain2_safe = cresult[0]; // double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); // //For all bands, scan will be done with decreasing drain2 voltages //The best guess is taken from look-up table double tune_range = 0.1; result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lo_freq); double middle_d2 = result[0]{0}; double drain2_v_start = min(middle_d2 * (1.0 + tune_range / 2.0),drain2_bluemax); double drain2_v_end = (1.0 - tune_range / 2.0) / (1.0 + tune_range / 2.0) * drain2_v_start; step_drain2_v = (drain2_v_end - drain2_v_start) / double(nsteps - 1); // result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); // //Send command HIFI_Configure_LCU_proc_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,macro_checksum,config_lo_delay); // //delay(5); //to settle at this value // //Load vector scan //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Load_vector_safe_1a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "1b") { //Band 1b Hifi_HIFI_Load_vector_safe_1b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2a") { //Band 2a Hifi_HIFI_Load_vector_safe_2a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2b") { //Band 2b Hifi_HIFI_Load_vector_safe_2b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3a") { //Band 3a Hifi_HIFI_Load_vector_safe_3a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3b") { //Band 3b Hifi_HIFI_Load_vector_nom_3b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "4a") { //Band 4a Hifi_HIFI_Load_vector_safe_4a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "4b") { //Band 4b Hifi_HIFI_Load_vector_safe_4b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "5a") { //Band 5a Hifi_HIFI_Load_vector_nom_5a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "5b") { //Band 5b Hifi_HIFI_Load_vector_nom_5b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6a") { //Band 6a Hifi_HIFI_Load_vector_nom_6a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6b") { //Band 6b Hifi_HIFI_Load_vector_nom_6b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7a") { //Band 7a Hifi_HIFI_Load_vector_nom_7a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7b") { //Band 7b Hifi_HIFI_Load_vector_nom_7b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } // delay(1); // //Execute tuning: check which mixer is to be used if(mixer_polarization == "V") { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCV($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCV($BBID,target_current); } } else { if(band == "5a" || band == "5b") { Hifi_HIFI_Tune_LO5_Using_MXCH($BBID,target_current); } else { Hifi_HIFI_Tune_LO_Using_MXCH($BBID,target_current); } } // double time_needed = double(nsteps) * step_time; delay(iround(time_needed + 2.0 + 0.5)); //0.5s added for completion of load_vector // //Store settings into available register HIFI_HL_store_tm_only_proc_fm(); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } // Global slow chop spectroscopy for stability measurement, procedure procedure Slow_chop_spectro_for_Stability_proc_fm { string band = "1a"; // HIFI band int n = 100; //The number of integrations int integ_time = 8; //Total integration time in sec. to be set at end of test string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code double chop1 = 3.4; //First chopper position double chop2 = 4.7; //Second chopper position }{ //First derive backend setting codes as expected by VO's routine //Build up backend parameter tupple: {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = BackendSettings(band,0.0,hrs_mode,backend); // Readout parameters for HRS1,HRS2, WBS1,WBS2 //Compute data_time and n_switch using the wrapper int[] res = ConfigSlowChop(integ_time,"chop",band,0.0,backendreadoutparms); int data_time = res[0]; int n_switch = n * res[1]; //For stability measurement, the number of loop is a user input // Now call the spectroscopy setup: it is common to ILT and AOT CUS. // The deadtimes output is not used at ILT level. {double,double} dtimes = ConfigSpectroscopySlowChop(data_time,n_switch,"chop",band,0.0,backendreadoutparms,true); //Compute data-rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] rates = dataparms{1}; // set data rates non_ess_hk_data_rate(rates[2] / 1024.0); data_rate(rates[0] / 1024.0); //Now start the long integration HIFI_Spectr_slow_chop_proc_fm(chop1,chop2); //Apply delays Apply_Slow_Chop_delay(data_time * n_switch,band,backend); // reset data rates non_ess_hk_data_rate(rates[1] / 1024.0); data_rate(0.0); } // Set diplexer currents for both polarizations, block block Set_Single_Diplexer_current_block_fm HIFI 3744 { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 522.0; //The LO frequency in GHz string polarization = "H" in ["H","V"]; //The polarization on which the test is done }{ //Start_block(); if(band == "3a" || band == "3b" || band == "4a" || band == "4b" || band == "6a" || band == "6b" || band == "7a" || band == "7b") { double[] result_dip = Get_Diplexer_setting(band,lo_freq); if(polarization == "H") { Hifi_HIFI_CH1_DPACT_C($BBID,result_dip[0]); } else { Hifi_HIFI_CV1_DPACT_C($BBID,result_dip[1]); } } delay(1); } // Needs the chopper in open-loop mode !! block Chopper_closed_loop_parameter_check_block_ops HIFI 7695 { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ //StartBlock_ops(); //Move chopper to 0V mois_step("Move chopper to 0V"); double targetAngle = 0.0; if(prime_or_redundant == "Prime") { Hifi_HIFI_P_Chopper_Rot($BBID,targetAngle); } else { Hifi_HIFI_R_Chopper_Rot($BBID,targetAngle); } //Hifi_HIFI_non_periodic_hk_FCU (); //To get sent voltage delay(1); mois_tmcheck("Check that parameter HF_DPR_CH_ROT is set to 0V"); //Go to -7.09V and monitor short term stabilisation int milliSecSample = 3; // interval between samples int samplesBefore = 50; int samplesAfter = 1000; targetAngle = -7.09; mois_step("Monitor chopper LVDT when moving from 0V to -7.09V"); Engineering_scan_for_closed_loop_scan_ops(targetAngle,milliSecSample,samplesBefore,samplesAfter,prime_or_redundant); //mois_tmcheck("Check arrival of TBD TM packet"); mois_tmcheck("Check that parameter HF_DPR_CH_ROT is set to -7.09V"); // //Monitor chopper position while staying at -7.09V milliSecSample = 10; // interval between samples //This special procedure does not change prime angles into red angles mois_step("Monitor chopper LVDT when stable at -7.09V"); Engineering_scan_for_closed_loop_scan_ops(targetAngle,milliSecSample,samplesBefore,samplesAfter,prime_or_redundant); // //Move chopper to 0V mois_step("Move chopper back to 0V"); targetAngle = 0.0; if(prime_or_redundant == "Prime") { Hifi_HIFI_P_Chopper_Rot($BBID,targetAngle); } else { Hifi_HIFI_R_Chopper_Rot($BBID,targetAngle); } //Hifi_HIFI_non_periodic_hk_FCU (); //To get sent voltage delay(1); mois_tmcheck("Check that parameter HF_DPR_CH_ROT is set to 0V"); // //Move to -0.37 and monitor short term stabilisation milliSecSample = 3; // interval between samples targetAngle = -0.37; //This special procedure does not change prime angles into red angles mois_step("Monitor chopper LVDT when moving from 0V to -0.37V"); Engineering_scan_for_closed_loop_scan_ops(targetAngle,milliSecSample,samplesBefore,samplesAfter,prime_or_redundant); mois_tmcheck("Check that parameter HF_DPR_CH_ROT is set to -0.37V"); // //Move back to rest position: this one depends on prime/red string chop_startup_prime_red = "chop_startup_cold_prime"; if(prime_or_redundant == "Red") { chop_startup_prime_red = "chop_startup_cold_red"; } {double,string}[] result = ConfigurationReader("name_chopper",[chop_startup_prime_red],"0",0.0); mois_step("Move chopper back to rest position"); if(prime_or_redundant == "Prime") { Hifi_HIFI_P_Chopper_Rot($BBID,result[0]{0}); } else { Hifi_HIFI_R_Chopper_Rot($BBID,result[0]{0}); } //Hifi_HIFI_non_periodic_hk_FCU (); //To get sent voltage delay(1); mois_tmcheck("Check that parameter HF_DPR_CH_ROT is set to " + result[0]{0}); // } //HRS Functional Test #0, procedure: right after switch on, BEFORE HK collection procedure HRS_functional_test_No_0_proc_ops { }{ mois_comment("Performing HRS Functional Test #0"); //Use new command implemented in SCR-859 Hifi_HIFI_HRS_functional_test($BBID,0,"BOTH"); delay(5); // } //General LO configuration command block HIFI_Configure_LCU_block_aot HIFI 6617 { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978.2; //LO frequency int freq_nx = 0; // HL_freq_nx int lsu_main = 0; // HL_LSU_main int lsu_offset = 0; // HL_LSU_offset int d2_step = 1; // HL_D2_step double plevel_v = 0.0; double m1_v = 9.0; double m2_v = -2.0; double m3_v = 0.0; double gate1_v = -2.5; double gate2_v = -2.5; double drain1_v = 2.8; string curlim1_v = "1.4"; double drain2_v = 2.6; string curlim2_v = "1.4"; int macro_checksum = 0; // HL_macro_checksum int config_lo_delay = 6; }{ //Check that Vd2 is within the blue limits drain2_v = Check_BLUE_LIMIT_D2_proc_fm(band,lo_freq,drain2_v); // // //Execute configuration //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Conf_safe_LCU_ch1a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "1b") { //Band 1b Hifi_HIFI_Conf_safe_LCU_ch1b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "2a") { //Band 2a Hifi_HIFI_Conf_safe_LCU_ch2a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "2b") { //Band 2b Hifi_HIFI_Conf_safe_LCU_ch2b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "3a") { //Band 3a Hifi_HIFI_Conf_safe_LCU_ch3a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "3b") { //Band 3b Hifi_HIFI_Conf_nom_LCU_ch3b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "4a") { //Band 4a Hifi_HIFI_Conf_safe_LCU_ch4a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "4b") { //Band 4b Hifi_HIFI_Conf_safe_LCU_ch4b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "5a") { //Band 5a Hifi_HIFI_Conf_nom_LCU_ch5a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "5b") { //Band 5b Hifi_HIFI_Conf_nom_LCU_ch5b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "6a") { //Band 6a Hifi_HIFI_Conf_nom_LCU_ch6a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "6b") { //Band 6b Hifi_HIFI_Conf_nom_LCU_ch6b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "7a") { //Band 7a Hifi_HIFI_Conf_nom_LCU_ch7a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "7b") { //Band 7b Hifi_HIFI_Conf_nom_LCU_ch7b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } // delay(config_lo_delay); // //Read TM pages and clear error flags LCU_Read_TM_pages_proc_aot(); } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the observing mode procedure JupiterFastDBS_commanding { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 10 in [4,80]; // data dump interval int n_int = 20; // number chop cycles to integrate in ICU before transfer int n_seq = 1; // Number of continuous data transfer cycles int n_load = 0; // additional load measurements in one pointing phase int n_loadinterval = 10; // number of nods before a load measurement bool end_load = false; // Need for load after each pointing phase bool final_load = false; // Need for final load measurement int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,20,1,21,0]; // Timing of the observation from telescope int loadlength = 21; // Load duration int shiftlength = 10; // Shift of the loop start relative to the pointing }{ // Auxiliary variables // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Fixed timings in the fast-chop mode int load_datatime = GetStdLoadReadout(band,lo_freq); // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time int tnodslew = telescopetimes[2]; // slew dead time between points //////////////////////////////////////////////////////////////////////// // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // // Clustering is currently not implemented in MPS - switched off here int clustered = 0; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time / 2); double[] rates = dataparms{1}; int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,true); int readoutdead = FastChopReadoutDelay(band,lo_freq,backendreadoutparms); //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; int[] choppars = [2 * n_int,0]; bool runintostate = false; while(state[0] >= 0) { if(runintostate) { state = next_state_no_check(); } else { state = next_state(); } if(state[0] == 1) { // Initialization if(clustered != 1) { HIFIInitObs(); TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"jupiter"); } delay(tinitslew - (time() - startobs) - loadlength + shiftlength - hkduration); // First load measurement HIFISetHK("normal",false); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); if(shiftlength > 0) { runintostate = true; } else { runintostate = false; } } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 3) { // First nodding position choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_seq,band,lo_freq,backendreadoutparms); // Loop for load cycles for(int i1 = 1 .. n_load) { HIFIFastChopOnIntegration(data_time,n_seq,band,lo_freq,choppars,rates); // Perform load calibration delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_seq,band,lo_freq,backendreadoutparms); } // Last cycle - no load HIFIFastChopOnIntegration(data_time,n_seq,band,lo_freq,choppars,rates); // Second phase in first nod position // occurs for even cycle numbers runintostate = false; if(state[2] % 2 == 0) { if(end_load) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); runintostate = true; } } else { // A nod slew follows - active HK if not used by load measurement if(state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } } if(state[0] == 7) { // second nod position choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_seq,band,lo_freq,backendreadoutparms); // Loop for load cycles for(int i2 = 1 .. n_load) { HIFIFastChopOffIntegration(data_time,n_seq,band,lo_freq,choppars,rates); // Perform load calibration delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_seq,band,lo_freq,backendreadoutparms); } // Last cycle - no load HIFIFastChopOffIntegration(data_time,n_seq,band,lo_freq,choppars,rates); // First phase in second nod position // occurs for odd cycle numbers runintostate = false; if(state[2] % 2 == 1) { if(end_load) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); runintostate = true; } } else { // A nod slew follows - active HK if not used by load measurement if(state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } } if(state[0] == 9) { // Load nod delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); runintostate = false; } if(state[0] == 5) { delay(readoutdead); if(final_load) { // Perform final load measurement // ( Does not occur if end_load is set) LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); } runintostate = false; HIFICloseObs(); } } } //Get maximum value for vector_scan_BLUE_LIMIT double procedure Get_BLUE_LIMIT_D2_proc_fm { string band = "4a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978.2; //LO Frequency }{ //Implementation of SCR-2220 string name_configlcu = "name_configlcu_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlcu = "name_configlcu_b"; } {double,string}[] result = ConfigurationReader(name_configlcu,["drain2_v_blmn","drain2_v_blmx"],band,lo_freq); //Fetch offset to apply to blue max double[] cresult = CalibrationReader("name_blueoffset",["blueoffset"],band,0.0); double bloff = cresult[0]; // double drain2_max = 0.0; if(band == "1a") { drain2_max = result[1]{0} - bloff; } if(band == "1b") { drain2_max = result[1]{0} - bloff; } if(band == "2a") { drain2_max = result[1]{0} - bloff; } if(band == "2b") { drain2_max = result[1]{0} - bloff; } if(band == "3a") { drain2_max = result[1]{0} - bloff; } if(band == "3b") { drain2_max = result[1]{0} - bloff; } if(band == "4a") { drain2_max = result[1]{0} - bloff; } if(band == "4b") { drain2_max = result[1]{0} - bloff; } if(band == "5a") { drain2_max = result[1]{0} - bloff; } if(band == "5b") { drain2_max = result[1]{0} - bloff; } if(band == "6a") { drain2_max = result[1]{0} - bloff; } if(band == "6b") { drain2_max = result[1]{0} - bloff; } if(band == "7a") { drain2_max = result[1]{0} - bloff; } if(band == "7b") { drain2_max = result[1]{0} - bloff; } return drain2_max; } ////////////////////////////////////////////////////////////////////////// // Procedure to compute detailed timing of OTF observing mode {int,int,int,int,bool,int,int} procedure OTFFSwitchNoRef_pre_timing { int nlines = 1; // Number of rows in the map int npoints = 10; // Number of data dumps per row string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4 in [1,20]; // chunk size given by the data rates and optimum speed int n_chop_on = 2 in [1,3600]; // number of half nu1-nu2-nu2-nu1 cycles per point int n_cycles = 1 in [1,1200]; // Number of map coverages int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // First check validity of frequencies CheckLOFrequencies(band,lo_freq + min(freq_throw,0.0),lo_freq + max(freq_throw,0.0)); // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // First perform consistency checks // Check chunk size given by the data rates CheckDataTaking(backendreadoutparms,data_time); CheckFswOutOfBand(band,lo_freq,freq_throw,backendreadoutparms); // jitter treatment is already taken into account by ValidMapSize // Compute parameters for the instrument timing int lineint = npoints * n_chop_on * 2 * data_time; int nlines_tot = nlines * n_cycles; // compute load integration time int loadlength = duration(DoubleLoadMeasurement(band,lo_freq,freq_throw,eff_resolution{0},data_time,backendreadoutparms)); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); loadlength = loadlength + readoutdead; // Compute the scan size from the load interval int load_spacing = CheckedLoadSpacing(load_interval - loadlength,npoints * 8); // Here, we do not know the turn around-time yet. Ignored until post_timing int n_loadinterval = load_spacing / lineint; if(n_loadinterval < 1) { SError("Scan duration too long for load period. " + "Reduce the number of chop cycles."); } // Make sure that load slews occur at the same position in each coverage CheckReasonableLineNumber(nlines,true); n_loadinterval = IMultiple(n_loadinterval,nlines); // If no load required parameter has to be 0 if(n_loadinterval > nlines_tot) { // Determine need for final load measurement double rest = double(nlines_tot % n_loadinterval) + 0.5; bool end_load_on = rest > 0.5001 * double(n_loadinterval); } else { if(n_loadinterval > nlines) { n_loadinterval = nlines; } // In all these cases a final load will be made anyway in regular pattern end_load_on = false; } // Duration of initial set up // determine exact duration only in case of full commanding if(docommands) { int initlength = duration(HIFIInitObs()); initlength = initlength + duration(TuneHIFIFsw(band,lo_freq,freq_throw,hrs1,hrs2,wbs1{0},wbs2{0},"normal")); // Add time for HK readout int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); initlength = initlength + hkduration; } else { initlength = GetRoughInitLength(band,lo_freq,true); } initlength = initlength + loadlength; // Dangling load measurement not counted here, only dangling readout int dangling = readoutdead; // Return all the times needed in the observing mode modules // The holdlength parameter is abused for lineint here return {loadlength,load_spacing,n_loadinterval,lineint,end_load_on,initlength,dangling}; } //Readback of LCU safety table, block block LcuSafetyTableReadback_fm HIFI 3901 { }{ Start_block(); for(int band = 1 .. 7) { for(int fIndex = 0 .. 31) { Hifi_HIFI_non_periodic_hk_LCU(fIndex,"channel_" + band + "a"); delay(2); Hifi_HIFI_non_periodic_hk_LCU(fIndex,"channel_" + band + "b"); delay(2); } } } ///////////////////////////////////////////////////////////////// // Second step of timing computation after telescope behaviour // is known - Engineering Spectral Scan DBS observing mode // // This is only needed to get the consistency checks and noise computation // {int,{int,int,int,int,int,int,int,int,int,bool,int,int,int},double,double} procedure EngSScanDBS_post_timing { {int,int,int,int,int,int,int,int,int,bool,int,int,int} pre_timing = {4,15,4,21,11,1800,22,32,1,false,0,50,0}; // pre_timing parameter list int[] telescopetimes = [300,180,20,1,21,0]; int freqnumber = 50; // Total umber of frequencies int n_cycles = 1; // Number of half OFF-ON-ON-OFF cycles at one frequency }{ // Get all values from the pre_timing section int inttime = pre_timing{0}; int pointing = pre_timing{1}; int readouttime = pre_timing{2}; int loadlength = pre_timing{3}; int jitterdead = pre_timing{4}; int load_spacing = pre_timing{5}; int bigtunestep = pre_timing{6}; int n_loadinterval = pre_timing{7}; int n_bchop = pre_timing{8}; bool end_load = pre_timing{9}; int smallstep = pre_timing{10}; int initlength = pre_timing{11}; int dangling = pre_timing{12}; // Get all values from the telescope section int telinit = telescopetimes[1]; // Initial slew time int slewtime = telescopetimes[2]; // Slew time to OFF int longslew = telescopetimes[4]; // Actual slew time for load slew int pointwaittime = telescopetimes[3]; // Idle time between two phases int tend = telescopetimes[5]; // Final deceleration time ////////////////////////////////////////////////////////////////// // Now we start the actual computations // Pointwaittime is used for tuning // In all non-tuning cycles, pointwaittime acts like a longer slew slewtime = slewtime + pointwaittime; longslew = longslew + pointwaittime; // Half tune step has to be rounded up int halftunestep = (bigtunestep - jitterdead - pointwaittime + 1) / 2; pointing = inttime + halftunestep + jitterdead; // The initial time is no longer contained in the total time initlength = initlength - halftunestep; int shiftlength = halftunestep; ////////////////////////////////////////////////////////////////////// // Compute total duration int allslews = longslew + (n_cycles - 1) * slewtime; int totaltime = freqnumber * (n_cycles * 2 * pointing + allslews); double tdead = double(allslews) / double(n_cycles); double tscan = double(2 * inttime) + tdead; ////////////////////////////////////////////////////////////////////// // Compute total duration, remove pointwaittime for last slew int closelength = duration(HIFICloseObs()); dangling = imax(dangling + closelength - tend,0); totaltime = totaltime + dangling - pointwaittime + tend; // show gyro-propagation messages int pointcycle = longslew + 2 * pointing; GCPMessages(pointing,2 * pointcycle,tend); // Return all the times needed in the observing mode modules return {totaltime,{inttime,pointing,readouttime,loadlength,jitterdead,load_spacing,bigtunestep,n_loadinterval,n_bchop,end_load,shiftlength,initlength,dangling},tscan,tdead}; } //HIFI LO tuning only for M1 investigation in 7b, block //Target current is read from look-up table block LCU_config_w_M1_block_fm HIFI 3916 { string band = "7b"; // HIFI band double lo_freq = 1890.0; //LO frequency double m1 = -5.0; //M1 multiplier voltage }{ //Clear potential failure mode Set_LO_Nominal_proc_fm(); // //Start_block(); {double,string}[] result = ConfigurationReader("name_confpolar4lotune",[band],band,lo_freq); string mixer_polarization = result[0]{1}; // //Get target mixer current result = ConfigurationReader("name_confilmix",["target_mx_c_h","target_mx_c_v"],band,lo_freq); double target_current = result[0]{0}; if(mixer_polarization == "V") { target_current = result[1]{0}; } if(mixer_polarization == "B") { target_current = 0.5 * (result[1]{0} + result[0]{0}); } // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; name_configlcutune = "name_configlcutune_b"; } // result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = m1; //result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // //multiplier settings which are not passed as input must be //taken from safe table if(band == "3b") { double[] cresult = CalibrationReader("name_lcu_safe_values",["m1_v","m2_v","m3_v"],band,lo_freq); m2_v = cresult[1]; m3_v = cresult[2]; } // cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // result = ConfigurationReader(name_configlotune,["step_drain2_v","nsteps","step_time"],band,lo_freq); double step_drain2_v = result[0]{0}; int nsteps = iround(result[1]{0}); double step_time = result[2]{0}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // //Adjust scan cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); double drain2_safe = cresult[0]; // double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); // //Maximum Vd2 will be set double drain2_v_start = drain2_bluemax; // result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); // //Send command if(band == "3b") { Hifi_HIFI_Conf_nom_LCU_ch3b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,macro_checksum); //Send command: specific to M3 in 3b delay(config_lo_delay); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } if(band == "7b") { //Band 7b Hifi_HIFI_Conf_nom_LCU_ch7b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,macro_checksum); // delay(config_lo_delay); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } // } ////////////////////////////////////////////////////////////////////// // Procedure to display performance parameters of the observing mode procedure OTF_performance { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {double,double,double,double,double} noisevalues = {1.0,1.0,1.0,1.0,0.0}; // Noise values from noisecomputer int totaltime = 200; // Total observing time int nlines = 20; // Number of lines in the map int npoints = 20; // Number of points in the map int n_scans = 2; // Number of OTF scans to cover the map int n_cycles = 1; // Number of map coverages double tscan = 60.0; // Total average duration of one scan {double,double,double} tact = {10.0,4.0,12.0}; // field of actual timings }{ double tint_act = tact{1}; // integration time excluding all dead times double tintoff = tact{2}; // integration time on OFF // Get performance of ideal instrument for comparison {int,double,double,double,double,double} idealvalues = IdealInstrument(band,lo_freq,eff_resolution,totaltime); double idealnoise = idealvalues{1} * idealvalues{1}; double obsnoise = noisevalues{0} * noisevalues{0}; // rescale for map coverage idealnoise = idealnoise * double(npoints * nlines); double efficiency = idealnoise / obsnoise; // Compute the actual integration time double posinttime = double(n_cycles * nlines * npoints) * tint_act; double posofftime = double(n_cycles * n_scans + 1) * tintoff; int instrumenttime = iceil(double(n_cycles * n_scans) * tscan + tintoff); // Check total integration time double timeefficiency = (posinttime + posofftime) / double(totaltime); // Noise contribution double relnoise = noisevalues{4} / (1.0 + noisevalues{4}); // Non-standard messages message("

"); message("The observed map consists of " + nlines + " OTF lines, each covering " + npoints + " readout points.
"); // General messages PerformanceMessages(band,lo_freq,totaltime,posinttime,posofftime,timeefficiency,efficiency,relnoise,false); } // Standing wave analysis, mode NDW //HIFI-COP-3-StWv1 procedure Standing_wave_noretune_COP_proc_ops { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string backend = "both"; string[] hrs_mode = ["wb1","wb1"]; int freq_index = 1; //The frequency index to consider: 1 to 4 string los_code = "sc" in ["sc","sh","ss"]; //The line-of-sight code: sc (sky-CBB), sh (sky-HBB), ss (sky-sky) }{ //Retrieve frequencies from LUT string tabstwv = "config_stwvfreq.config"; double bandnb = GetBandCode(band); // //Check consistency of request if(freq_index > 1 && (los_code == "sh" || los_code == "ss")) { error("You cannot select this line-of-sight with this frequency index"); } if(iround(bandnb) % 2 == 0 && (los_code == "sh" || los_code == "ss")) { error("You cannot select this line-of-sight with b-bands"); } //Fetch observing parameters double lo_freq = dlookup(tabstwv,"" + iceil(bandnb),"freq" + freq_index); int integ_time = ilookup(tabstwv,"" + iceil(bandnb),"t" + freq_index); int total_stepnb = ilookup(tabstwv,"" + iceil(bandnb),"n" + freq_index + "_" + los_code); // if(lo_freq == 0.0) { error("There is no frequency associated with this band and this frequency index"); } // HRS_config_block_fm(band,hrs_mode); // int[] res = [0,0]; if(los_code == "sh") { res = Configure_Spectrometer_hc_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); } else { res = Configure_Spectrometer_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); } int total_time = res[0] * res[1]; // double step = 0.015; //GHz double stepnb = double(total_stepnb / 2); double[] lo_freq_input = [0.0,0.0,0.0]; //Build lo_freq_input array lo_freq_input = [lo_freq - stepnb * step,lo_freq + stepnb * step,step]; Standing_wave_noretune_fm_COP(band,total_time,hrs_mode,backend,lo_freq_input,los_code); // } // Diplexer scan, fast, procedure // Measures mixer current (thru HK thus), also suitable to just set the diplexer procedure Diplexer_scan_fast_proc { string band = "3a"; // HIFI band //Setting file double diplexer_current_min_h = -2.24; //minimum diplexer current H double diplexer_current_max_h = 2.24; //maximum diplexer current H double diplexer_current_min_v = -2.24; //minimum diplexer current V double diplexer_current_max_v = 2.24; //maximum diplexer current V int n_steps = 100; //number of steps double lo_freq = 807.0; //LO frequency string mixer_polarization = "H" in ["H","V"]; //Polarization: H or V }{ // //In case of band 6 or 7, use special biases if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { {double,string}[] result = ConfigurationReader("name_confilfpu",["bias_dipscan_h","bias_dipscan_v","bias_max_h","bias_max_v"],band,lo_freq); //First go to 4mV Mixerbias_block_fm(result[2]{0},result[3]{0}); //Then to 3mV Mixerbias_block_fm(result[0]{0},result[1]{0}); } // //Fetch diplexer settings double[] result_dip = Get_Diplexer_setting(band,lo_freq); double diplex_H = result_dip[0]; double diplex_V = result_dip[1]; //Case of H polarization if(mixer_polarization == "H") { //diplexer_current_min_v = diplex_V; diplexer_current_max_v = diplexer_current_min_v; Diplexer_scan_fast_fm(band,diplexer_current_min_h,diplexer_current_max_h,diplexer_current_min_v,diplexer_current_max_v,n_steps); } //Case of V polarization if(mixer_polarization == "V") { //diplexer_current_min_h = diplex_H; diplexer_current_max_h = diplexer_current_min_h; Diplexer_scan_fast_fm(band,diplexer_current_min_h,diplexer_current_max_h,diplexer_current_min_v,diplexer_current_max_v,n_steps); } //Get back to optimal settings Set_Diplexer_current_block_fm(diplex_H,diplex_V); // //In case of band 6 or 7,go back to nominal values if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { result = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,lo_freq); //First go to 4mV Mixerbias_block_fm(result[0]{0},result[1]{0}); //Then to nominal result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); Mixerbias_block_fm(result[0]{0},result[1]{0}); } // } // Total power integration for peak up block HIFIPeakupIntegration HIFI 6821 { int data_time = 4; // Integration time between two data readouts int n_cycle = 1; // number of readouts bool isWbs = true; // backend to use - resolution bool isH = true; // backend to use - polarization int point = 1; // Number of point in 3x3 raster string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double[] rates = [120.0,1.0,2.0]; // Data rates between and during integrations }{ // First part - actual peakup data aquisition // polarization string if(isH) { string polarization = "H"; } else { polarization = "V"; } // Call command if(isWbs) { Hifi_HIFI_acquire_peakup_wbs($BBID,polarization,point); } else { Hifi_HIFI_acquire_peakup_hrs($BBID,polarization,point); } delay(2); // Second part additional data frame aquisition HIFI_Spectr_slow_chop_proc_aot(data_time,n_cycle,band,lo_freq,["chop_M3","chop_M3right"],rates); // Move chopper back to center position RotateChopper(band,lo_freq,"chop_M3"); } //////////////////////////////////// // Frequency switch observing mode // // All properties inherited from the load-chop mode // // This whole implementation is highly speculative as we have no experience // with frequency switch measurements yet. // {int,double,double,double,double,double} obs HifiPointProcFSwitch { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source double raoff = 0.0; // RA coordinate of the OFF position double decoff = 0.0; // DEC coordinate of the OFF position bool refSelected = true; // Dummy parameter required by HSPOT string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rates int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles on ON int n_switch_off = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles on OFF int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF calibration cycles int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Single Point - Frequency Switch Ref",{data_time,data_time_off,0,n_switch_on,n_switch_off,0,0,0,n_cycles,load_interval}); // position switch // Call first part of the timing computer {int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int} pre_timing_ps = FSwitch_pre_timing(band,lo_freq,freq_throw,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,n_switch_on,n_switch_off,n_cycles,load_interval,docommands); // Prepare telescope command {double,double} onPosition = {ra,dec}; {double,double} refPosition = {raoff,decoff}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,int,int,int,int,int,int} tpar_ps = PositionSwitch_telescope(naifid,onPosition,refPosition,band,lo_freq,pre_timing_ps,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = nodding_pointing(false,tpar_ps{0},tpar_ps{1},tpar_ps{2},tpar_ps{3},tpar_ps{4},tpar_ps{5},tpar_ps{6},tpar_ps{7},tpar_ps{8},tpar_ps{9},tpar_ps{10},tpar_ps{11},tpar_ps{12},tpar_ps{13},tpar_ps{14},tpar_ps{15},tpar_ps{16},tpar_ps{17},tpar_ps{18},true); // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int},int,bool,double,double} post_timing_ps = DoubleChop_post_timing(pre_timing_ps,telescopetimes,n_cycles); // Now the actual observation starts // Prepare telescope command tpar_ps = PositionSwitch_telescope(naifid,onPosition,refPosition,band,lo_freq,post_timing_ps{1},n_cycles); // Call telescope command telescopetimes = nodding_pointing(true,tpar_ps{0},tpar_ps{1},tpar_ps{2},tpar_ps{3},tpar_ps{4},tpar_ps{5},tpar_ps{6},tpar_ps{7},tpar_ps{8},tpar_ps{9},tpar_ps{10},tpar_ps{11},tpar_ps{12},tpar_ps{13},tpar_ps{14},tpar_ps{15},tpar_ps{16},tpar_ps{17},tpar_ps{18},true); // Consistency check int totaltime = post_timing_ps{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following ////////////////////////////////////////////////////////////////////// int on_inttime = post_timing_ps{1}{0}; int off_inttime = post_timing_ps{1}{1}; int on_pointing = post_timing_ps{1}{2}; int off_pointing = post_timing_ps{1}{3}; int loadlength = post_timing_ps{1}{4}; int n_loadinterval = post_timing_ps{1}{7}; int n_per_on = post_timing_ps{1}{8}; int n_per_off = post_timing_ps{1}{9}; int n_load_on = post_timing_ps{1}{10}; int n_load_off = post_timing_ps{1}{11}; bool end_load_on = post_timing_ps{1}{12}; bool end_load_off = post_timing_ps{1}{13}; int initshiftlength = post_timing_ps{2}; bool final_load = post_timing_ps{3}; double tscan = post_timing_ps{4}; double tdead = post_timing_ps{5}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands ////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { FSwitch_commanding(band,lo_freq,freq_throw,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,n_per_on,n_per_off,n_loadinterval,n_load_on,n_load_off,end_load_on,end_load_off,final_load,startobs,telescopetimes,loadlength,initshiftlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double,double,double} tact = DoubleChop_deadtimes("fs",band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,n_per_on,n_per_off,n_load_on,n_load_off,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = FSwitch_noisecomputer(band,lo_freq,effResolution,oneGHzReference,on_inttime,off_inttime,n_cycles,tscan,tact); // Evaluate performance DoubleChop_performance(band,lo_freq,effResolution,noisevalues,timeTaken,n_cycles,n_per_on * (n_load_on + 1),n_per_off * (n_load_off + 1),true,tscan,on_pointing,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } //HIFI-COP-X-Dip-FSW procedure Dip_FSW_COP_proc_ops { string band = "3a" in ["3a","3b","4a","4b","6a","6b","7a","7b"]; // HIFI band int throw_index = 1; //index of FSW throw as of stab FSW table of throws int freq_index = 1; //index of FSW throw as of stab FSW table of frequencies string[] hrs_mode = ["wb1","wb1"]; int integ_time = 600; string backend = "both"; int nb_pairs = 20; //number of FSW1-FSW2 pairs string polarization = "H" in ["H","V"]; //The polarization on which the test is done bool retune = true; //whether the diplexer is adjusted between frequencies or not }{ // //Define frequencies of interest: first freq. index of stab_freq_fsw string tab = "config_stabfreq_" + band + ".config"; double lo_freq1 = dlookup(tab,"" + freq_index,"freq_fsw"); //Get throw string tabfsw = "config_freqthrow.config"; double bandnb = GetBandCode(band); double freq_throw = dlookup(tabfsw,"" + iceil(bandnb),"freq_throw_" + throw_index); double lo_freq2 = lo_freq1 + freq_throw / 1000.0; double lo_freq_ref = (lo_freq1 + lo_freq2) / 2.0; //Init MSA at FSW1 and on HBB for tuning //Tune FSW1 and store in register if(retune) { Init_MSA_HBB_fm(band,"CLOSE",lo_freq1,"ON"); LO_tuning_FSW_block_fm(band,lo_freq1,lo_freq_ref,true); } else { Init_MSA_HBB_fm(band,"CLOSE",lo_freq_ref,"ON"); LO_tuning_FSW_block_fm(band,lo_freq1,lo_freq_ref,true); } //Configure HRS HRS_config_block_fm(band,hrs_mode); //Magnet tuning: only bands 3 and 4 if(band == "3a" || band == "3b" || band == "4a" || band == "4b") { Magnet_tuning_block_fm(band,lo_freq1,"HRS",40); } //Backend config and tuning if(backend == "hrs" || backend == "both" || backend == "hrsFast") { HRS_tune_block_fm(band); } if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { //WBS calibration WBS_calib_fm(band); WBS_tune_proc_fm(band); } // //Tune FSW2 and store in register if(retune) { Set_Diplexer_current_FSW_block_fm(band,lo_freq2); LO_tuning_FSW_block_fm(band,lo_freq2,lo_freq_ref,false); } else { //Set_Diplexer_current_FSW_block_fm(band,lo_freq_ref); LO_tuning_FSW_block_fm(band,lo_freq2,lo_freq_ref,false); } //Perform hotcold at FSW1 int[] res = Configure_Spectrometer_hc_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); int total_time = res[0] * res[1]; if(retune) { Set_Diplexer_current_FSW_block_fm(band,lo_freq1); } else { //Set_Diplexer_current_FSW_block_fm(band,lo_freq_ref); } Activate_FSW_register_block_fm("FSW1"); Hot_cold(band,hrs_mode,backend,total_time,"slowchop",0,0); //Perform hotcold at FSW2 if(retune) { Set_Diplexer_current_FSW_block_fm(band,lo_freq2); } else { //Set_Diplexer_current_FSW_block_fm(band,lo_freq_ref); } Activate_FSW_register_block_fm("FSW2"); Hot_cold(band,hrs_mode,backend,total_time,"slowchop",0,0); //Look at the sky Chopper_Rotation_block_fm(band,"chop_hot_ang","chop_M3_ang"); //Start integration in total power res = Configure_Spectrometer_AOTlike_proc_fm(band,integ_time,hrs_mode,backend); int phase_counter = 0; int phase_a_counter = 1; int phase_b_counter = 0; int nb_loop = nb_pairs * 2; bool modulate = true; while(phase_counter < nb_loop) { //First A-phase if(phase_counter < nb_loop) { if(phase_counter == 0) { modulate = true; } else { modulate = false; } Dip_FSW_A_phase(band,retune,lo_freq1,lo_freq_ref,[res[0],res[1]],backend,polarization,modulate); phase_a_counter = phase_a_counter + 1; phase_counter = phase_counter + 1; message("A1"); } //Second A-phase if applicable if(phase_a_counter < 2 && phase_counter < nb_loop) { Dip_FSW_A_phase(band,retune,lo_freq1,lo_freq_ref,[res[0],res[1]],backend,polarization,true); phase_a_counter = phase_a_counter + 1; phase_counter = phase_counter + 1; message("A2"); } //B-phase if(phase_counter < nb_loop) { Dip_FSW_B_phase(band,retune,lo_freq2,lo_freq_ref,[res[0],res[1]],backend,polarization,true); phase_b_counter = phase_b_counter + 1; phase_counter = phase_counter + 1; message("B1"); } //Second B-phase if applicable if(phase_b_counter < 2 && phase_counter < nb_loop) { Dip_FSW_B_phase(band,retune,lo_freq2,lo_freq_ref,[res[0],res[1]],backend,polarization,false); phase_b_counter = phase_b_counter + 1; phase_counter = phase_counter + 1; message("B2"); } //Closure A-phase if(phase_counter < nb_loop) { Dip_FSW_A_phase(band,retune,lo_freq1,lo_freq_ref,[res[0],res[1]],backend,polarization,true); phase_counter = phase_counter + 1; message("A2"); } //Reset counters if(phase_counter % 4 == 0) { phase_a_counter = 1; phase_b_counter = 0; } } //Transfer delay before closing off observation {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = BackendSettings(band,0.0,hrs_mode,backend); int transfer = SlowChopReadoutDelay(band,lo_freq1,backendreadoutparms); delay(transfer); } ///////////////////////////////////// // Blocks ///////////////////////////////////// // OBS SFT, block block OBS_SFT_block_fm HIFI 3922 { }{ Start_block_no_hk_request(); //Check PM memory //Applies to OBS 5.9.0 int check_start = 0x5500; int check_end = 0x18435; int check_crc = 0x7b2e; Hifi_HIFI_check_PM_memory(check_start,check_end,check_crc); delay(3); // //Set Housekeeping rate to 1/sec Hifi_HIFI_Housekeeping_on("1_pkt_per_s","ON","ON","ON","ON","ON","ON"); delay(1); // Hifi_HIFI_enable_time_verify(); delay(1); //Simulate science: are the spectrometers automatically configured ? Hifi_HIFI_simulate_science(); delay(30); //Should abort the above Hifi_HIFI_abort_spectroscopy(); delay(1); } //HIFI-COP-1.2-FPU_FT procedure FPU_FT_COP_proc_ops { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b","8"]; // HIFI band double lo_freq = 500.0; //LO frequency string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ mois_comment("Start of HIFI FPU Functional Test for band " + band); mois_comment("Please ensure that instrument was switched on with the " + prime_or_redundant + " unit"); //General parameters in use string hbb_heater = "ON"; //hot source on/off string chopper_loop = "CLOSE"; // string chop_startup_prime_red = "chop_startup_cold_prime"; if(prime_or_redundant == "Red") { chop_startup_prime_red = "chop_startup_cold_red"; } {double,string}[] result = ConfigurationReader("name_chopper",[chop_startup_prime_red],"0",0.0); if(chopper_loop == "OPEN") { result = ConfigurationReader("name_chopper",["chop_startup_warm"],"0",0.0); } mois_step("Init of FPU"); Init_MSA_ops(band,chopper_loop,lo_freq,result[0]{0},hbb_heater,prime_or_redundant); mois_tmcheck("Check content of ANDs FCU_H_device, FCU_V_device, FCU_PR_power and FPU_common with HIFI expert"); // if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { mois_step("FPU heater test"); Heater_fm(band); } // } // Compute the offset between two points // This is an approximation for small offsets {double,double} procedure AngularOffset { {double,double} vector1 = {0.0,0.0}; // First vector {double,double} vector2 = {0.2,0.2}; // Second vector }{ double pih = 3.14159265 / 2.0; double pideg = pih / 90.0; double l1 = vector1{0} * pideg; double b1 = vector1{1} * pideg; double l2 = vector2{0} * pideg; double b2 = vector2{1} * pideg; // 3-D vector double u1 = cos(b2) * cos(l2); double u2 = cos(b2) * sin(l2); double u3 = sin(b2); // Rotate by l1 double s1 = cos(l1) * u1 + sin(l1) * u2; double s2 = -sin(l1) * u1 + cos(l1) * u2; double s3 = u3; // Rotate by b1 u1 = cos(b1) * s1 + sin(b1) * s3; u2 = s2; u3 = -sin(b1) * s1 + cos(b1) * s3; // Extract angles double u12 = sqrt(u1 * u1 + u2 * u2); if(u12 > 0.0) { double db = atan(u3 / u12); } else { db = pih; } if(u1 != 0.0) { double dl = atan(u2 / u1); } else { dl = pih; } return {dl / pideg,db / pideg}; } // Total noise from a symmetric two-phase observation // This is still to be scaled by a factor 1.0/(B_fluct*T_obs) double procedure TwoPhaseNoise { double x = 0.1; // value for integration time relative to Allan time double[] parameters = [0.3,2.5]; // Parameters: delay relative to Allan time, drift exponent }{ // Assign parameters double d = parameters[0]; double alpha = parameters[1]; // add radiometric and drift noise double yn = TwoPhaseRadioNoise(x); double yd = TwoPhaseDrift(x,d,alpha); // Add and normalize with respect to total observing time double y = (yn + yd) * (2.0 * x + d); return y; } // FPU settling time for a mixer band change, 3rd block // Block for third tuning block FPU_Settling_time_third_tuning_fm HIFI 3685 { string band_1 = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band int int_time2 = 600; //Integration time after first and second switch double lo_freq_1 = 500.0; //LO frequency in sub-band a string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); // //Init and tune of LO: configuration from safe to tuned. LCU_config_nominal_proc_fm(band_1,lo_freq_1); LO_tuning_w_mixerchoice_proc(band_1,lo_freq_1,"H"); // //Configure spectroscopy integration Configure_Spectrometer_proc_fm(band_1,int_time2,["wb1","wb1"],backend); //4 sec. integration //Take series of spectra during int_time2 seconds HIFI_Spectr_total_power_proc_fm(band_1,backend,int_time2); // //Now switch off LO sub-band LCU_switch_off_proc_fm(); } // Mode initialisation procedure StartMode_no_hk_request { }{ BroadcastOBSID_no_hk_request(); //Get applicable HK rate {double,string}[] result_d = ConfigurationReader("name_delays",["hk_rate"],"0",0.0); double hk_rate = result_d[0]{0}; //HKrate (hk_rate) ; } //////////////////////////////////////// // Standing wave analysis, procedure NDW // This is like a radiometry: 4 spectra // noretune version procedure Standing_wave_noretune_fm { string band = "1a"; // HIFI band int integ_time = 4; //Total integration time in sec. string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast double[] lo_freq_input = [500.0,500.15,0.02]; //Start, end and step lo_freq for the LO scan }{ // Initial LO tuning at centre frequency of scan (NDW) // double lo_freq_ref = (lo_freq_input[0] + lo_freq_input[1]) / 2.0; LO_tuning_block_fm(band,lo_freq_ref); double lo_freq = lo_freq_input[0]; // //WBS calibration and backend tuning if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band); WBS_tune_stndwave_proc_fm(band); } if(backend == "hrs" || backend == "both") { HRS_config_block_fm(band,hrs_mode); HRS_tune_block_fm(band); } // //Configure spectrometers integration //Slowchop will be used for all bands - FSW no longer considered for HEBs // int[] res = [0,0]; int total_time = 0; res = Configure_Spectrometer_hc_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); total_time = res[0] * res[1]; // //Loop on LO frequencies. It is assumed that the LO is tuned at the middle frequency of the scan // while(lo_freq <= lo_freq_input[1]) { // //Set synthesizer to new LO freq. LCU_config_nominal_noretune_block_fm(band,lo_freq,lo_freq_ref); // NDW // //First internal loads Hot_cold(band,hrs_mode,backend,res[0] * res[1],"slowchop",0,0); //Then external loads - this will drop if not ILT-context //Hot_cold_external(band,res[0]*res[1],backend); //Increase lo_freq lo_freq = lo_freq + lo_freq_input[2]; } } // convenience procedure for collecting // consecutive memory locations from an LCU memory patch file // Also works for maxrunlength = 1 {int,int[]}[] procedure LcuGetMemoryRuns { string section = "P" in ["P","R"]; // select prime or redundant LCU int maxrunlength = 100 in [1,1000]; }{ string tab = "LcuMemoryPatch_" + section + ".config"; int total = table_size(tab); {int,int[]}[] result = []; int runcount = 0; int[] thisrun = []; int thisrunlength = 0; int startlocation = -1; for(int line = 1 .. total) { string look = "" + line; int loc = ilookup(tab,look,"location"); int val = ilookup(tab,look,"value"); bool samerun = loc == startlocation + 2 * thisrunlength; if(samerun && thisrunlength < maxrunlength) { thisrun[thisrunlength] = val; thisrunlength = thisrunlength + 1; } else { if(startlocation >= 0) { result[runcount] = {startlocation,thisrun}; runcount = runcount + 1; } thisrun = [val]; thisrunlength = 1; startlocation = loc; } } if(thisrunlength > 0) { result[runcount] = {startlocation,thisrun}; } return result; } {int,double,double,double,double,double} obs HifiMappingModeLoadChopOTF { string modeName = "load-raster"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // chunk size given by the data rates and optimum speed int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 1 in [1,1800]; // Supersamplingfactor int n_switch_off = 3 in [1,3600]; // Number of data dumps for the OFF integration time int n_linesperscan = 1 in [1,32]; // Number of lines between two OFFs int n_cycles = 1 in [1,1200]; // Number of map coverages int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode OpenMessages("HIFI Mapping - OTF Map Load Chop Ref",{data_time,data_time_off,0,n_switch_on,n_switch_off,n_linesperscan,0,0,n_cycles,load_interval}); // Auxiliary routine for API parameter correction {double,double,int} mapused = ValidMapSize(band,lo_freq,lineDistance,nlines,stepsize,npoints,2 * data_time * n_switch_on); double line_used = mapused{0}; double scanvelocity = mapused{1}; int npoints_used = mapused{2}; // Call first part of the timing computer {int,int,int,int,int,int,int,int} pre_timing = OTFLoadChop_pre_timing(nlines,npoints_used,band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,n_switch_on,n_switch_off,n_linesperscan,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {double,double} refPosition = {raoff,decoff}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,double,double,int,int,double,double,int,int,int,int,int} tpar = OTFmap_telescope(naifid,onPosition,lineDistance,nlines,line_used,refPosition,scanvelocity,band,lo_freq,n_linesperscan,n_cycles,pre_timing); // Dummy call to spacecraft command int[] telescopetimes = line_scan_with_off_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23}); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int},double,double} post_timing = OTFmap_post_timing(pre_timing,telescopetimes,data_time,n_linesperscan,n_cycles,load_interval); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = OTFmap_telescope(naifid,onPosition,lineDistance,nlines,line_used,refPosition,scanvelocity,band,lo_freq,n_linesperscan,n_cycles,post_timing{1}); // Call telescope command telescopetimes = line_scan_with_off_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23}); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int n_pp = post_timing{1}{0}; int n_scans = post_timing{1}{1}; int off_inttime = post_timing{1}{2}; int loadlength = post_timing{1}{4}; int n_loadinterval = post_timing{1}{5}; double tscan = post_timing{2}; double tdead = post_timing{3}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { OTFLoadChop_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,npoints_used * n_switch_on,n_switch_off,nlines * n_cycles,n_linesperscan,n_loadinterval,startobs,telescopetimes,loadlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double,double,double} tact = OTFDoubleChop_deadtimes("lchop",band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,n_switch_on,n_switch_off,n_linesperscan,n_pp,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = OTFLoadChop_noisecomputer(band,lo_freq,effResolution,oneGHzReference,nlines,data_time,n_switch_on,n_linesperscan,off_inttime,n_cycles,tscan,tact); // Evaluate performance OTFDoubleChop_performance(band,lo_freq,effResolution,noisevalues,timeTaken,nlines,npoints_used,n_switch_on,n_switch_off,n_scans,n_cycles,false,tscan,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } //HIFI-COP-2.3-Param-Scan procedure Parameter_Scan_COP_proc_ops { int index = 1 in [1,7]; // Test case index as of config_paramscan_COP.config int phase = 1 in [1,2]; //Measurement phase int integ_time = 4; //Integration time PER PHASE for the Tsys slowchop measurement string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int m1_index = 1 in [1,5]; //Index of M1 value - only applicable is phase = 1. Index 1 is least negative int m2_index = 1 in [1,5]; //Index of M2 value - only applicable is phase = 1. Index 1 is least negative int bias_index = 1 in [1,3]; //Index of bias value - only applicable is phase = 2 int imix_index = 1 in [1,3]; //Index of Imix value - only applicable is phase = 2 }{ int start = time(); // //Read all band+param to perform string tab = "config_paramscan_COP.config"; int total = table_size(tab); double lo_freq = dlookup(tab,"" + index,"lofreq"); string band = slookup(tab,"" + index,"band"); double m1_min = dlookup(tab,"" + index,"m1_1"); double m1_max = dlookup(tab,"" + index,"m1_2"); double m1_step = dlookup(tab,"" + index,"m1_step"); double m2_min = dlookup(tab,"" + index,"m2_1"); double m2_max = dlookup(tab,"" + index,"m2_2"); double m2_step = dlookup(tab,"" + index,"m2_step"); double bias_min = dlookup(tab,"" + index,"bias_1"); double bias_max = dlookup(tab,"" + index,"bias_2"); double bias_step = dlookup(tab,"" + index,"bias_step"); double imix_min = dlookup(tab,"" + index,"imix_1"); double imix_max = dlookup(tab,"" + index,"imix_2"); double imix_step = dlookup(tab,"" + index,"imix_step"); double m1 = m1_max - double(m1_index - 1) * m1_step; double m2 = m2_max - double(m2_index - 1) * m2_step; double bias = bias_min + double(bias_index - 1) * bias_step; double imix = imix_min + double(imix_index - 1) * imix_step; //Implementation of SCR-2460: for the time being, M2 is fixed to its nominal value - no scan string name_configlcu = "name_configlcu_b"; {double,string}[] result = ConfigurationReader(name_configlcu,["m2_v"],band,lo_freq); //DT - 28-06-09: now allowed to proceed with M2 scan as well //m2 = result[0]{0}; //General parameters for spectroscopy string backend = "both"; string chopmode = "slowchop"; double sampling_rate = 3.0; //Sampling rate: 2 (2 HRS-H + 2 HRS-V), 4 (HRS-H + HRS-V, 2 HRS-H or 2 HRS-V) or 8 (1 HRS-H or 1 HRS-V) Hz double hrs_h_1 = 7.4; //Position in IF of HRS-H sub-band 1 double hrs_h_2 = 7.4; //Position in IF of HRS-H sub-band 2 double hrs_v_1 = 7.4; //Position in IF of HRS-V sub-band 1 double hrs_v_2 = 7.4; //Position in IF of HRS-V sub-band 2 double[] hrs_subband = [hrs_h_1,hrs_h_2,hrs_v_1,hrs_v_2]; string hrs_polarization = "B"; //HRS polarization: selection works only for 4 and 8 Hz int n = 1466; //Switch-on LO //Should be done prior to test //LCU_switchon_proc_fm(band); //Wait an extra delay of 1 min for short term stabilization //delay(60); // //FPU configuration Init_MSA_HBB_fm(band,"CLOSE",lo_freq,"ON"); //Phase 1 measurement: M1 and M2 pair if(phase == 1) { // //Tune LO at standard target LO_tuning_w_M1M2_block_fm(band,lo_freq,m1,m2); message(band + ", " + lo_freq + ", " + m1 + ", " + m2); // //Tsys measurement WBS_calib_fm(band); WBS_tune_proc_fm(band); HRS_config_block_fm(band,["wb1","wb1"]); HRS_tune_block_fm(band); //Configure spectroscopy for slowchop hotcold int[] res = Configure_Spectrometer_hc_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); int total_time = res[0] * res[1]; Hot_cold(band,hrs_mode,backend,total_time,chopmode,0,0); // //HRS fast stability measurment Stability_fast_proc_fm(band,n,hrs_subband,sampling_rate,hrs_polarization); // } //Phase 2 measurement: bias and Imix pair if(phase == 2) { //Configure at nominal M1,M2 (i.e. they are in the LCU safety table release) LCU_config_nominal_proc_fm(band,lo_freq); message(band + ", " + lo_freq + ", " + bias + ", " + imix / 1000.0); //Apply biases //In case of band 6 or 7, go via max first if(band == "7b") { result = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,lo_freq); //First go to 4mV Mixerbias_block_fm(result[0]{0},result[1]{0}); //Then to nominal Mixerbias_block_fm(bias,bias); } // //Tune LO at dedicated target (use of H mixer) LO_tuning_w_targetC_block_fm(imix / 1000.0,band,lo_freq,"H"); // //Tsys measurement WBS_calib_fm(band); WBS_tune_proc_fm(band); HRS_config_block_fm(band,["wb1","wb1"]); HRS_tune_block_fm(band); //Configure spectroscopy for slowchop hotcold res = Configure_Spectrometer_hc_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); total_time = res[0] * res[1]; Hot_cold(band,hrs_mode,backend,total_time,chopmode,0,0); // //HRS fast stability measurment Stability_fast_proc_fm(band,n,hrs_subband,sampling_rate,hrs_polarization); // } } //////////////////////////////////// // Mode status procedures: allow // spacon to check mode status at // start and end from mode switch // procedure //////////////////////////////////// //Dump 7AH page block Dump_7AH_page_block_mois HIFI 3851 { }{ // BBID needs to be set manually as the main TC command has no BBID argument Hifi_HIFI_Set_OBS_ID($BBID,$OBSID); delay(1); // //Hifi_HIFI_LCU_read_settings(); delay(1); // } // Function allowing to derive HRS internal LO parameters A and M // in function of requested frequencies. // - The first 4 IF are given in GHz between 4 and 8 GHz // - The 5th and 6th LOs (fixed) are given in GHz // - The 7th LO is given in MHz // // The rules are: // - 64 <= M <= 84, 0 <= A <= 9 // - Flo = 200x(M+1)+20xA // with Flo in 13-17.180 GHz, i.e. 9GHz above IF // // The result array is organized as follows: // [A1_h,M1_H, A2_H,...A7_h,A1_v,M1_v,A2_v,..,A7_v] // // DT - 3 June 2005 int[] procedure ComputeA_M_parameters { string[] hrs_mode = ["wb","wb"]; //HRS resolution mode for both polar: hr, mr, lr, wb double hrh_up_ol1 = 4.5; // IF1 frequency for H-polar double hrh_up_ol2 = 4.5; // IF2 frequency for H-polar double hrh_up_ol3 = 4.5; // IF3 frequency for H-polar double hrh_up_ol4 = 4.5; // IF4 frequency for H-polar double hrh_down_ol5 = 10.5; // LO5 frequency for H-polar double hrh_down_ol6 = 1.25; // LO6 frequency for H-polar double hrh_down_ol7 = 490.0; // LO7 frequency for H-polar double hrv_up_ol1 = 4.5; // IF1 frequency for V-polar double hrv_up_ol2 = 4.5; // IF2 frequency for V-polar double hrv_up_ol3 = 4.5; // IF3 frequency for V-polar double hrv_up_ol4 = 4.5; // IF4 frequency for V-polar double hrv_down_ol5 = 10.5; // LO5 frequency for V-polar double hrv_down_ol6 = 1.25; // LO6 frequency for V-polar double hrv_down_ol7 = 490.0; // LO7 frequency for V-polar }{ //Initialize array //Defaults are: lo1=13, lo2=14, lo3=15, lo4=16 GHz int[] a_m_parameter = [0,64,0,64,0,64,0,64,5,51,0,49,7,0,64,0,64,0,64,0,64,5,51,0,49,7]; int[] a_m = [0,0]; // //The number of A and M parameters to compute depends on the mode // //First rename LO7 and convert to GHz double flo7_h = hrh_down_ol7 / 1000.0; double flo7_v = hrv_down_ol7 / 1000.0; //Initialize freq. double flo_u1_h = 0.0; double flo_u1_v = 0.0; double flo_l2_h = 0.0; double flo_l2_v = 0.0; double flo_u3_h = 0.0; double flo_u3_v = 0.0; double flo_l4_h = 0.0; double flo_l4_v = 0.0; // //Available sub-band width: as of SPR-2479 double bw_h = flo7_h / 2.0 - 0.015; double bw_v = flo7_v / 2.0 - 0.015; //High-Resolution if(hrs_mode[0] == "hr") { //H-polar flo_u1_h = (9.25 - bw_h / 2.0 + hrh_up_ol1) * 1000.0; //Implement SCR-1243: 14.4 and 14.42 GHz not allowed flo_u1_h = Check_HRS_prohibited_LO_proc_fm(flo_u1_h); a_m = GetA_M(flo_u1_h); a_m_parameter[0] = a_m[0]; a_m_parameter[1] = a_m[1]; } // if(hrs_mode[1] == "hr") { //V-polar flo_u1_v = (9.25 - bw_v / 2.0 + hrv_up_ol1) * 1000.0; //Implement SCR-1243: 14.4 and 14.42 GHz not allowed flo_u1_v = Check_HRS_prohibited_LO_proc_fm(flo_u1_v); a_m = GetA_M(flo_u1_v); a_m_parameter[13] = a_m[0]; a_m_parameter[14] = a_m[1]; } // //Medium-Resolution if(hrs_mode[0] == "mr") { //H-polar flo_u1_h = (9.25 - bw_h / 2.0 + hrh_up_ol1) * 1000.0; //Implement SCR-1243: 14.4 and 14.42 GHz not allowed flo_u1_h = Check_HRS_prohibited_LO_proc_fm(flo_u1_h); a_m = GetA_M(flo_u1_h); a_m = GetA_M(flo_u1_h); a_m_parameter[0] = a_m[0]; a_m_parameter[1] = a_m[1]; flo_l4_h = (9.25 + bw_h / 2.0 + hrh_up_ol4) * 1000.0; //Implement SCR-1243: 14.4 and 14.42 GHz not allowed flo_l4_h = Check_HRS_prohibited_LO_proc_fm(flo_l4_h); a_m = GetA_M(flo_l4_h); a_m_parameter[6] = a_m[0]; a_m_parameter[7] = a_m[1]; } // //Medium-Resolution if(hrs_mode[1] == "mr") { //V-polar flo_u1_v = (9.25 - bw_v / 2.0 + hrv_up_ol1) * 1000.0; //Implement SCR-1243: 14.4 and 14.42 GHz not allowed flo_u1_v = Check_HRS_prohibited_LO_proc_fm(flo_u1_v); a_m = GetA_M(flo_u1_v); a_m_parameter[13] = a_m[0]; a_m_parameter[14] = a_m[1]; flo_l4_v = (9.25 + bw_v / 2.0 + hrv_up_ol4) * 1000.0; //Implement SCR-1243: 14.4 and 14.42 GHz not allowed flo_l4_v = Check_HRS_prohibited_LO_proc_fm(flo_l4_v); a_m = GetA_M(flo_l4_v); a_m_parameter[19] = a_m[0]; a_m_parameter[20] = a_m[1]; } // //Low-Resolution if(hrs_mode[0] == "lr") { //H-polar flo_u1_h = (9.25 - bw_h / 2.0 + hrh_up_ol1) * 1000.0; //Implement SCR-1243: 14.4 and 14.42 GHz not allowed flo_u1_h = Check_HRS_prohibited_LO_proc_fm(flo_u1_h); a_m = GetA_M(flo_u1_h); a_m_parameter[0] = a_m[0]; a_m_parameter[1] = a_m[1]; flo_l2_h = (9.25 + bw_h / 2.0 + hrh_up_ol2) * 1000.0; //Implement SCR-1243: 14.4 and 14.42 GHz not allowed flo_l2_h = Check_HRS_prohibited_LO_proc_fm(flo_l2_h); a_m = GetA_M(flo_l2_h); a_m_parameter[2] = a_m[0]; a_m_parameter[3] = a_m[1]; flo_u3_h = (9.25 - bw_h / 2.0 + hrh_up_ol3) * 1000.0; //Implement SCR-1243: 14.4 and 14.42 GHz not allowed flo_u3_h = Check_HRS_prohibited_LO_proc_fm(flo_u3_h); a_m = GetA_M(flo_u3_h); a_m_parameter[4] = a_m[0]; a_m_parameter[5] = a_m[1]; flo_l4_h = (9.25 + bw_h / 2.0 + hrh_up_ol4) * 1000.0; //Implement SCR-1243: 14.4 and 14.42 GHz not allowed flo_l4_h = Check_HRS_prohibited_LO_proc_fm(flo_l4_h); a_m = GetA_M(flo_l4_h); a_m_parameter[6] = a_m[0]; a_m_parameter[7] = a_m[1]; } // //Low-Resolution if(hrs_mode[1] == "lr") { //V-polar flo_u1_v = (9.25 - bw_v / 2.0 + hrv_up_ol1) * 1000.0; //Implement SCR-1243: 14.4 and 14.42 GHz not allowed flo_u1_v = Check_HRS_prohibited_LO_proc_fm(flo_u1_v); a_m = GetA_M(flo_u1_v); a_m_parameter[13] = a_m[0]; a_m_parameter[14] = a_m[1]; flo_l2_v = (9.25 + bw_v / 2.0 + hrv_up_ol2) * 1000.0; //Implement SCR-1243: 14.4 and 14.42 GHz not allowed flo_l2_v = Check_HRS_prohibited_LO_proc_fm(flo_l2_v); a_m = GetA_M(flo_l2_v); a_m_parameter[15] = a_m[0]; a_m_parameter[16] = a_m[1]; flo_u3_v = (9.25 - bw_v / 2.0 + hrv_up_ol3) * 1000.0; //Implement SCR-1243: 14.4 and 14.42 GHz not allowed flo_u3_v = Check_HRS_prohibited_LO_proc_fm(flo_u3_v); a_m = GetA_M(flo_u3_v); a_m_parameter[17] = a_m[0]; a_m_parameter[18] = a_m[1]; flo_l4_v = (9.25 + bw_v / 2.0 + hrv_up_ol4) * 1000.0; //Implement SCR-1243: 14.4 and 14.42 GHz not allowed flo_l4_v = Check_HRS_prohibited_LO_proc_fm(flo_l4_v); a_m = GetA_M(flo_l4_v); a_m_parameter[19] = a_m[0]; a_m_parameter[20] = a_m[1]; } // //Wide-Band if(hrs_mode[0] == "wb") { //H-polar flo_u1_h = (9.25 + hrh_up_ol1) * 1000.0; //Implement SCR-1243: 14.4 and 14.42 GHz not allowed flo_u1_h = Check_HRS_prohibited_LO_proc_fm(flo_u1_h); a_m = GetA_M(flo_u1_h); a_m_parameter[0] = a_m[0]; a_m_parameter[1] = a_m[1]; flo_l2_h = (9.25 + hrh_up_ol2) * 1000.0; //Implement SCR-1243: 14.4 and 14.42 GHz not allowed flo_l2_h = Check_HRS_prohibited_LO_proc_fm(flo_l2_h); a_m = GetA_M(flo_l2_h); a_m_parameter[2] = a_m[0]; a_m_parameter[3] = a_m[1]; flo_u3_h = (9.25 + hrh_up_ol3) * 1000.0; //Implement SCR-1243: 14.4 and 14.42 GHz not allowed flo_u3_h = Check_HRS_prohibited_LO_proc_fm(flo_u3_h); a_m = GetA_M(flo_u3_h); a_m_parameter[4] = a_m[0]; a_m_parameter[5] = a_m[1]; flo_l4_h = (9.25 + hrh_up_ol4) * 1000.0; //Implement SCR-1243: 14.4 and 14.42 GHz not allowed flo_l4_h = Check_HRS_prohibited_LO_proc_fm(flo_l4_h); a_m = GetA_M(flo_l4_h); a_m_parameter[6] = a_m[0]; a_m_parameter[7] = a_m[1]; } // //Wide-Band if(hrs_mode[1] == "wb") { //V-polar flo_u1_v = (9.25 + hrv_up_ol1) * 1000.0; //Implement SCR-1243: 14.4 and 14.42 GHz not allowed flo_u1_v = Check_HRS_prohibited_LO_proc_fm(flo_u1_v); a_m = GetA_M(flo_u1_v); a_m_parameter[13] = a_m[0]; a_m_parameter[14] = a_m[1]; flo_l2_v = (9.25 + hrv_up_ol2) * 1000.0; //Implement SCR-1243: 14.4 and 14.42 GHz not allowed flo_l2_v = Check_HRS_prohibited_LO_proc_fm(flo_l2_v); a_m = GetA_M(flo_l2_v); a_m_parameter[15] = a_m[0]; a_m_parameter[16] = a_m[1]; flo_u3_v = (9.25 + hrv_up_ol3) * 1000.0; //Implement SCR-1243: 14.4 and 14.42 GHz not allowed flo_u3_v = Check_HRS_prohibited_LO_proc_fm(flo_u3_v); a_m = GetA_M(flo_u3_v); a_m_parameter[17] = a_m[0]; a_m_parameter[18] = a_m[1]; flo_l4_v = (9.25 + hrv_up_ol4) * 1000.0; //Implement SCR-1243: 14.4 and 14.42 GHz not allowed flo_l4_v = Check_HRS_prohibited_LO_proc_fm(flo_l4_v); a_m = GetA_M(flo_l4_v); a_m_parameter[19] = a_m[0]; a_m_parameter[20] = a_m[1]; } // //Get LO5 to LO7 // a_m = GetA_M(hrh_down_ol5 * 1000.0); a_m_parameter[8] = a_m[0]; a_m_parameter[9] = a_m[1]; a_m = GetA_M(hrv_down_ol5 * 1000.0); a_m_parameter[21] = a_m[0]; a_m_parameter[22] = a_m[1]; // //flo6 is 1.25, we use a trick here since the formula for lo6 is 25(M+1)+2.5A double flo6_h = hrh_down_ol6 + 8.75; double flo6_v = hrv_down_ol6 + 8.75; a_m = GetA_M(flo6_h * 1000.0); //should be 49,0 a_m_parameter[10] = a_m[0]; a_m_parameter[11] = a_m[1]; a_m = GetA_M(flo6_v * 1000.0); //should be 49,0 a_m_parameter[23] = a_m[0]; a_m_parameter[24] = a_m[1]; // a_m_parameter[12] = iround((flo7_h * 1000.0 - 350.0) / 20.0); //flo7 = 2(10(M+1)+A), A=5, M = M+16 a_m_parameter[25] = iround((flo7_v * 1000.0 - 350.0) / 20.0); //So 490 MHz is M=7. // //debug_print("Tuning result " + a_m_parameter); return a_m_parameter; } // FPU Standby with chopper switched on and to be used for open-loop. // Ensures that chopper will be commanded to zero-position, block block Band0_chopper_at_zero_block_fm HIFI 3296 { string band = "0"; // HIFI band string chop_loop = "CLOSE"; // Chopper Loop status string hbb_heater = "ON" in ["ON","OFF"]; //hot source on/off }{ Start_block(); //Get parameters {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,0.0); int band_nb = iround(result_d[0]{0}); // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,0.0); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // string chop_sine_s = "ON"; result_d = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,0.0); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // double calibcurrent = result_d[7]{0}; if(hbb_heater == "ON") { result_d = ConfigurationReader("name_confilfpu",["calibrator_current_on"],band,0.0); calibcurrent = result_d[0]{0}; } // result_d = ConfigurationReader("name_confilfpu",["bias_standby_h","diplexer_standby_h","bias_standby_v","diplexer_standby_v","diplex_h_ctrl_mode","diplex_v_ctrl_mode","chop_M3right"],band,0.0); // double bias_H = result_d[0]{0}; double diplex_H = result_d[1]{0}; double bias_V = result_d[2]{0}; double diplex_V = result_d[3]{0}; int diplex_h_ctrl_mode = iround(result_d[4]{0}); int diplex_v_ctrl_mode = iround(result_d[5]{0}); // //Retrieve magnets Magnet are so far at maximum value. Now set to nominal double magnetcurrent_H = result_d[1]{0}; double magnetcurrent_V = result_d[4]{0}; // if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilfpu",["magnet_standby_h","magnet_standby_v"],band,0.0); magnetcurrent_H = result_d[0]{0}; magnetcurrent_V = result_d[1]{0}; } // result_d = ConfigurationReader("name_chopper",["chop_startup_cold"],band,0.0); //Here we force to 0.0 even in CLOSE loop double chopper = 0.0; //result_d[0]{0}; //For this configuration we won't convert prime chopper voltage into redundant voltage //Just checking we are in range. //chopper = Check_Chopper_Prime_Redundant(chopper); chopper = Check_Chopper_Range(chopper); // // //Switch on upconverter, assuming chopper and mixers are also ON Hifi_HIFI_Configure_FCU_Power($BBID,"ON","ON","ON","ON","ON"); // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result_d = ConfigurationReader("name_delays",["config_fpu_delay"],band,0.0); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // } //Set LCU6Hb back to standby status, procedure procedure LCU6Hb_standby_proc_fm { string band = "7b"; // HIFI band double lo_freq = 1800.0 in [1800.0,1900.0]; //LO frequency }{ error("This module is obsolete: use LCU_standby_proc_fm instead"); } // Spectra obtained with the mixer bias low in the resistive region block Spectra_resistive_low_fm HIFI 3231 { string band = "1a"; double bias_h = 0.0; double bias_v = 0.0; int integ_time = 4; //Total integration time in sec.: at least 2sec ! string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block() ; Mixerbias(bias_h,bias_v); HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // } // Stability test, procedure // Measurement of internal cold against internal hot procedure Proc_stability_intcold_inthot { string band = "1a"; // HIFI band int n = 100; //Number of load pairs to be measured string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int integ_time = 4; //Total (co-added) integration time of a phase in sec. string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string chopmode = "slowchop" in ["slowchop","fastchop"]; //Whether to use slowchop or fastchop double chop_phase = 1.0 in [0.2,2.0]; // Chop phase length }{ // Chopper_Rotation_block_fm(band,"chop_M3_ang","chop_hot_ang"); //Look at HBB // //WBS calibration if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band); WBS_tune_proc_fm(band); } if(backend == "hrs" || backend == "both" || backend == "hrsFast") { //Configure and tune backends HRS_config_block_fm(band,hrs_mode); HRS_tune_block_fm(band); } // //Configure spectrometers integration after tuning: done later //Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); // Stability_intcold_inthot_fm(band,n,integ_time,hrs_mode,backend,chopmode,chop_phase); //Configure spectrometers integration back to default in tp mode Configure_Spectrometer_proc_fm(band,4,hrs_mode,backend); //2 sec. integration } //Retune HIFI - keep magnet and backends procedure HIFITuneFreqNoretune { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; //LO frequency }{ // frequency setup, stored in FSW1 register LCU_config_nominal_noretune_block_aot(band,lo_freq / 1000.0,false); // } // Check constancy of magnet current across scan procedure CheckSpectralScanRange { string band = "4a"; // HIFI band double lo_freq = 978200.0; // reference LO frequency in MHz double lo_freq_low = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz }{ // The current implementation assumes that the magnet current does not // change within a spectral scan - to be sure I add a check if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { // first frequency {double,string}[] result_d = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq / 1000.0); bool ok = true; double mxmg_h = result_d[0]{0}; double mxmg_v = result_d[1]{0}; // second frequency result_d = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq_low / 1000.0); if(mxmg_h != result_d[0]{0} || mxmg_v != result_d[1]{0}) { ok = false; } // third frequency result_d = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq_up / 1000.0); if(mxmg_h != result_d[0]{0} || mxmg_v != result_d[1]{0}) { ok = false; } if(!ok) { CError("Magnet field not constant across selected spectral scan range"); } } } {int,double,double,double,double,double} obs HifiPointModeLoadChopNoRef { string modeName = "load"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rates int n_cycles = 2 in [1,3600]; // number of half load-sky-sky-load cycles on ON int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode OpenMessages("HIFI Single Point - Load Chop noRef",{data_time,0,0,0,0,0,0,0,n_cycles,load_interval}); // Call first part of the timing computer {int,int,int,int,int,int,bool,int,int} pre_timing_f = LoadChopNoRef_pre_timing(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_cycles,load_interval,docommands); // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,double,double,int} tpar_f = Fine_telescope(naifid,onPosition,band,lo_freq,pre_timing_f); // Dummy call to spacecraft command int[] telescopetimes = basic_fine_pointing(false,tpar_f{0},tpar_f{1},tpar_f{2},tpar_f{3},tpar_f{4},tpar_f{5},tpar_f{6},tpar_f{7},tpar_f{8},tpar_f{9}); // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,bool,int,int},double,double} post_timing_f = SingleChopNoRef_post_timing(pre_timing_f,telescopetimes); // Now the actual observation starts // Prepare telescope command tpar_f = Fine_telescope(naifid,onPosition,band,lo_freq,post_timing_f{1}); // Call telescope command telescopetimes = basic_fine_pointing(true,tpar_f{0},tpar_f{1},tpar_f{2},tpar_f{3},tpar_f{4},tpar_f{5},tpar_f{6},tpar_f{7},tpar_f{8},tpar_f{9}); // Consistency check int totaltime = post_timing_f{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following ////////////////////////////////////////////////////////////////////// // standard parameters for fine pointing int loadlength = post_timing_f{1}{2}; int n_per_on = post_timing_f{1}{4}; int n_load_on = post_timing_f{1}{5}; bool end_load_on = post_timing_f{1}{6}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands ////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { LoadChopNoRef_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_per_on,n_load_on,end_load_on,startobs,telescopetimes,loadlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // There are no telescope dead times involved in this mode {double,double,double} tact = SingleChop_deadtimes("lchop",band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_per_on); double tscan = 2.0 * (tact{1} + tact{2}); double tdead = 2.0 * tact{2}; // // Call noise computer {double,double,double,double,double} noisevalues = PositionSwitch_noisecomputer(band,lo_freq,effResolution,oneGHzReference,n_per_on * (n_load_on + 1),tscan,tdead); // Evaluate performance SingleChopNoRef_performance(band,lo_freq,effResolution,noisevalues,timeTaken,n_per_on * (n_load_on + 1),false,tscan,tdead); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } ////////////////////////////////////////////////////////////////////////// // Procedure for telescope commanding is inherited from DBS mode //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the observing mode procedure SScanDBS_commanding { string band = "4a"; // HIFI band double reffreq = 978300.0; // Reference characteristic LO frequency {double,double} eff_resolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int grouplen = 1; // Number of frequency steps per nodding phase int[][] grouporder = [[0],[0]]; // Sequence to trace frequency points in both phases double[] freqgrid = [978053.7,978301.8,978381.1]; // Table of frequency points bool retuning = false; // need for WBS retuning double[] targetlevels = [1.0,1.0,1.0]; // WBS tuning levels int data_time = 4; // chunk size int n_cycles = 1; // Number of half OFF-ON-ON-OFF cycles at one frequency int allsteps = 4; // Total number of frequency pointing periods int n_bchop = 1; // Normal number of chop cycles per frequency and pointing int n_long = 1; // Chop cycles per frequency and pointing without retuning int n_loadinterval = 1; // number of nods before a load measurement int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,20,1,21,0]; // Timing of the observation from telescope int shiftlength = 10; // Shift of the loop start relative to the pointing }{ // Auxiliary variables // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time int tnodslew = telescopetimes[2]; // slew dead time between points // First frequency double runningfreq = freqgrid[grouporder[0][0]]; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] rates = dataparms{1}; int hkduration = HkReadoutTime(band,reffreq,backendreadoutparms,false); int readoutdead = SlowChopReadoutDelay(band,reffreq,backendreadoutparms); // recompute load duration for initial load measurement int loadlength = duration(SScanLoadMeasurement(band,runningfreq,reffreq,true,eff_resolution{0},data_time,backendreadoutparms)); loadlength = loadlength + readoutdead; bool retuneload = n_loadinterval > 1; // Tuning levels string[] targetnames = TargetNames(band,reffreq,retuning,targetlevels); string target = targetnames[0]; // All commands with a duration possibly depending on the frequency // are taken at the reference frequency to guarantee synchonization // Declare auxiliary variables to be used in the loops int i_freqcycles = 0; int i_group = 0; int i_phase = 0; // variables storing the configuration setting bool islong = false; bool isinvalid = true; //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; bool runintostate = false; while(state[0] >= 0) { if(runintostate) { state = next_state_no_check(); } else { state = next_state(); } if(state[0] == 1) { // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // HIFIInitObs(); TuneHIFI(band,runningfreq,hrs1,hrs2,wbs1{0},wbs2{0},target); delay(tinitslew - (time() - startobs) - loadlength + shiftlength - hkduration); // First load measurement HIFISetHK("normal",false); SScanLoadMeasurement(band,runningfreq,reffreq,true,eff_resolution{0},data_time,backendreadoutparms); if(shiftlength > 0) { runintostate = true; } else { runintostate = false; } } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 3) { // First nodding position i_phase = (state[2] + 1) % 2; // Reset group counter i_group = 0; runintostate = false; // long integrations not possible in last and first nod cycle if(n_cycles > 1 && state[2] % n_cycles != state[2] % 2) { if(isinvalid || !islong) { HIFIConfigureSlowChopIntegration(data_time,n_long,band,reffreq,backendreadoutparms); islong = true; isinvalid = false; } HIFISlowChopOnIntegration(data_time,n_long,band,reffreq,rates); } else { if(isinvalid || islong) { HIFIConfigureSlowChopIntegration(data_time,n_bchop,band,reffreq,backendreadoutparms); islong = false; isinvalid = false; } while(i_group < grouplen - 1) { HIFISlowChopOnIntegration(data_time,n_bchop,band,reffreq,rates); // retune i_group = i_group + 1; runningfreq = freqgrid[grouporder[i_phase][i_group] + i_freqcycles * grouplen]; HIFIChangeFreq(band,runningfreq); } HIFISlowChopOnIntegration(data_time,n_bchop,band,reffreq,rates); // Now we switch to the next frequency group or repeat the cycle if(state[2] % n_cycles == 0 && i_phase == 1) { // Big tuning step, but not at end of observation if(state[2] < allsteps) { i_freqcycles = i_freqcycles + 1; runningfreq = freqgrid[grouporder[0][0] + i_freqcycles * grouplen]; target = targetnames[i_freqcycles]; HIFIRetuneFreq(band,runningfreq,target); runintostate = true; } } } // Active WBS HK if we have a nod slew without calibration if(state[2] % 2 == 1 && state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } if(state[0] == 7) { // second nod position i_phase = state[2] % 2; // First nodding position // Reset group counter i_group = 0; runintostate = false; // long integrations not possible in last and first nod cycle if(n_cycles > 1 && state[2] % n_cycles != (state[2] + 1) % 2) { if(isinvalid || !islong) { HIFIConfigureSlowChopIntegration(data_time,n_long,band,reffreq,backendreadoutparms); islong = true; isinvalid = false; } HIFISlowChopOffIntegration(data_time,n_long,band,reffreq,rates); } else { if(isinvalid || islong) { HIFIConfigureSlowChopIntegration(data_time,n_bchop,band,reffreq,backendreadoutparms); islong = false; isinvalid = false; } while(i_group < grouplen - 1) { HIFISlowChopOffIntegration(data_time,n_bchop,band,reffreq,rates); // retune i_group = i_group + 1; runningfreq = freqgrid[grouporder[i_phase][i_group] + i_freqcycles * grouplen]; HIFIChangeFreq(band,runningfreq); } HIFISlowChopOffIntegration(data_time,n_bchop,band,reffreq,rates); // Now we switch to the next frequency group or repeat the cycle if(state[2] % n_cycles == 0 && i_phase == 1) { // Big tuning step, but not at end of observation if(state[2] < allsteps) { i_freqcycles = i_freqcycles + 1; runningfreq = freqgrid[grouporder[0][0] + i_freqcycles * grouplen]; target = targetnames[i_freqcycles]; HIFIRetuneFreq(band,runningfreq,target); runintostate = true; } } } // Active WBS HK if we have a nod slew without calibration if(state[2] % 2 == 0 && state[2] % n_loadinterval > 0) { HIFIActiveHK("normal",tnodslew); } } if(state[0] == 9) { // Load nod delay(readoutdead); SScanLoadMeasurement(band,runningfreq,reffreq,retuneload,eff_resolution{0},data_time,backendreadoutparms); isinvalid = true; runintostate = false; } if(state[0] == 5) { // The instrument stops halftunelength before the telescope // but I have to wait to close the observation HIFICloseObs(); } } } {string,double,double}[] procedure HifiMappingModeLoadChopOTFSequencerInit { string modeName = "load-raster"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // chunk size given by the data rates and optimum speed int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 1 in [1,1800]; // Supersamplingfactor int n_switch_off = 3 in [1,3600]; // Number of data dumps for the OFF integration time int n_linesperscan = 1 in [1,32]; // Number of lines between two OFFs int n_cycles = 1 in [1,1200]; // Number of map coverages int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode // limit on data rate {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // limits from noise section {double,double,double,double} phaselengths = LoadChopPhaseLengths(band,lo_freq,effResolution,oneGHzReference); // Compute derived quantities // Main loop int main_phase = iceil(phaselengths{0}); // How many lines could we do at most? int n_linesperscan_guess = main_phase / (2 * datalimit) + 1; n_linesperscan_guess = imax(n_linesperscan_guess * n_linesperscan_guess / npoints,1); // restrict the scan size if(nlines == 1 && n_linesperscan_guess > 1) { n_linesperscan_guess = 2; } else { n_linesperscan_guess = IMultiple(n_linesperscan_guess,nlines); n_linesperscan_guess = imin(n_linesperscan_guess,nlines); } int n_linesperscan_range = 1 - n_linesperscan_guess; if(n_linesperscan_range == 0) { n_linesperscan_range = 1; } double n_pointsperscan = double(n_linesperscan * npoints); // Compute back int int_time_guess = main_phase / iceil(sqrt(n_pointsperscan)); int data_time_guess = imin(imax(iceil(phaselengths{1}),datalimit),20); int n_switch_on_guess = imax(int_time_guess / (2 * data_time_guess),1); int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } data_time_guess = imax(imin(5,int_time_guess / (2 * n_switch_on_guess)),datalimit); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } // OFF phase int data_time_off_guess = imin(imax(iceil(phaselengths{2}),datalimit),20); int data_time_off_range = datalimit - data_time_off_guess; if(data_time_off_range == 0) { data_time_off_range = 1; } int n_switch_off_guess = imax(iceil(double(data_time_guess * n_switch_on_guess) * 0.67 * sqrt(n_pointsperscan) / (double(data_time_off_guess) * sqrt(phaselengths{3} / effResolution{1}))),1); int n_switch_off_range = 1 - n_switch_off_guess; if(n_switch_off_range == 0) { n_switch_off_range = 1; } // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"data_time_off",double(data_time_off_guess),double(data_time_off_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)},{"n_switch_off",double(n_switch_off_guess),double(n_switch_off_range)},{"n_linesperscan",double(n_linesperscan_guess),double(n_linesperscan_range)}]; return retvalues; } //TM check when in standby I procedure Mode_status_check_standby_I { string chopper_loop = "OPEN" in ["OPEN","CLOSE"]; //chopper loop status string sequence_order = "up" in ["down","up"]; //order in which sequence is done string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ mois_comment("Checking instrument status in standby I mode"); //General checks: only done when going from intermediate if(sequence_order == "up") { mois_tmcheck("Check that the HK parameter HI_FCU_S, HI_WBSH_S, HI_WBSV_S, HI_HRSH_S, HI_HRSV_S and HI_LCU_S are all ON."); } //FCU checks: only done when going from intermediate {double,string}[] result_d = ConfigurationReader("name_confilfpu",["calibrator_current_on"],"0",0.0); double calibcurrent = result_d[0]{0}; if(sequence_order == "up") { mois_tmcheck("Check that parameter HF_DH1_MXBAND and HF_DV1_MXBAND are both 0"); mois_tmcheck("Check that parameter HF_APR_CS_C is set to " + calibcurrent + " mA. If not, you can proceed but need to inform the HIFI ICC."); mois_tmcheck("Check that parameter HF_DPR_CHLOOP_S is set to " + chopper_loop); } //Chopper voltage string chop_startup_prime_red = "chop_startup_cold_prime"; if(prime_or_redundant == "Red") { chop_startup_prime_red = "chop_startup_cold_red"; } result_d = ConfigurationReader("name_chopper",[chop_startup_prime_red],"0",0.0); if(chopper_loop == "OPEN") { result_d = ConfigurationReader("name_chopper",["chop_startup_warm"],"0",0.0); } if(sequence_order == "up") { mois_tmcheck("Check that parameter HF_DPR_CH_ROT is set to " + result_d[0]{0}); } //WBS checks result_d = ConfigurationReader("name_configwbs",["hwh_latchup_s","hwv_latchup_s"],"0",0.0); string hwh_latchup_s = "Low"; if(result_d[0]{1} == "Level2") { hwh_latchup_s = "High"; } string hwv_latchup_s = "Low"; if(result_d[1]{1} == "Level2") { hwv_latchup_s = "High"; } mois_tmcheck("Check that parameters HWH_Laser1_S, HWH_Laser2_S, HWV_Laser1_S and HWV_Laser2_S are all OFF"); if(sequence_order == "up") { mois_tmcheck("Check that both parameters HWH_Zero_S and HWV_Zero_S are ON"); mois_tmcheck("Check that both parameters HWH_Comb_S and HWV_Comb_S are OFF"); mois_tmcheck("Check that parameters HWH_LUP_level_S and HWV_LUP_level_S are " + hwh_latchup_s + " and " + hwv_latchup_s + " respectively"); mois_tmcheck("Check that parameter HWH_IN_ATT is set to 15, and parameters HWH_Band_1_ATT, HWH_Band_2_ATT, HWH_Band_3_ATT, HWH_Band_4_ATT are set to 7"); mois_tmcheck("Check that parameter HWV_IN_ATT is set to 15, and parameters HWV_Band_1_ATT, HWV_Band_2_ATT, HWV_Band_3_ATT, HWV_Band_4_ATT are set to 7"); } //HRS Checks: HRS only modified if from intermediate to standbyI if(sequence_order == "up") { // Fetch HRS configuration parameters //=================================== //H-polar string hrs_filename_h = "name_confighrs_wb"; {double,string}[] result = ConfigurationReader(hrs_filename_h,["hrh_switch","hrh_1u_att","hrh_1l_att","hrh_2u_att","hrh_2l_att","hrh_3u_att","hrh_3l_att","hrh_4u_att","hrh_4l_att","hrh_up_ol1","hrh_up_ol2","hrh_up_ol3","hrh_up_ol4","hrh_down_ol5","hrh_down_ol6","hrh_down_ol7"],"0",0.0); string hrs_polarization_h = result[0]{1}; double[] hrsH_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; //V-polar string hrs_filename_v = "name_confighrs_wb"; result = ConfigurationReader(hrs_filename_v,["hrv_switch","hrv_1u_att","hrv_1l_att","hrv_2u_att","hrv_2l_att","hrv_3u_att","hrv_3l_att","hrv_4u_att","hrv_4l_att","hrv_up_ol1","hrv_up_ol2","hrv_up_ol3","hrv_up_ol4","hrv_down_ol5","hrv_down_ol6","hrv_down_ol7"],"0",0.0); string hrs_polarization_v = result[0]{1}; double[] hrsV_LO = [result[9]{0},result[10]{0},result[11]{0},result[12]{0},result[13]{0},result[14]{0},result[15]{0}]; // mois_tmcheck("Check that parameters HRH_1U_ATT, HRH_1L_ATT, HRH_2U_ATT, HRH_2L_ATT, HRH_3U_ATT, HRH_3L_ATT, HRH_4U_ATT and HRH_4L_ATT are set to 15.5"); mois_tmcheck("Check that parameters HRV_1U_ATT, HRV_1L_ATT, HRV_2U_ATT, HRV_2L_ATT, HRV_3U_ATT, HRV_3L_ATT, HRV_4U_ATT and HRV_4L_ATT are set to 15.5"); mois_tmcheck("Check that parameters HRH_LOCK_LO1_S, HRH_LOCK_LO2_S, HRH_LOCK_LO3_S, HRH_LOCK_LO4_S, HRH_LOCK_LO5_S, HRH_LOCK_LO6_S, and HRH_LOCK_LO7_S are all Locked"); mois_tmcheck("Check that parameters HRV_LOCK_LO1_S, HRV_LOCK_LO2_S, HRV_LOCK_LO3_S, HRV_LOCK_LO4_S, HRV_LOCK_LO5_S, HRV_LOCK_LO6_S, and HRV_LOCK_LO7_S are all Locked"); Check_HRS_LO_proc_ops(["wb","wb"],hrsH_LO[0],hrsH_LO[1],hrsH_LO[2],hrsH_LO[3],hrsH_LO[4],hrsH_LO[5],hrsH_LO[6],hrsV_LO[0],hrsV_LO[1],hrsV_LO[2],hrsV_LO[3],hrsV_LO[4],hrsV_LO[5],hrsV_LO[6]); } //LOU Checks: first time to check LOU HK when coming from intermediate if(sequence_order == "up") { mois_tmcheck("Check that parameter HL_MODE_S is standby"); mois_tmcheck("Check that parameter HL_Channel_S is Off"); } } // Get maximum delay needed for backend readout after FastChopSpectroscopy int procedure FastChopReadoutDelay { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{true,1,[true,true,true,true]},{true,1,[true,true,true,true]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]},{true,[[0,2048],[0,2048],[0,2048],[0,2048]]}}; // HRS1/2 {used,resolution,subbands used}, WBS1/2 {used, channel windows} }{ // Currently the delay applies independent from the spectrometer selection // if (backendreadoutparms{2}{0} || backendreadoutparms{3}{0}) { double[] dead = CalibrationReader("fastchopreadout",["fastchopreadout"],band,lo_freq); // } return iceil(dead[0]); } // Equivalent procedure for the nodding_of_raster pointing mode {int,int,int,string,int,double,double,bool,double,double,double,int,int,double,double,int,int,double,double,int,int,int,int,int} procedure DBSMultiRaster_telescope { int naifid = 0; // Tracing object ID {double,double} mapcenter = {0.0,0.0}; // Coordinates of the center of the map {double,double} linedistance = {0.0050,0.0050}; // Distance between subsequent rows double stepsize = 0.0050; // Distance between subsequent points in the raster line int nlines_tot = 1; // Number of rows in the map; int npoints = 10; // Number of points per row string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz string throw = ""; // Identifier for chop throw, empty is standard {int,int,int,int,int,int,int,int,int,int,int,int,int} timing = {4,10,4,21,1,1800,0,10,1,1,1,50,0}; // full timing parameter list int n_cycles = 1; // Number of half OFF-ON-ON-OFF pointing cycles }{ // Assign values int pointing = timing{1}; int loadlength = timing{3}; int n_loadinterval = timing{7}; int n_pointsperscan = timing{10}; int initlength = timing{11}; int dangling = timing{12}; // Create variables for telescope command string ib = GetBoresight(band,lo_freq,true); // A change of ra-dec depending on naifid may be needed double ra = mapcenter{0}; double dec = mapcenter{1}; double patt = AngleFromVector(linedistance); patt = RotateRight(patt); // Pattern angle and throw of the chopper direction // The nodding angle should always be parallel to the chopper double[] chopper = GetSkyChopThrow(band,lo_freq,throw); double nodlength = chopper[0]; double pattnod = chopper[1]; nodlength = max(nodlength * 3600.0,2.0); // Map always in sky coordinates, // (nod is always in instrument coordinates by default) bool fixed = true; // Map parameters double rowstep = 0.5 / 3600.0; double d1 = double(iceil(stepsize / rowstep)) * rowstep * 3600.0; double linestep = 0.5 / 3600.0; double d2 = AngleVectorLength(linedistance); d2 = double(iceil(d2 / linestep)) * linestep * 3600.0; // Exception for the "impossible" case of spacings below 2arcsec d1 = max(d1,2.0); d2 = max(d2,2.0); // no load slew if period too long if(n_loadinterval > npoints * nlines_tot * n_cycles / n_pointsperscan) { n_loadinterval = 0; } // Check parameter compatibility with pointing command for parameters // which are no direct input parameters if(pointing < 10) { SError("Pointing phase length too short. Increase the number of integrations."); } if(nodlength > 960.0) { IError("Nodding length too long. Choose a smaller chop throw."); } if(d1 > 480.0) { IError("Raster point spacing too coarse. Increase the sampling."); } if(d2 > 480.0) { IError("Raster line spacing too coarse. Increase the sampling."); } // repetition at multiple frequencies not yet implemented: int trep = 0; int n_repeat = 1; // return parameters in required order return {initlength,0,dangling,ib,naifid,ra,dec,fixed,patt,0.0,0.0,npoints,nlines_tot,d1,d2,pointing,trep,pattnod,nodlength,n_cycles,n_pointsperscan,n_repeat,loadlength,n_loadinterval}; } // LO settling time for a LO sub-band change, 3rd block // Block for third tuning block LO_Settling_time_third_tuning_fm HIFI 3682 { string band_a = "1a" in ["1a","2a","3a","4a","5a","6a","7a"]; // HIFI band a int int_time2 = 600; //Integration time after first and second switch double lo_freq_a = 500.0; //LO frequency in sub-band a string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); // //Init and tune of LO: configuration from safe to tuned. LCU_config_nominal_proc_fm(band_a,lo_freq_a); LO_tuning_w_mixerchoice_proc(band_a,lo_freq_a,"H"); // //Configure spectroscopy integration Configure_Spectrometer_proc_fm(band_a,int_time2,["wb1","wb1"],backend); //4 sec. integration //Take series of spectra during int_time2 seconds HIFI_Spectr_total_power_proc_fm(band_a,backend,8); // //Now switch off LO sub-band LCU_switch_off_proc_fm(); } // Switch HIFI off, block // Prime and Redundancy are both called, regardless of which is effectively used // block HIFI_global_switch_off_block_ops HIFI 7921 { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ StartBlock_ops(); //Sequentially notify PDU off then switch off S/S // //LOU string lo_subsys = "LO_Prime"; string icu_subsys = "ICU_Prime"; if(prime_or_redundant == "Red") { lo_subsys = "LO_Red"; icu_subsys = "ICU_Red"; } mois_step("Switch OFF LO S/S"); HIFI_notify_PDU_status_off_proc_ops("ON","OFF","ON","ON","ON","ON"); PDU_switch_off_proc_ops(lo_subsys); //WBS-H mois_step("Switch OFF WBS-H S/S"); HIFI_notify_PDU_status_off_proc_ops("ON","OFF","ON","OFF","ON","ON"); PDU_switch_off_proc_ops("WBS_H"); //WBS-V mois_step("Switch OFF WBS-V S/S"); HIFI_notify_PDU_status_off_proc_ops("ON","OFF","OFF","OFF","ON","ON"); PDU_switch_off_proc_ops("WBS_V"); //HRS-H mois_step("Switch OFF HRS-H S/S"); HIFI_notify_PDU_status_off_proc_ops("ON","OFF","OFF","OFF","ON","OFF"); PDU_switch_off_proc_ops("HRS_H"); //HRS-V mois_step("Switch OFF HRS-V S/S"); HIFI_notify_PDU_status_off_proc_ops("ON","OFF","ON","OFF","OFF","OFF"); PDU_switch_off_proc_ops("HRS_V"); //ICU mois_step("Switch OFF DPU and FCU S/S"); HIFI_notify_PDU_status_off_proc_ops("OFF","OFF","OFF","OFF","OFF","OFF"); PDU_switch_off_proc_ops(icu_subsys); //At that stage, the instrument is idle... mois_tmcheck("No telemetry should be received anymore from HIFI."); } // Switch HIFI off, procedure // Prime and Redundancy are both called, regardless of which is effectively used // procedure HIFI_global_switch_off_proc_ops { string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ //Sequentially notify PDU off then switch off S/S // //LOU string lo_subsys = "LO_Prime"; string icu_subsys = "ICU_Prime"; if(prime_or_redundant == "Red") { lo_subsys = "LO_Red"; icu_subsys = "ICU_Red"; } mois_step("Switch OFF LO S/S"); HIFI_notify_PDU_status_off_block_ops("ON","OFF","ON","ON","ON","ON"); PDU_switch_off_block_ops(lo_subsys); //WBS-H mois_step("Switch OFF WBS-H S/S"); HIFI_notify_PDU_status_off_block_ops("ON","OFF","ON","OFF","ON","ON"); PDU_switch_off_block_ops("WBS_H"); //WBS-V mois_step("Switch OFF WBS-V S/S"); HIFI_notify_PDU_status_off_block_ops("ON","OFF","OFF","OFF","ON","ON"); PDU_switch_off_block_ops("WBS_V"); //HRS-H mois_step("Switch OFF HRS-H S/S"); HIFI_notify_PDU_status_off_block_ops("ON","OFF","OFF","OFF","ON","OFF"); PDU_switch_off_block_ops("HRS_H"); //HRS-V mois_step("Switch OFF HRS-V S/S"); HIFI_notify_PDU_status_off_block_ops("ON","OFF","ON","OFF","OFF","OFF"); PDU_switch_off_block_ops("HRS_V"); //ICU mois_step("Switch OFF DPU and FCU S/S"); HIFI_notify_PDU_status_off_block_ops("OFF","OFF","OFF","OFF","OFF","OFF"); //If we want to have a chance to switch obsid/bbid to 0, it is here the //last opportunity StopMode_block_ops(); //Finally, switch off ICU PDU_switch_off_block_ops(icu_subsys); //At that stage, the instrument is idle... mois_tmcheck("No telemetry should be received anymore from HIFI."); } ///////////////////////////////////////////////////////////////////////////// // Procedure to perform the noise level evaluation for the OTF observing mode {double,double,double,double,double} procedure OTFLoadChop_noisecomputer { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF int nlines_tot = 1; // Number of rows in the map int data_time = 4; // chunk size given by the data rates and optimum speed int n_switch_on = 1; // Supersamplingfactor int n_linesperscan = 2; // Number of lines between two OFFs int off_inttime = 16; // Integration time per OFF phase int n_cycles = 1; // Number of map coverages double tscan = 60.0; // Total average duration of one scan {double,double,double,double,double} tact = {10.0,4.9,4.9,0.05,0.05}; // Field of actual dead and integration times }{ // The sum of drift noise and radiometric noise is computed. // double tdead = tact{0}; // Average total dead time in one scan double inttimeperonphase = tact{1}; // Actual integration time in ON phase double inttimeperoffphase = tact{2}; // Actual integration time in OFF phase double deadtimeperonphase = tact{3}; // Dead time per switch phase on ON // Get parameters which are needed double tsys = InterpolateTsys(band,lo_freq); double eta_mb = InterpolateCoupling(band,lo_freq); double[] gssb = InterpolateGssb(band,lo_freq); // Get the drift parameters to compute the drift noise double[] allanparms = InterpolateSpecAllan(band,lo_freq,oneGHzReference); // rescale to frequency resolution double alpha = allanparms[1]; double binningexp = 1.0 / allanparms[2]; double allan_time_lores = allanparms[0] * pow(1.0 / eff_resolution{1},binningexp); double allan_time_hires = allanparms[0] * pow(1.0 / eff_resolution{0},binningexp); // Differential Allan variance allanparms = InterpolateSpecLChopAllan(band,lo_freq,oneGHzReference); // rescale to frequency resolution double dalpha = allanparms[1]; binningexp = 1.0 / allanparms[2]; double dallan_time_lores = allanparms[0] * pow(1.0 / eff_resolution{1},binningexp); double dallan_time_hires = allanparms[0] * pow(1.0 / eff_resolution{0},binningexp); // resolution of OFF phase double sw_resolution = GetLoadChopSWResolution(band,lo_freq); double sw_resolution_lores = max(eff_resolution{1},sw_resolution); double sw_resolution_hires = max(eff_resolution{0},sw_resolution); // !!!! The computation of the noise is formally NOT CORRECT for this // !!!! case. For simplicity we use as a rough approximations the equations // !!!! for a double-difference setup instead of a difference with // !!!! OTF scheme !!! // Compute the relative noise for the detailed timing double on_int = double(2 * data_time * n_switch_on); // correct for double scan - treat like integrated in one go if(nlines_tot == 1 && n_linesperscan > 1) { on_int = on_int * double(n_linesperscan); } // fudge factor to taking OFF interpolation into account double off_int = double(off_inttime) * 1.5; // The dead time per switch might deviate between ON and OFF - ignored double deadtimeperswitch = deadtimeperonphase; // Dead time includes other points, but excludes off_int fudging // This is slightly too small (excludes inner point dead time) - ignored double tdiff = max(tscan - on_int - off_int,0.0); // Get actual noise // This is returned twice: for both limiting resolutions double systemnoise_lores = DoubleDifferenceNoise(inttimeperonphase / allan_time_lores,[inttimeperoffphase / inttimeperonphase,sw_resolution_lores / eff_resolution{1},on_int / allan_time_lores,off_int / allan_time_lores,deadtimeperswitch / allan_time_lores,tdiff / allan_time_lores,alpha,dallan_time_lores / allan_time_lores,dalpha]); double systemnoise_hires = DoubleDifferenceNoise(inttimeperonphase / allan_time_hires,[inttimeperoffphase / inttimeperonphase,sw_resolution_hires / eff_resolution{0},on_int / allan_time_hires,off_int / allan_time_hires,deadtimeperswitch / allan_time_hires,tdiff / allan_time_hires,alpha,dallan_time_hires / allan_time_hires,dalpha]); double noiseratio = DoubleDifferenceNoiseRatio(inttimeperonphase / allan_time_lores,[inttimeperoffphase / inttimeperonphase,sw_resolution_lores / eff_resolution{1},on_int / allan_time_lores,off_int / allan_time_lores,deadtimeperswitch / allan_time_lores,tdiff / allan_time_lores,alpha,dallan_time_lores / allan_time_lores,dalpha]); // Compute total double sideband noise double dsbnoise_lores = tsys * sqrt(systemnoise_lores / (eff_resolution{1} * 1000000.0 * double(n_cycles) * tscan)); double dsbnoise_hires = tsys * sqrt(systemnoise_hires / (eff_resolution{0} * 1000000.0 * double(n_cycles) * tscan)); // Translate to the main beam scale, correct for eta_mb // (This is typically not done at ground based telescopes, // but leads often to problems there - to be discussed.) dsbnoise_lores = dsbnoise_lores / eta_mb; dsbnoise_hires = dsbnoise_hires / eta_mb; // Get single sideband noise equivalent double usbnoise_lores = dsbnoise_lores / gssb[0]; double usbnoise_hires = dsbnoise_hires / gssb[0]; double lsbnoise_lores = dsbnoise_lores / gssb[1]; double lsbnoise_hires = dsbnoise_hires / gssb[1]; // Return noise values and the maximum ratio of drift to radiometric noise return {usbnoise_lores,usbnoise_hires,lsbnoise_lores,lsbnoise_hires,noiseratio}; } // FPU Standby with chopper switched on. // Ensures that chopper will be commanded to zero-position, block block Band0_chopper_at_zero_block_ops HIFI 7296 { string band = "0"; // HIFI band string chop_loop = "CLOSE"; // Chopper Loop status string hbb_heater = "ON" in ["ON","OFF"]; //hot source on/off string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ //StartBlock_ops(); //Get parameters {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,0.0); int band_nb = iround(result_d[0]{0}); // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,0.0); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // string chop_sine_s = "ON"; // result_d = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,0.0); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // double calibcurrent = result_d[7]{0}; if(hbb_heater == "ON") { result_d = ConfigurationReader("name_confilfpu",["calibrator_current_on"],band,0.0); calibcurrent = result_d[0]{0}; } // result_d = ConfigurationReader("name_confilfpu",["bias_standby_h","diplexer_standby_h","bias_standby_v","diplexer_standby_v","diplex_h_ctrl_mode","diplex_v_ctrl_mode","chop_M3right"],band,0.0); // double bias_H = result_d[0]{0}; double diplex_H = result_d[1]{0}; double bias_V = result_d[2]{0}; double diplex_V = result_d[3]{0}; int diplex_h_ctrl_mode = iround(result_d[4]{0}); int diplex_v_ctrl_mode = iround(result_d[5]{0}); double chopper = 0.0; // //Retrieve magnets Magnet are so far at maximum value. Now set to nominal double magnetcurrent_H = result_d[1]{0}; double magnetcurrent_V = result_d[4]{0}; // if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilfpu",["magnet_standby_h","magnet_standby_v"],band,0.0); magnetcurrent_H = result_d[0]{0}; magnetcurrent_V = result_d[1]{0}; } // //Switch on upconverter, assuming chopper and mixers are also ON Hifi_HIFI_Configure_FCU_Power($BBID,"ON","ON","ON","ON","ON"); // if(prime_or_redundant == "Prime") { Hifi_HIFI_P_Configure_FCU($BBID,band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); } else { Hifi_HIFI_R_Configure_FCU($BBID,band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); } // result_d = ConfigurationReader("name_delays",["config_fpu_delay"],band,0.0); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // Hifi_HIFI_non_periodic_hk_FCU(); // //mois_tmcheck("Check that parameter HF_APR_CS_C is set to " + calibcurrent + " mA"); //mois_tmcheck("Check that parameter HF_DPR_CHLOOP_S is set to " + chop_loop); mois_tmcheck("Check that parameter HF_DPR_CHSINE_S is set to " + chop_sine_s); // } //Slow chop between sky and Sky, block block Sky_Sky_fm_COP HIFI 3927 { string band = "1a"; int integ_time = 4; //Total integration time for delay computation string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4,etc string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast }{ //Fetch respective chopper angles {double,string}[] result = ConfigurationReader("name_confilfpu",["chop_M3left","chop_M3right"],band,0.0); double chop_M3left = result[0]{0}; double chop_M3right = result[1]{0}; // //Compute data-rate double[] rates = ILT_datarate_proc_fm(band,backend,"slowchop",integ_time); //Take spectrum // set data rates non_ess_hk_data_rate(rates[2] / 1024.0); data_rate(rates[0] / 1024.0); // HIFI_Spectr_slow_chop_proc_fm(chop_M3left,chop_M3right); Apply_Slow_Chop_delay(integ_time,band,backend); // reset data rates non_ess_hk_data_rate(rates[1] / 1024.0); data_rate(0.0); } // Receiver gain and noise procedure Hot_cold { string band = "1a"; // HIFI band string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4,etc string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast int integ_time = 4; //Total integration time per load integration in sec string chopmode = "tp" in ["tp","slowchop","fastchop","fsw"]; //modulation mode between hot/cold: tp, slowchop, fastchop int n_wbs1 = 20; int n_hrs_trans = 1; }{ if(chopmode == "tp") { Hot_spectra_fm(band,integ_time,backend); Cold_spectra_fm(band,integ_time,backend); } if(chopmode == "slowchop") { Hot_cold_slowchop_fm(band,integ_time,hrs_mode,backend); } if(chopmode == "fsw") { Hot_cold_FSW_fm(band,integ_time,backend); } if(chopmode == "fastchop") { Hot_cold_fastchop_fm(band,integ_time,hrs_mode,backend,n_wbs1,n_hrs_trans); } } //HIFI-COP-3-Stab-1 //This one should only be used for preparation of MOIS files //for MOC. It assumes one single obsid for several frequencies //This is not the default approach - see rather HifiEng_Stab_COP mode HifiManCmd_Stab_COP_MOIS { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string stab = "sys" in ["sys","lsw","int","dbs","fsw","stab"]; //category of stability measurement }{ // StartMode_block_ops(); //Allow fast HK readout HKrate_block_ops(1.0); // double band_nb = GetBandCode(band); //General parameters in use string backend = "both"; string[] hrs_mode = ["wb1","wb1"]; int[] res = [0,0]; int n_wbs1 = 0; int n_hrs_trans = 0; string chopmode = "slowchop"; //For bands 6 and 7, use wb8 if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { hrs_mode = ["wb8","wb8"]; } // int integ_time = 4; int n = 900; double chop_phase = 1.0; string shutter = "open"; // //Get the list of frequencies to be used for the scan string tab = "config_stabfreq_" + band + ".config"; int total = table_size(tab); double stabfreq = 0.0; int time_systab = 0; int time_stabil = 20; if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { time_stabil = 45; } // if(stab == "stab") { // stabfreq = dlookup(tab,"1","freq_sys"); Init_MSA_HBB_fm(band,"CLOSE",stabfreq,"ON"); // LCU_switchon_proc_fm(band); // LO_tuning_block_fm(band,stabfreq); HRS_config_block_fm(band,hrs_mode); WBS_calib_fm(band); WBS_tune_proc_fm(band); HRS_tune_block_fm(band); // chopmode = "tp"; n = time_stabil * 60 / integ_time + 1; // Proc_stability_intcold(band,n,hrs_mode,integ_time,backend,chopmode,chop_phase); } // //start loop on frequencies for(int j = 1 .. total) { if(stab != "stab") { stabfreq = dlookup(tab,"" + j,"freq_" + stab); } time_systab = iround(dlookup(tab,"" + j,"tsystab")); //Only deal with non-zero entries if(stabfreq != 0.0) { // if(stab == "int") { n = 450; // Init_MSA_HBB_fm(band,"CLOSE",stabfreq,"ON"); LO_tuning_block_fm(band,stabfreq); WBS_calib_fm(band); WBS_tune_proc_fm(band); HRS_tune_block_fm(band); // Proc_stability_intcold_inthot(band,n,hrs_mode,integ_time,backend,chopmode,chop_phase); } // if(stab == "lsw") { n = 450; // Init_MSA_CBB_fm(band,"CLOSE",stabfreq,"ON"); LO_tuning_block_fm(band,stabfreq); WBS_calib_fm(band); WBS_tune_proc_fm(band); HRS_tune_block_fm(band); // Proc_stability_intcold_exthot(band,n,hrs_mode,integ_time,backend,chopmode,chop_phase); } // if(stab == "sys") { //Start with 4min fast HRS sampling double sampling_rate = 3.0; //Sampling rate: 2 (2 HRS-H + 2 HRS-V), 3 (HRS-H + HRS-V), 4 (2 HRS-H or 2 HRS-V) or 6 (1 HRS-H or 1 HRS-V) Hz. //Note: a 7.4GHz below will be moved by 245MHz, and since this is half of a wb pair //of sub-bands the sub-band will START at 7.65GHz and go until 7.88GHz double hrs_h_1 = 7.4; //Position in IF of HRS-H sub-band 1 double hrs_h_2 = 7.4; //Position in IF of HRS-H sub-band 2 double hrs_v_1 = 7.4; //Position in IF of HRS-V sub-band 1 double hrs_v_2 = 7.4; //Position in IF of HRS-V sub-band 2 double[] hrs_subband = [hrs_h_1,hrs_h_2,hrs_v_1,hrs_v_2]; string hrs_polarization = "B"; //HRS polarization: selection works only for 4 and 8 Hz n = 950; backend = "hrs"; // Init_MSA_HBB_fm(band,"CLOSE",stabfreq,"ON"); LO_tuning_block_fm(band,stabfreq); // if(band_nb > 10.0) { Stability_fast_proc_fm(band,n,hrs_subband,sampling_rate,hrs_polarization); } // chopmode = "tp"; backend = "both"; n = time_systab * 60 / integ_time; // HRS_config_block_fm(band,hrs_mode); WBS_calib_fm(band); WBS_tune_proc_fm(band); HRS_tune_block_fm(band); Proc_stability_intcold(band,n,hrs_mode,integ_time,backend,chopmode,chop_phase); } // if(stab == "fsw") { chopmode = "fsw"; n = 225; // Init_MSA_SKY_fm(band,"CLOSE",stabfreq,"ON"); LO_tuning_block_fm(band,stabfreq); WBS_calib_fm(band); WBS_tune_proc_fm(band); HRS_tune_block_fm(band); // //For FSW, there is an additional loop on various throws //Retrieve frequency throws from LUT string tabfsw = "config_freqthrow.config"; double bandnb = GetBandCode(band); double[] freq_throw = []; for(int i = 1 .. 4) { freq_throw[i] = dlookup(tabfsw,"" + iceil(bandnb),"freq_throw_" + i); bool do_test = true; if(j > 2 && i > 1) { do_test = false; } if(freq_throw[i] != 0.0 && do_test) { //Check that frequencies to switch are not far by more than 1 index Check_FSW_index_proc_fm(band,stabfreq - freq_throw[i] / 2000.0,stabfreq + freq_throw[i] / 2000.0); Proc_stability_freqswitch(band,stabfreq,freq_throw[i],n,hrs_mode,integ_time,backend); } //For one freq. in 1a, 3a, 6a and 7b, the FSW on the CBB is performed string tabfswcbb = "config_stabfreq_fsw_CBB.config"; double fsw_cbb_freq = dlookup(tabfswcbb,"" + iceil(bandnb),"freq_fsw"); double freq_throw_cbb = dlookup(tabfswcbb,"" + iceil(bandnb),"freq_throw_" + i); if(fsw_cbb_freq == stabfreq && freq_throw_cbb == freq_throw[i]) { int n_cbb = n; if(bandnb < 6.0) { //only 15 min n_cbb = n / 2; } Proc_stability_freqswitch_COP_CBB(band,stabfreq,freq_throw[i],n_cbb,hrs_mode,integ_time,backend); } } // } // if(stab == "dbs") { n = 450; // Init_MSA_HBB_fm(band,"CLOSE",stabfreq,"ON"); LO_tuning_block_fm(band,stabfreq); WBS_calib_fm(band); WBS_tune_proc_fm(band); HRS_tune_block_fm(band); // Proc_stability_dbs(band,n,hrs_mode,integ_time,backend,shutter,chopmode,chop_phase); } // } } //Back to slow HK readout HKrate_block_ops(0.25); //end of obsid for LCU switch on StopMode_block_ops(); } //General script to clear error flags and set to nominal, block block LCU_enable_FreqTMY_check_block_fm HIFI 3669 { }{ // //Start_block(); //switch to standby Hifi_HIFI_HL_Standby($BBID); {double,string}[] result = ConfigurationReader("name_delays",["stdby_delay"],"0",0.0); int stdby_delay = iround(result[0]{0}); delay(stdby_delay); //Clear error flags Hifi_HIFI_Conf_LCU_internal($BBID,16383,"RESET","RESET",256); //sets bandmask to 3FFF: all bands //LSU_delta_f: sets to 256 = 88mV //Switch back to nominal Hifi_HIFI_HL_Normal($BBID); int set_to_nominal_delay = stdby_delay; delay(set_to_nominal_delay); // } // Diplexer scan, very fast, procedure // Uses the fast OBS TC procedure Diplexer_scan_proc { string band = "3a" in ["0","3a","3b","4a","4b","6a","6b","7a","7b"]; // HIFI band double diplexer_current_min_h = -2.24; //starting diplexer current H double diplexer_current_min_v = -2.24; //starting diplexer current V double diplexer_current_step = 2.24; //Common diplexer current step int n_steps = 100; //number of steps double stepTime = 0.1; //Step time in seconds: GRANULARITY IS 0.1sec!!!! double lo_freq = 807.0; //LO frequency }{ // //In case of band 6 or 7, use special biases if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { {double,string}[] result = ConfigurationReader("name_confilfpu",["bias_dipscan_h","bias_dipscan_v","bias_max_h","bias_max_v"],band,lo_freq); //First go to 4mV Mixerbias_block_fm(result[2]{0},result[3]{0}); //Then to 3mV Mixerbias_block_fm(result[0]{0},result[1]{0}); } // //Fetch diplexer settings double[] result_dip = Get_Diplexer_setting(band,lo_freq); double diplex_H = result_dip[0]; double diplex_V = result_dip[1]; //Perform scan Scan_diplexer_block_fm(band,diplexer_current_min_h,diplexer_current_min_h,diplexer_current_step,n_steps,stepTime); // //Get back to optimal settings Set_Diplexer_current_block_fm(diplex_H,diplex_V); // //In case of band 6 or 7,go back to nominal values if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { result = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,lo_freq); //First go to 4mV Mixerbias_block_fm(result[0]{0},result[1]{0}); //Then to nominal result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); Mixerbias_block_fm(result[0]{0},result[1]{0}); } // } {int,double,double,double,double,double} obs HifiSScanModeDBS { string modeName = "freq"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_switch_on = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per frequency and pointing int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int n_cycles = 1 in [1,600]; // Number of half OFF-ON-ON-OFF cycles at one frequency int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode OpenMessages("HIFI Spectral Scan - DBS slowChop",{data_time,0,0,n_switch_on,0,0,0,n_freq_point,n_cycles,load_interval}); // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,redundancy,wbs1Used,wbs2Used,data_time); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; ////////////////////////////////////////////////////////////////////// // Call first part of the timing computer {{int,int,int,int,int,int,int,int,int,bool,int,int,int},{int,double,double[],int[][],bool,double[],int,bool}} pre_timing = SScanDBS_pre_timing(band,lo_freq,lo_freq_up,redundancy,effResolution,hr1,hr2,wb1,wb2,data_time,n_switch_on,n_freq_point,n_cycles,load_interval,docommands); // frequency parameters int groupnumber = pre_timing{1}{0}; double reffreq = pre_timing{1}{1}; double[] freqgrid = pre_timing{1}{2}; int[][] grouporder = pre_timing{1}{3}; bool retuning = pre_timing{1}{4}; double[] targetlevels = pre_timing{1}{5}; int nfreq_if = pre_timing{1}{6}; bool dsb = pre_timing{1}{7}; int n_total = groupnumber * n_cycles; ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,int,int,int,int,int,int} tpar = DBS_telescope(naifid,onPosition,band,reffreq,"",pre_timing{0},n_total); // Dummy call to spacecraft command int[] telescopetimes = nodding_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},false); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,bool,int,int,int},double,double,double} post_timing = SScanDBS_post_timing(pre_timing{0},telescopetimes,n_freq_point,groupnumber,n_cycles,false); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = DBS_telescope(naifid,onPosition,band,reffreq,"",post_timing{1},n_total); // Call telescope command telescopetimes = nodding_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},false); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following // normal pre_timing values int n_loadinterval = post_timing{1}{7}; int n_bchop = post_timing{1}{8}; int shiftlength = post_timing{1}{10}; int initlength = post_timing{1}{11}; double avnumchop = post_timing{2}; // efficiency parameters double tscan = post_timing{3}; double tdead = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { SScanDBS_commanding(band,reffreq,effResolution,hr1,hr2,wb1,wb2,n_freq_point,grouporder,freqgrid,retuning,targetlevels,data_time,n_cycles,n_total,n_bchop,n_switch_on,n_loadinterval,startobs,telescopetimes,shiftlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double} tact = SScanDBS_deadtimes(band,reffreq,hr1,hr2,wb1,wb2,n_freq_point,data_time,n_bchop,n_switch_on,n_cycles,avnumchop,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = SScanDBS_noisecomputer(band,reffreq,nfreq_if,dsb,effResolution,continuumDetection,n_cycles,tscan,tact); // Evaluate performance SScanDBS_performance(band,reffreq,nfreq_if,dsb,effResolution,noisevalues,timeTaken,n_total,groupnumber * n_freq_point,avnumchop,tscan,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the DBS raster mode procedure JupiterFastDBSRaster_commanding { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 10 in [4,80]; // data dump interval int n_int = 20; // number chop cycles to integrate in ICU before transfer int n_seq = 1; // number of data transfer cycles per pointing int n_cycles = 1; // Number of half OFF-ON-ON-OFF cycles int n_pointsperscan = 1; // Number of points measured before moving to the second pointing phase int n_loadinterval = 10; // number of nods before a load measurement int n_load = 0; // additional load measurements in one pointing phase bool final_load = false; // Need for final load measurement int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,10,0,10,20,21,0,0,0]; // Timing of the observation from telescope int loadlength = 21; // Load duration bool iscross = false; // Whether we use a cross instead of a raster }{ // Auxiliary variables // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Fixed timings in the fast-chop mode int load_datatime = GetStdLoadReadout(band,lo_freq); // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time //////////////////////////////////////////////////////////////////////// // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // // Clustering is currently not implemented in MPS - switched off here int clustered = 0; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time / 2); double[] rates = dataparms{1}; int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,true); int readoutdead = FastChopReadoutDelay(band,lo_freq,backendreadoutparms); // Count phases by hand to allow simultaneous usage by Raster and Cross int iphase = 0; // There is no nod counter in the return values - count this by hand int inod = 0; // Do I have to make loads in short nods and subsequent holds? if(iscross) { bool holdforload = n_pointsperscan > 1; } else { holdforload = n_pointsperscan == 1 && n_loadinterval > n_cycles; } bool isOffAtPoint = false; //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; int[] choppars = [2 * n_int,0]; bool runintostate = false; while(state[0] >= 0) { if(runintostate) { state = next_state_no_check(); } else { state = next_state(); } if(state[0] == 1) { // Initialization if(clustered != 1) { HIFIInitObs(); TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"jupiter"); } delay(tinitslew - (time() - startobs) - hkduration - loadlength); // First load measurement HIFISetHK("normal",false); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); runintostate = false; iphase = iphase + 1; } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 3) { // First nodding position // Check whether we are in a cross mode using computed OFF isOffAtPoint = iscross && inod % 2 == 0; // Configure measurement choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_seq,band,lo_freq,backendreadoutparms); // Loop for load cycles // The use of n_load differs by 1 from the other observing modes here for(int i1 = 1 .. n_load - 1) { if(isOffAtPoint) { HIFIFastChopOffIntegration(data_time,n_seq,band,lo_freq,choppars,rates); } else { HIFIFastChopOnIntegration(data_time,n_seq,band,lo_freq,choppars,rates); } // Perform load calibration delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_seq,band,lo_freq,backendreadoutparms); } // Last cycle - no load if(isOffAtPoint) { HIFIFastChopOffIntegration(data_time,n_seq,band,lo_freq,choppars,rates); } else { HIFIFastChopOnIntegration(data_time,n_seq,band,lo_freq,choppars,rates); } // Load measurement if required - time included in pointing if(n_load > 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); } // Final point before nod // Special treatment for all cases where load has to be replaced by hold: // n_pointsperscan=1, n_loadinterval > n_cycles if(iphase % n_pointsperscan == 0 && iphase / n_pointsperscan % 2 == 1) { inod = inod + 1; if(holdforload && inod % n_loadinterval == 0 && n_load == 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); runintostate = true; } } else { // keep shift if we come from a holdforload nod, otherwise reset if(!holdforload) { runintostate = false; } } // Update phase counter iphase = iphase + 1; } // Second pointing phase if(state[0] == 7) { // second nod position choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_seq,band,lo_freq,backendreadoutparms); for(int i2 = 1 .. n_load - 1) { HIFIFastChopOffIntegration(data_time,n_seq,band,lo_freq,choppars,rates); // Perform load calibration delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); choppars = HIFIConfigureFastChopIntegration(data_time,n_int,n_seq,band,lo_freq,backendreadoutparms); } // Last cycle HIFIFastChopOffIntegration(data_time,n_seq,band,lo_freq,choppars,rates); // Load measurement if required - time included in pointing if(n_load > 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); } // Final point before nod // Special treatment for all cases where load has to be replaced by hold: if(iphase % n_pointsperscan == 0 && iphase / n_pointsperscan % 2 == 1) { inod = inod + 1; if(holdforload && inod % n_loadinterval == 0 && n_load == 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); runintostate = true; } } else { // keep shift if we come from a holdforload nod, otherwise reset if(!holdforload) { runintostate = false; } } // Update phase counter iphase = iphase + 1; } // Load nod if(state[0] == 9) { // Load nod delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); runintostate = false; } // Hold if(state[0] == 6) { // finished shift of instrument operations relative to pointing command runintostate = false; } // Final load if(state[0] == 5) { delay(readoutdead); if(final_load) { // Perform final load measurement LoadMeasurement(band,lo_freq,eff_resolution{0},load_datatime,backendreadoutparms); } runintostate = false; HIFICloseObs(); } } } ///////////////////////////////////////////////////////////////////////////// // procedure needed for LO tuning ///////////////////////////////////////////////////////////////////////////// //General LO configuration command procedure HIFI_Configure_LCU_proc_aot { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978.2; //LO frequency int freq_nx = 0; // HL_freq_nx int lsu_main = 0; // HL_LSU_main int lsu_offset = 0; // HL_LSU_offset int d2_step = 1; // HL_D2_step double plevel_v = 0.0; double m1_v = 9.0; double m2_v = -2.0; double m3_v = 0.0; double gate1_v = -2.5; double gate2_v = -2.5; double drain1_v = 2.8; string curlim1_v = "1.4"; double drain2_v = 2.6; string curlim2_v = "1.4"; int macro_checksum = 0; // HL_macro_checksum int config_lo_delay = 6; }{ //Check that Vd2 is within the blue limits drain2_v = Check_BLUE_LIMIT_D2_proc_fm(band,lo_freq,drain2_v); // // //Execute configuration //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Conf_safe_LCU_ch1a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "1b") { //Band 1b Hifi_HIFI_Conf_safe_LCU_ch1b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "2a") { //Band 2a Hifi_HIFI_Conf_safe_LCU_ch2a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "2b") { //Band 2b Hifi_HIFI_Conf_safe_LCU_ch2b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "3a") { //Band 3a Hifi_HIFI_Conf_safe_LCU_ch3a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "3b") { //Band 3b Hifi_HIFI_Conf_nom_LCU_ch3b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "4a") { //Band 4a Hifi_HIFI_Conf_safe_LCU_ch4a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "4b") { //Band 4b Hifi_HIFI_Conf_safe_LCU_ch4b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "5a") { //Band 5a Hifi_HIFI_Conf_nom_LCU_ch5a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "5b") { //Band 5b Hifi_HIFI_Conf_nom_LCU_ch5b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "6a") { //Band 6a Hifi_HIFI_Conf_nom_LCU_ch6a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "6b") { //Band 6b Hifi_HIFI_Conf_nom_LCU_ch6b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "7a") { //Band 7a Hifi_HIFI_Conf_nom_LCU_ch7a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "7b") { //Band 7b Hifi_HIFI_Conf_nom_LCU_ch7b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } // delay(config_lo_delay); // //Read TM pages and clear error flags LCU_Read_TM_pages_proc_aot(); } //Generic procedure to launch engineering scan applied to chopper rotation, procedure procedure Engineering_scan_for_chopper_rotation_COP { double targetAngle = 0.0; //Target chopper voltage int milliSecSample = 3; // interval between samples int samplesBefore = 30 in [0,50]; // HIF_N_samples_1 int samplesAfter = 1000 in [0,1000]; // HIF_N_samples_2 string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ // targetAngle = Check_Chopper_Prime_Redundant_COP(targetAngle,prime_or_redundant); if(prime_or_redundant == "Prime") { Hifi_HIFI_P_Chopper_scan_fast(milliSecSample,targetAngle,samplesBefore,samplesAfter); } else { Hifi_HIFI_R_Chopper_scan_fast(milliSecSample,targetAngle,samplesBefore,samplesAfter); } // // delay calculation int nb_HK = 1; //For this TC, the 2 last HK fields are blanked out int millisecondsUsed = 1000 + 10 + milliSecSample * nb_HK * (samplesBefore + samplesAfter); delay(iceil(0.0010 * double(millisecondsUsed))); // } // HRS partial configuration SPECIFIC TO AOT CUS, block // Configures the LO and attenuators block HRS_config_att_lo_block_aot HIFI 6624 { string band = "4a"; // HIFI band string[] hrs_mode = ["mr","mr"]; //HRS resolution code double[] hrsH_LO = [4.5,5.5,6.5,7.5]; //IF position of HRS-H sub-bands double[] hrsV_LO = [4.5,5.5,6.5,7.5]; //IF position of HRS-V sub-bands }{ // Fetch HRS configuration parameters //=================================== //H-polar string hrs_filename_h = "name_confighrs_" + hrs_mode[0]; {double,string}[] result = ConfigurationReader(hrs_filename_h,["hrh_switch","hrh_1u_att","hrh_1l_att","hrh_2u_att","hrh_2l_att","hrh_3u_att","hrh_3l_att","hrh_4u_att","hrh_4l_att","hrh_down_ol5","hrh_down_ol6","hrh_down_ol7"],band,0.0); string hrs_polarization_h = result[0]{1}; double hrsH_ATT_U1 = result[1]{0}; double hrsH_ATT_L1 = result[2]{0}; double hrsH_ATT_U2 = result[3]{0}; double hrsH_ATT_L2 = result[4]{0}; double hrsH_ATT_U3 = result[5]{0}; double hrsH_ATT_L3 = result[6]{0}; double hrsH_ATT_U4 = result[7]{0}; double hrsH_ATT_L4 = result[8]{0}; double[] hrsH_LO_total = [hrsH_LO[0],hrsH_LO[1],hrsH_LO[2],hrsH_LO[3],result[9]{0},result[10]{0},result[11]{0}]; //V-polar string hrs_filename_v = "name_confighrs_" + hrs_mode[1]; result = ConfigurationReader(hrs_filename_v,["hrv_switch","hrv_1u_att","hrv_1l_att","hrv_2u_att","hrv_2l_att","hrv_3u_att","hrv_3l_att","hrv_4u_att","hrv_4l_att","hrv_down_ol5","hrv_down_ol6","hrv_down_ol7"],band,0.0); string hrs_polarization_v = result[0]{1}; double hrsV_ATT_U1 = result[1]{0}; double hrsV_ATT_L1 = result[2]{0}; double hrsV_ATT_U2 = result[3]{0}; double hrsV_ATT_L2 = result[4]{0}; double hrsV_ATT_U3 = result[5]{0}; double hrsV_ATT_L3 = result[6]{0}; double hrsV_ATT_U4 = result[7]{0}; double hrsV_ATT_L4 = result[8]{0}; double[] hrsV_LO_total = [hrsV_LO[0],hrsV_LO[1],hrsV_LO[2],hrsV_LO[3],result[9]{0},result[10]{0},result[11]{0}]; // result = ConfigurationReader("name_delays",["hrs_config_delay"],band,0.0); int hrs_config_delay = iround(result[0]{0}); // //Convert IF frequencies into A and M parameters int[] a_m_parameter = ComputeA_M_parameters(hrs_mode,hrsH_LO_total[0],hrsH_LO_total[1],hrsH_LO_total[2],hrsH_LO_total[3],hrsH_LO_total[4],hrsH_LO_total[5],hrsH_LO_total[6],hrsV_LO_total[0],hrsV_LO_total[1],hrsV_LO_total[2],hrsV_LO_total[3],hrsV_LO_total[4],hrsV_LO_total[5],hrsV_LO_total[6]); //H-polar int hrsH_LO1_M = a_m_parameter[1]; int hrsH_LO1_A = a_m_parameter[0]; int hrsH_LO2_M = a_m_parameter[3]; int hrsH_LO2_A = a_m_parameter[2]; int hrsH_LO3_M = a_m_parameter[5]; int hrsH_LO3_A = a_m_parameter[4]; int hrsH_LO4_M = a_m_parameter[7]; int hrsH_LO4_A = a_m_parameter[6]; int hrsH_LO5_M = a_m_parameter[9]; int hrsH_LO5_A = a_m_parameter[8]; int hrsH_LO6_M = a_m_parameter[11]; int hrsH_LO6_A = a_m_parameter[10]; int hrsH_LO7_M = a_m_parameter[12]; Hifi_HIFI_Config_HRS_H_att_lo($BBID,hrs_polarization_h,hrsH_ATT_U1,hrsH_ATT_L1,hrsH_ATT_U2,hrsH_ATT_L2,hrsH_ATT_U3,hrsH_ATT_L3,hrsH_ATT_U4,hrsH_ATT_L4,hrsH_LO1_M,hrsH_LO1_A,hrsH_LO2_M,hrsH_LO2_A,hrsH_LO3_M,hrsH_LO3_A,hrsH_LO4_M,hrsH_LO4_A,hrsH_LO5_M,hrsH_LO5_A,hrsH_LO6_M,hrsH_LO6_A,hrsH_LO7_M); // //delay(hrs_config_delay); //V-polar int hrsV_LO1_M = a_m_parameter[14]; int hrsV_LO1_A = a_m_parameter[13]; int hrsV_LO2_M = a_m_parameter[16]; int hrsV_LO2_A = a_m_parameter[15]; int hrsV_LO3_M = a_m_parameter[18]; int hrsV_LO3_A = a_m_parameter[17]; int hrsV_LO4_M = a_m_parameter[20]; int hrsV_LO4_A = a_m_parameter[19]; int hrsV_LO5_M = a_m_parameter[22]; int hrsV_LO5_A = a_m_parameter[21]; int hrsV_LO6_M = a_m_parameter[24]; int hrsV_LO6_A = a_m_parameter[23]; int hrsV_LO7_M = a_m_parameter[25]; Hifi_HIFI_Config_HRS_V_att_lo($BBID,hrs_polarization_v,hrsV_ATT_U1,hrsV_ATT_L1,hrsV_ATT_U2,hrsV_ATT_L2,hrsV_ATT_U3,hrsV_ATT_L3,hrsV_ATT_U4,hrsV_ATT_L4,hrsV_LO1_M,hrsV_LO1_A,hrsV_LO2_M,hrsV_LO2_A,hrsV_LO3_M,hrsV_LO3_A,hrsV_LO4_M,hrsV_LO4_A,hrsV_LO5_M,hrsV_LO5_A,hrsV_LO6_M,hrsV_LO6_A,hrsV_LO7_M); // delay(hrs_config_delay); } //Retune HIFI for frequency switch - keep magnet and backends procedure HIFITuneFreqFsw { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq_1 = 978200.0; //LO frequency for FSW1 phase double lo_freq_2 = 978300.0; //LO frequency for FSW2 phase bool newsetting = true; // whether LSU/LOU parameters are new string target_name = "sscan_normal"; // Name of target level }{ //LO power tuning: could use either H or V polar {double,string}[] result = ConfigurationReader("name_confpolar4lotune",[band],band,lo_freq_1); double x = result[0]{0}; string tuningbackend = "H"; if(iround(x) == 2) { tuningbackend = "V"; } else { tuningbackend = "H"; } // All tuning for first frequency, and store in FSW1 register double lo_freq_setting = 0.5 * (lo_freq_1 / 1000.0 + lo_freq_2 / 1000.0); LO_tuning_block_aot(band,lo_freq_1 / 1000.0,lo_freq_setting,tuningbackend,newsetting,newsetting,true); // //Spectrometer attenuator tuning - on the sky or cold load if(target_name != "") { WBS_attenuators_block(band,lo_freq_1 / 1000.0,target_name,true); } // // Second frequency setup, and stored in FSW2 register LO_tuning_block_aot(band,lo_freq_2 / 1000.0,lo_freq_setting,tuningbackend,false,newsetting,true); // } // Chop between internal cold and external hot loads, block // We take 1 spectrum per phase. block Stability_intcold_exthot_fm HIFI 3434 { string band = "1a"; // HIFI band int n = 100; //The number of integration pairs int integ_time = 4; //Total (co-added) integration time of ONE SINGLE phase in sec. string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string chopmode = "slowchop" in ["slowchop","fastchop"]; //Whether to use slowchop or fastchop double chop_phase = 1.0 in [0.2,2.0]; // Chop phase length }{ Start_block(); //Get chopper settings {double,string}[] result = ConfigurationReader("name_confilfpu",["chop_M3","chop_cold"],band,0.0); double chop_middle = result[0]{0}; double chop_cold = result[1]{0}; // //We implement a special slow-chop spectroscopy between //internal cold and external hot if(chopmode == "slowchop") { Slow_chop_spectro_for_Stability_proc_fm(band,n,integ_time * 2,backend,hrs_mode,chop_middle,chop_cold); } else { Fast_chop_spectro_for_Stability_proc_fm(band,n,integ_time * 2,backend,hrs_mode,chop_middle,chop_cold,chop_phase); } } //Procedure checking whether commanded voltage is in the acceptable range double procedure Check_Chopper_Range_COP { double chopper_angle = 0.0; //prime or redundant chopper voltage string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ //Check prime or redundant status {double,string}[] result_d = ConfigurationReader("name_chopper",["prime_endstop_min","prime_endstop_max","red_endstop_min","red_endstop_max"],"0",0.0); double chop = chopper_angle; double prime_endstop_min = result_d[0]{0}; double prime_endstop_max = result_d[1]{0}; double red_endstop_min = result_d[2]{0}; double red_endstop_max = result_d[3]{0}; // //Checks the chopper angle is within the ranges if(prime_or_redundant == "Prime") { if(chop > prime_endstop_max || chop < prime_endstop_min) { error("The chopper voltage (requested is " + chop + " V) in " + result_d[0]{1} + " mode has to be between " + prime_endstop_min + " and " + prime_endstop_max + " V."); } } if(prime_or_redundant == "Red") { if(chop > red_endstop_max || chop < red_endstop_min) { error("The chopper voltage (requested is " + chop + " V) in " + result_d[0]{1} + " mode has to be between " + red_endstop_min + " and " + red_endstop_max + " V."); } } return chop; } // Integrate only on internal cold, block // We take 1 spectrum per phase. block Stability_intcold_fm HIFI 3426 { string band = "1a"; // HIFI band int n = 100; //The number of integrations int integ_time = 4; //Total integration time in sec. to be set at end of test string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code string obsmode = "fastchop" in ["fastchop","tp"]; //tp or fastchop double chop_phase = 1.0 in [0.2,2.0]; // Chop phase length }{ Start_block(); Chopper_Rotation_proc_fm(band,"chop_M3_ang","chop_cold_ang"); //Look at CBB //Get chopper settings {double,string}[] result = ConfigurationReader("name_confilfpu",["chop_cold"],band,0.0); double chop_cold = result[0]{0}; //Do a long integration // - for B1-5, use 2 sec. with wbs or hrs only, thus tp is OK // - for B6: use 1 sec. with reduced wbs (wbsFast), thus tp is OK //We implement a special spectroscopy configuration with fixed values if(obsmode == "tp") { Total_power_spectro_for_Stability_proc_fm(band,n,integ_time,backend,hrs_mode); } if(obsmode == "fastchop") { Fast_chop_spectro_for_Stability_proc_fm(band,n,integ_time * 2,backend,hrs_mode,chop_cold,chop_cold,chop_phase); } } // Stability test, procedure // Measurement of internal cold only procedure Proc_stability_intcold { string band = "1a"; // HIFI band int n = 100; //Number of load pairs to be measured string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int integ_time = 4; //Total integration time in sec. to be set at end of test string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string obsmode = "fastchop" in ["fastchop","tp"]; //tp or fastchop double chop_phase = 1.0 in [0.2,2.0]; // Chop phase length }{ // Chopper_Rotation_block_fm(band,"chop_M3_ang","chop_cold_ang"); //Look at CBB // //WBS calibration if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band); WBS_tune_proc_fm(band); } if(backend == "hrs" || backend == "both" || backend == "hrsFast") { //Configure and tune backends HRS_config_block_fm(band,hrs_mode); HRS_tune_block_fm(band); } // //Configure spectrometers integration: done later //Configure_Spectrometer_proc_fm(band,4,hrs_mode,backend); //2 sec. integration // Stability_intcold_fm(band,n,integ_time,backend,hrs_mode,obsmode,chop_phase); //Configure spectrometers integration back to default Configure_Spectrometer_proc_fm(band,4,hrs_mode,backend); } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the DBS raster mode procedure DBSRaster_commanding { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // chunk size int n_seq = 1; // Number of continuous chop cycles int n_cycles = 1; // Number of half OFF-ON-ON-OFF cycles int n_pointsperscan = 1; // Number of points measured before moving to the second pointing phase int n_loadinterval = 10; // number of nods before a load measurement int n_load = 0; // additional load measurements in one pointing phase bool final_load = false; // Need for final load measurement int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,10,0,10,20,21,0,0,0]; // Timing of the observation from telescope int loadlength = 21; // Load duration bool iscross = false; // Whether we use a cross instead of a raster }{ // Auxiliary variables // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Get all values from the telescope section int tinitslew = telescopetimes[1]; // Initial slew time //////////////////////////////////////////////////////////////////////// // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // // Clustering is currently not implemented in MPS - switched off here int clustered = 0; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] rates = dataparms{1}; int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); // Count phases by hand to allow simultaneous usage by Raster and Cross int iphase = 0; // There is no nod counter in the return values - count this by hand int inod = 0; // Do I have to make loads in short nods and subsequent holds? if(iscross) { bool holdforload = n_pointsperscan > 1; } else { holdforload = n_pointsperscan == 1 && n_loadinterval > n_cycles; } bool isOffAtPoint = false; //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; bool runintostate = false; while(state[0] >= 0) { if(runintostate) { state = next_state_no_check(); } else { state = next_state(); } if(state[0] == 1) { // Initialization if(clustered != 1) { HIFIInitObs(); TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal"); } delay(tinitslew - (time() - startobs) - loadlength - hkduration); // First load measurement HIFISetHK("normal",false); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); runintostate = false; iphase = iphase + 1; } ////////////////////////////////////////////////////////////////////// // States for actual observations if(state[0] == 3) { // First nodding position // Check whether we are in a cross mode using computed OFF isOffAtPoint = iscross && inod % 2 == 0; // Configure measurement HIFIConfigureSlowChopIntegration(data_time,n_seq,band,lo_freq,backendreadoutparms); // Loop for load cycles // The use of n_load differs by 1 from the other observing modes here for(int i1 = 1 .. n_load - 1) { if(isOffAtPoint) { HIFISlowChopOffIntegration(data_time,n_seq,band,lo_freq,rates); } else { HIFISlowChopOnIntegration(data_time,n_seq,band,lo_freq,rates); } // Perform load calibration delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); HIFIConfigureSlowChopIntegration(data_time,n_seq,band,lo_freq,backendreadoutparms); } // Last cycle if(isOffAtPoint) { HIFISlowChopOffIntegration(data_time,n_seq,band,lo_freq,rates); } else { HIFISlowChopOnIntegration(data_time,n_seq,band,lo_freq,rates); } // Load measurement if required - time included in pointing if(n_load > 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } // Final point before nod // Special treatment for all cases where load has to be replaced by hold: // n_pointsperscan=1, n_loadinterval > n_cycles if(iphase % n_pointsperscan == 0 && iphase / n_pointsperscan % 2 == 1) { inod = inod + 1; if(holdforload && inod % n_loadinterval == 0 && n_load == 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); runintostate = true; } } else { // keep shift if we come from a holdforload nod, otherwise reset if(!holdforload) { runintostate = false; } } // Update phase counter iphase = iphase + 1; } // Second pointing phase if(state[0] == 7) { // second nod position HIFIConfigureSlowChopIntegration(data_time,n_seq,band,lo_freq,backendreadoutparms); for(int i2 = 1 .. n_load - 1) { HIFISlowChopOffIntegration(data_time,n_seq,band,lo_freq,rates); // Perform load calibration delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); HIFIConfigureSlowChopIntegration(data_time,n_seq,band,lo_freq,backendreadoutparms); } // Last cycle HIFISlowChopOffIntegration(data_time,n_seq,band,lo_freq,rates); // Load measurement if required - time included in pointing if(n_load > 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } // Final point before nod // Special treatment for all cases where load has to be replaced by hold: if(iphase % n_pointsperscan == 0 && iphase / n_pointsperscan % 2 == 1) { inod = inod + 1; if(holdforload && inod % n_loadinterval == 0 && n_load == 0) { delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); runintostate = true; } } else { // keep shift if we come from a holdforload nod, otherwise reset if(!holdforload) { runintostate = false; } } // Update phase counter iphase = iphase + 1; } // Load nod if(state[0] == 9) { // Load nod delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); runintostate = false; } // Hold if(state[0] == 6) { // finished shift of instrument operations relative to pointing command runintostate = false; } // Final load if(state[0] == 5) { delay(readoutdead); if(final_load) { // Perform final load measurement LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } runintostate = false; HIFICloseObs(); } } } ///////////////////////////////////////////////////////////////// // Procedure to compute total dead times for the mode // {double,double,double} procedure FastDBS_deadtimes { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // data dump interval int n_int = 20; // number of integrations in one data dump interval int n_data = 3; // number of subsequent readouts int n_load = 0; // number of integrations in one pointing phase -1 double tdead = 10.0; // Dead time from telescope }{ ////////////////////////////////////////////////////////////////////// // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Compute parameters for the instrument timing {double,double} tinst = GetInstDeadFastChop(data_time,n_int,n_data,band,lo_freq,backendreadoutparms); // dead time double tdeadint = double(data_time * n_data) - tinst{0}; // subtract dead times in switches // only half of them are subtracted due to ABAB scheme tdeadint = tdeadint - double(n_int * n_data) * tinst{1}; // Total dead time per cycle double tdead_tot = tdead + double(2 * (n_load + 1)) * tdeadint; // Integration time double tphaseint = tinst{0} / double(2 * n_int * n_data); return {tdead_tot,tphaseint,tinst{1}}; } // Initialisation, block with IF1 set OFF block Init_noIF1_fm HIFI 3209 { string band = "1a"; // HIFI band string mixer_polarization = "B" in ["H","V","B"]; //Polarization: H, V, or both (B) }{ Start_block(); //Get parameters {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,0.0); int band_nb = iround(result_d[0]{0}); // double volt_H_FIF_1 = 0.075; double curr_H_FIF_1 = 0.5; double volt_H_FIF_2 = 0.075; double curr_H_FIF_2 = 0.5; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // Check whether H-polar is requested if(mixer_polarization == "V") { volt_H_SIF_1 = 0.075; curr_H_SIF_1 = 0.5; volt_H_SIF_2 = 0.075; curr_H_SIF_2 = 0.5; volt_H_SIF_3 = 0.075; curr_H_SIF_3 = 0.5; } // result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,0.0); // double volt_V_FIF_1 = 0.075; double curr_V_FIF_1 = 0.5; double volt_V_FIF_2 = 0.075; double curr_V_FIF_2 = 0.5; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // Check whether H-polar is requested if(mixer_polarization == "H") { volt_V_SIF_1 = 0.075; curr_V_SIF_1 = 0.5; volt_V_SIF_2 = 0.075; curr_V_SIF_2 = 0.5; volt_V_SIF_3 = 0.075; curr_V_SIF_3 = 0.5; } // string chop_sine_s = "ON"; string chop_loop = "CLOSE"; //Chopper is not used anyway result_d = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,0.0); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // double calibcurrent = result_d[7]{0}; // //Junctions do not need to be biased, nor should diplexers be moved double bias_H = 0.0; double magnetcurrent_H = 0.0; double bias_V = 0.0; double magnetcurrent_V = 0.0; double diplex_H = 0.0; double diplex_V = 0.0; int diplex_h_ctrl_mode = 0; int diplex_v_ctrl_mode = 0; // double chopper = 0.0; // // chopper = Check_Chopper_Prime_Redundant(chopper); HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result_d = ConfigurationReader("name_delays",["config_fpu_delay"],band,0.0); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // // } //HIFI-COP-1.2-LO_FT procedure LO_FT_COP_proc_sft { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ mois_comment("Start of HIFI LO Functional Test for band " + band); mois_comment("Please check that instrument was switched on with the " + prime_or_redundant + " unit"); mois_tmcheck("Check content of AND LCU_temperatures_with HIFI expert."); //General parameters in use string multiplier = "ALL"; int operation_delay = 0; // double[] cresult_d = CalibrationReader("name_keyfreq",["keyfreq"],band,0.0); double lo_freq = cresult_d[0]; //applies to cold LO // mois_step("Init MSA"); string chop_startup_prime_red = "chop_startup_cold_prime"; if(prime_or_redundant == "Red") { chop_startup_prime_red = "chop_startup_cold_red"; } {double,string}[] result = ConfigurationReader("name_chopper",[chop_startup_prime_red],"0",0.0); Init_MSA_ops(band,"CLOSE",lo_freq,result[0]{0},"ON",prime_or_redundant); // //First switch off the band. LCU_switch_off_block_fm(); mois_tmcheck("Check that parameter HL_Channel_S is OFF"); // mois_step("Measure LCU IV curve"); Measure_LCU_IV_proc_fm(band,multiplier,operation_delay); // //Switch on with safe Vd2 mois_step("Switch on LO band"); LCU_switchon_proc_sft(band); mois_tmcheck("Check that parameter HL_MODE_S is normal"); mois_tmcheck("Check that parameter HL_Channel_S is " + band); // mois_step("LO SFT"); //This will switch on the chain again LO_SFT_proc_sft(band,prime_or_redundant); // mois_tmcheck("Check whether parameter HL_error_word_S has been FAULT at any time of the procedure. Communicate occurences to HIFI expert."); mois_tmcheck("Check content of AND LCU_status2 and LCU_" + band + " with HIFI expert."); } //////////////////////////////////// // Routines to provide initial guesses for sequence parameters //////////////////////////////////// // Frequency switch observing mode // {string,double,double}[] procedure HifiPointProcFSwitchSequencerInit { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source double raoff = 0.0; // RA coordinate of the OFF position double decoff = 0.0; // DEC coordinate of the OFF position string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rates int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles on ON int n_switch_off = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles on OFF int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF calibration cycles int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode // limit on data rate {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // limits from noise section {double,double,double,double} phaselengths = FSwitchPhaseLengths(band,lo_freq,effResolution,oneGHzReference); // Compute derived quantities int data_time_guess = imin(imax(iceil(phaselengths{1}),datalimit),20); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } int n_switch_on_guess = imax(iceil(phaselengths{0} / (2.0 * double(data_time_guess))),1); int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } // OFF phase int data_time_off_guess = imin(imax(iceil(phaselengths{2}),datalimit),20); int data_time_off_range = datalimit - data_time_off_guess; if(data_time_off_range == 0) { data_time_off_range = 1; } int n_switch_off_guess = imax(iceil(double(data_time_guess * n_switch_on_guess) / (double(data_time_off_guess) * sqrt(phaselengths{3} / effResolution{1}))),1); int n_switch_off_range = 1 - n_switch_off_guess; if(n_switch_off_range == 0) { n_switch_off_range = 1; } // Add pointing requirements condition: >=10s {int,int} new_data_time = MatchMinPointing(data_time_guess,data_time_range,2 * n_switch_on_guess); data_time_guess = new_data_time{0}; data_time_range = new_data_time{1}; new_data_time = MatchMinPointing(data_time_off_guess,data_time_off_range,2 * n_switch_off_guess); data_time_off_guess = new_data_time{0}; data_time_off_range = new_data_time{1}; // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"data_time_off",double(data_time_off_guess),double(data_time_off_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)},{"n_switch_off",double(n_switch_off_guess),double(n_switch_off_range)}]; return retvalues; } //FSW Integration on Internal hot, block block Hot_spectra_FSW_fm HIFI 3233 { string band = "1a"; int integ_time = 8; //Total integration time in sec.: at least 2sec ! string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); //Rotate chopper: assume we come from M3 Chopper_Rotation_proc_fm(band,"chop_M3_ang","chop_hot_ang"); // //Compute data-rate double[] rates = ILT_datarate_proc_fm(band,backend,"fsw",integ_time); //Take spectrum // set data rates non_ess_hk_data_rate(rates[2] / 1024.0); data_rate(rates[0] / 1024.0); // Hifi_HIFI_Spectr_freq_switch($BBID); Apply_Slow_Chop_delay(integ_time,band,backend); // reset data rates non_ess_hk_data_rate(rates[1] / 1024.0); data_rate(0.0); } // Get main beam size for message double procedure GetMainBeamSize { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency }{ double[] fwhm = CalibrationReader("beam",["resolution"],band,lo_freq); return fwhm[0]; } //Chopper health check test#3 during CL, mode mode HifiManCmd_Chopper_closed_loop_parameter_check_ops { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! string prime_or_redundant = "Prime" in ["Prime","Red"]; //Prime or Red }{ mois_tmcheck("This should be the very first test performed after transition between open loop and closed loop contexts"); mois_tmcheck("The instrument should be in Standby I mode in CL context for this test"); //It is done after chopper has been switched on in closed loop // mois_comment("Performing part three of HIFI internal chopper health check"); StartMode_block_ops(); // //Get chopper ON in closed-loop with voltage at rest position string chop_startup_prime_red = "chop_startup_cold_prime"; if(prime_or_redundant == "Red") { chop_startup_prime_red = "chop_startup_cold_red"; } {double,string}[] result = ConfigurationReader("name_chopper",[chop_startup_prime_red],"0",0.0); //Remove loop closure to be in line with procedure and re-generate MOIS //Loop closure is done via context transition procedure NCXT/RCXT //Init_MSA_ops("0","CLOSE",0.0,result[0]{0},"ON",prime_or_redundant); mois_tmcheck("Check that parameter HF_DPR_CHLOOP_S is set to CLOSE"); mois_tmcheck("Check that parameter HF_DPR_CH_ROT is set to " + result[0]{0} + " V"); Chopper_closed_loop_parameter_check_block_ops(prime_or_redundant); StopMode_block_ops(); mois_spacon("Complete success of this integrity check needs off-line analysis. Please write down the OBS_ID corresponding to this mode and communicate it to the HIFI ICC"); } {int,double,double,double,double,double} obs HifiMappingModeFSwitchOTF { string modeName = "fs-raster"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // chunk size given by the data rates and optimum speed int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 1 in [1,1800]; // Supersamplingfactor int n_switch_off = 3 in [1,3600]; // Number of data dumps for the OFF integration time int n_linesperscan = 1 in [1,32]; // Number of lines between two OFFs int n_cycles = 1 in [1,1200]; // Number of map coverages int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode OpenMessages("HIFI Mapping - OTF Map Frequency Switch Ref",{data_time,data_time_off,0,n_switch_on,n_switch_off,n_linesperscan,0,0,n_cycles,load_interval}); // Auxiliary routine for API parameter correction {double,double,int} mapused = ValidMapSize(band,lo_freq,lineDistance,nlines,stepsize,npoints,2 * data_time * n_switch_on); double line_used = mapused{0}; double scanvelocity = mapused{1}; int npoints_used = mapused{2}; // Call first part of the timing computer {int,int,int,int,int,int,int,int} pre_timing = OTFFSwitch_pre_timing(nlines,npoints_used,band,lo_freq,freq_throw,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,n_switch_on,n_switch_off,n_linesperscan,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {double,double} refPosition = {raoff,decoff}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,double,double,int,int,double,double,int,int,int,int,int} tpar = OTFmap_telescope(naifid,onPosition,lineDistance,nlines,line_used,refPosition,scanvelocity,band,lo_freq,n_linesperscan,n_cycles,pre_timing); // Dummy call to spacecraft command int[] telescopetimes = line_scan_with_off_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23}); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int},double,double} post_timing = OTFmap_post_timing(pre_timing,telescopetimes,data_time,n_linesperscan,n_cycles,load_interval); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = OTFmap_telescope(naifid,onPosition,lineDistance,nlines,line_used,refPosition,scanvelocity,band,lo_freq,n_linesperscan,n_cycles,post_timing{1}); // Call telescope command telescopetimes = line_scan_with_off_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23}); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int n_pp = post_timing{1}{0}; int n_scans = post_timing{1}{1}; int off_inttime = post_timing{1}{2}; int loadlength = post_timing{1}{4}; int n_loadinterval = post_timing{1}{5}; double tscan = post_timing{2}; double tdead = post_timing{3}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { OTFFSwitch_commanding(band,lo_freq,freq_throw,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,npoints_used * n_switch_on,n_switch_off,nlines * n_cycles,n_linesperscan,n_loadinterval,startobs,telescopetimes,loadlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double,double,double} tact = OTFDoubleChop_deadtimes("fs",band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,n_switch_on,n_switch_off,n_linesperscan,n_pp,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = OTFFSwitch_noisecomputer(band,lo_freq,effResolution,oneGHzReference,nlines,data_time,n_switch_on,n_linesperscan,off_inttime,n_cycles,tscan,tact); // Evaluate performance OTFDoubleChop_performance(band,lo_freq,effResolution,noisevalues,timeTaken,nlines,npoints_used,n_switch_on,n_switch_off,n_scans,n_cycles,true,tscan,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } //////////////////////////////////// // Auxiliary functions // IsContained functions bool procedure StringIsContained { string x = " "; // search string string[] lot = [""]; // array to be searched }{ int nlen = length(lot); bool found = false; for(int i = 0 .. nlen - 1) { if(x == lot[i]) { found = true; } } return found; } // Switch on LO band: assumes HIFI is prime and LO is in nominal mode // This is wrapped into an engineeering obs in MTL // During the stabilization phase a normal load-chop-noref observation // is performed obs HifiEngSwitchonLO { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band bool robust = true; // whether the subsequent AOR is chopped+spectroscopic }{ // First part - determine timing and telescope parameters // Fixed parameters int data_time = 4; // Data readout period {double,double} eff_resolution = {1.1,1.1}; // Native WBS resolution as goal resolution // Get reference frequency string keyfreqname = "keyfreq"; //this is for cold LO operations // "keyfreq" for cold LO operations // "keyfreq_dummy" for dummy LO operations // "midfreq" old approach double[] result_d = CalibrationReader("name_keyfreq",[keyfreqname],band,0.0); double lo_freq = result_d[0] * 1000.0; // Backend settings // standard routine from spectral scans {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,2,true,true,data_time); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; // Call specific pre_timing computer {int,int,int,int,int,int} pre_timing = SwitchOnLoadChop_pre_timing(band,lo_freq,eff_resolution,hr1,hr2,wb1,wb2,data_time,robust); // get parameters for fine pointing int totaltime = pre_timing{0}; // total duration for check int on_pointing = pre_timing{1}; // Pointing time int initlength = pre_timing{2}; // Initial setup time int dangling = pre_timing{3}; // Final load measurement // telescope command int[] ts = no_pointing(true,initlength,dangling,on_pointing); }{ // Second part - instrument commanding // get parameters for instrument int n_cycles1 = pre_timing{4}; int n_cycles = pre_timing{5}; // Backend settings // Create a composite readout structure {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hr1{0},hr1{1},hr1{3}},{hr2{0},hr2{1},hr2{3}},wb1,wb2}; // additional fixed parameters like in standard observing modes // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] rates = dataparms{1}; int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); ////////////////// // Instrument commanding sync(); int startobs = time(); // use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); // Actual switch-on // The switch will always be done at the same frequency LCU_switchon_proc_aot(band,lo_freq / 1000.0); // Initial setup and LO tuning Init_Mixing_proc_aot(band,lo_freq / 1000.0); //Deflux will do be done for bands 1 to 4 Deflux_SingleBand_proc_aot(band,lo_freq / 1000.0); // Standard backend tuning string target_name = "normal"; // Name of target level if(wb1{0} || wb2{0}) { WBS_attenuators_block(band,lo_freq / 1000.0,target_name,false); } if(hr1{0} || hr2{0}) { HRS_tune_block_aot(band); } // First load measurement HIFISetHK("normal",false); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } if(state[0] == 3) { // ON integration - long hot-cold measurement if(n_cycles1 > 0) { HIFI_Calibrate_hot_cold(band,lo_freq,data_time,2 * n_cycles1,backendreadoutparms,false); HIFITuneFreq(band,lo_freq,false,""); } HIFI_Calibrate_hot_cold(band,lo_freq,data_time,2 * n_cycles,backendreadoutparms,false); } if(state[0] == 5) { delay(readoutdead); // Perform final load measurement LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); HIFICloseObs(); } } // Finalize observations // consistency check int timeTaken = time() - startobs; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } // Noise estimates could be easily added, but are not done here // in the current implementation } //Set LCU1a back to standby status, procedure procedure LCU1a_standby_proc_fm { string band = "1a"; // HIFI band double lo_freq = 500.0 in [488.0,552.0]; //LO frequency }{ error("This module is obsolete: use LCU_standby_proc_fm instead"); } {string,double,double}[] procedure HifiSScanModeFastDBSSequencerInit { string modeName = "freq"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 10 in [4,80]; // data dump interval int n_int_on = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_switch_on = 1 in [1,1800]; // number of data transfer cycles per pointing int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int n_cycles = 1 in [1,600]; // Number of half OFF-ON-ON-OFF cycles at one frequency int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,redundancy,wbs1Used,wbs2Used,data_time / 2); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hr1{0},hr1{1},hr1{3}},{hr2{0},hr2{1},hr2{3}},wb1,wb2}; // Get frequency grid characteristic parameters {double,int,double} gfref = GetFReference(band,lo_freq,lo_freq_up); double reffreq = gfref{0}; int stdredun = gfref{1}; double stdstep = gfref{2}; int increment = stdredun / redundancy; // allowed group size double nocaliblen = GetFNoCalibLength(band,reffreq); int n_freq_point_guess = ifloor(nocaliblen / (stdstep * double(increment)) + 1.0); int n_freq_point_range = 1 - n_freq_point_guess; if(n_freq_point_range == 0) { n_freq_point_range = 1; } // Now general part of DBS modes // Get the drift parameters to compute the drift noise // spectral scans always use the full bandwidth for reference bool narrowReference = false; {double,double} phaselengths = DBSPhaseLengths(band,reffreq,effResolution,continuumDetection,narrowReference); // Compute derived quantities // Top down approach here int main_phase = iceil(phaselengths{0}); // Arbitrary selection of data_time int data_time_guess = 20; // remaining part for n_switch int n_switch_on_guess = main_phase / (n_freq_point_guess * data_time_guess) + 1; data_time_guess = main_phase / (n_freq_point_guess * n_switch_on_guess); // Check with data rate {int,double[]} dataparms = DataTaking(backendreadoutparms,8); int datalimit = 2 * dataparms{0}; if(data_time_guess < datalimit) { data_time_guess = datalimit; n_switch_on_guess = 1; } int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } // Chop phase length double phase_min = min(max(phaselengths{1},0.15),1.5); int n_int_on_guess = ifloor(double(data_time_guess) / (2.0 * phase_min)); int n_int_on_range = -n_int_on_guess / 2; if(n_int_on_range == 0) { n_int_on_range = 1; } // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"n_int_on",double(n_int_on_guess),double(n_int_on_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)},{"n_freq_point",double(n_freq_point_guess),double(n_freq_point_range)}]; return retvalues; } // Change LO frequency // possibly without diplexer retuning // procedure HIFIChangeLO { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency for LO double reffreq = 978200.0; // LO frequency for diplexer bool retunediplexer = false; // whether to change the diplexer with freq bool retunelo = false; // whether to retune LO Vd2 with freq }{ if(retunediplexer) { ConfigureFPU(band,lo_freq,false); } else { ConfigureFPU(band,reffreq,false); } if(retunelo) { HIFITuneFreq(band,lo_freq,true,""); } else { HIFITuneFreqNoretune(band,lo_freq); } } //Procedure checking whether the requested integration //time is compliant with the allowed packet/datarate //in fast chop spectroscopy context bool procedure Check_Fast_Chop_datarate { int n_wbs_start = 1; //Nb of frames int r_hrs = 1; //Nb of HRS readout per WBS readout int n_wbs_integr = 4; //Number of wbs readout packetized per WBS frame int n_hrs_integr = 4; //Number of hrs readout packetized per HRS frame int del_hrs = 5; //Delay before starting HRS integration int del_wbs = 5; //Delay before starting WBS integration int t_acc_wbs = 1005; //Duration of WBS frame int t_acc_hrs = 950; //Duration of HRS frame int wbsh_offset1 = 0; int wbsh_width1 = 2048; int wbsh_offset2 = 2048; int wbsh_width2 = 2048; int wbsh_offset3 = 4096; int wbsh_width3 = 2048; int wbsh_offset4 = 6144; int wbsh_width4 = 2048; int wbsv_offset1 = 0; int wbsv_width1 = 2048; int wbsv_offset2 = 2048; int wbsv_width2 = 2048; int wbsv_offset3 = 4096; int wbsv_width3 = 2048; int wbsv_offset4 = 6144; int wbsv_width4 = 2048; int hrs_rshift = 0; //HRS bit shift int wbs_rshift = 0; //WBS bit shift int hrsh_sel = 255; //HRS-H band selection int hrsv_sel = 255; //HRS-V band selection string wbs_packing = "24_bits_format"; string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3 int n_wbs_1 = 8; //n_wbs_1: number of WBS cycles (should be even) string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ error("Procedure Check_Fast_Chop_datarate is not used anymore."); return false; } //Peak test data aquisition, block block Peakup_test_acquire_data_block_fm HIFI 3821 { string band = "1" in ["1","2","3","4","5","6","7"]; // HIFI band string backend = "hrs" in ["hrs","wbs"]; //Backend in use: hrs or wbs int total_time = 2; //Total integration time in sec. string peakup_matrix = "centred" in ["centred","offseted","flat"]; //Which brightness distribution to simulate with shutter string mixer_polarization = "H" in ["H","V"]; //mixer polarization to be used }{ //Start_block(); //Get some data for delay computation string band_nb = band + "a"; {double,string}[] result = ConfigurationReader("name_delays",["wbs_transfer_delay"],band_nb,0.0); int wbs_packet_transfer_time = iround(result[0]{0}); // //Loop on positions: succesively move shutter and acquire data for(int position = 1 .. 9) { //Move shutter: this is equivalent to the telescope motion ////Peakup_shutter_rotation_proc_fm(band,position,peakup_matrix); //THE ABOVE IS NOT AVAILABLE IN IST - WE USE BACKEND ATT. INSTEAD Peakup_backend_attenuation_proc_fm(band,position,peakup_matrix,backend,total_time); //Acquire data if(backend == "hrs") { Hifi_HIFI_acquire_peakup_hrs($BBID,mixer_polarization,position); delay(total_time + wbs_packet_transfer_time / 1000); } else { Hifi_HIFI_acquire_peakup_wbs($BBID,mixer_polarization,position); delay(total_time + wbs_packet_transfer_time / 1000); } //Add a short integration to get distribution of IF power independently Hifi_HIFI_Spectr_total_power($BBID); delay(total_time + wbs_packet_transfer_time / 1000 + 1); } // //Trigger AOCS correction computation (?) Hifi_HIFI_correction_AOCS($BBID); delay(1); } // Initialisation of FPU, block with both MSA in use // It is for warm context ! block Init_MSA_fm_warm HIFI 3216 { string band = "1a"; // HIFI band string chop_loop = "CLOSE"; double lo_freq = 522.0; //LO frequency }{ Start_block(); //Get parameters {double,string}[] result_d = ConfigurationReaderWarm("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,lo_freq); int band_nb = iround(result_d[0]{0}); double diplex_H = 0.0; double diplex_V = 0.0; int diplex_h_ctrl_mode = 0; int diplex_v_ctrl_mode = 0; // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // result_d = ConfigurationReaderWarm("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,lo_freq); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // string chop_sine_s = "ON"; // string chop_loop = "CLOSE" ; result_d = ConfigurationReaderWarm("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,lo_freq); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // double calibcurrent = result_d[7]{0}; // //Get biases result_d = ConfigurationReaderWarm("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); double bias_H = result_d[0]{0}; double bias_V = result_d[1]{0}; // //Get magnets: not applicable to bands 6 and 7 double magnetcurrent_H = 0.0; double magnetcurrent_V = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReaderWarm("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); magnetcurrent_H = result_d[0]{0}; magnetcurrent_V = result_d[1]{0}; } //Diplexer is interpolated from a table for Bands 3, 4, 6L and 6H if(band_nb <= 2 || band_nb == 5) { diplex_H = 0.0; //For bands 1, 2 and 5 diplex_V = 0.0; diplex_h_ctrl_mode = 0; diplex_v_ctrl_mode = 0; } else { //Get diplexer currents result_d = ConfigurationReaderWarm("name_confilfpu",["diplex_h_ctrl_mode","diplex_v_ctrl_mode","diplexer_current_normal_h","diplexer_current_normal_v"],band,lo_freq); diplex_h_ctrl_mode = iround(result_d[0]{0}); diplex_v_ctrl_mode = iround(result_d[1]{0}); //double[] result_dip = Get_Diplexer_setting(band,lo_freq); diplex_H = result_d[2]{0}; //result_dip[0]; diplex_V = result_d[3]{0}; //result_dip[1]; } // result_d = ConfigurationReader("name_chopper",["chop_startup_warm"],band,0.0); double chopper = result_d[0]{0}; // //Switch on upconverter, assuming chopper and mixers are also ON Hifi_HIFI_Configure_FCU_Power($BBID,"ON","ON","ON","ON","ON"); // //For this configuration we won't convert prime chopper voltage into redundant voltage //Just checking we are in range. //chopper = Check_Chopper_Prime_Redundant(chopper); chopper = Check_Chopper_Range(chopper); // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result_d = ConfigurationReaderWarm("name_delays",["config_fpu_delay"],band,lo_freq); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // Hifi_HIFI_non_periodic_hk_FCU(); } //////////////////////////////////// // Position switch observing mode // // Combination of four modules implementing the new structure // // Implemented as procedure returning time and noise levels for HSPOT {int,double,double,double,double,double} obs HifiPointProcPositionSwitch { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source double raoff = 0.0; // RA coordinate of the OFF position double decoff = 0.0; // DEC coordinate of the OFF position bool refSelected = true; // Dummy parameter required by HSPOT string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[36,2012],[36,2012],[36,2012],[36,2012]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,5]; // data dump interval limited by the data rates int n_int_on = 3 in [2,1800]; // number of data dumps for integration per phase int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF cycles int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Single Point - Position Switch",{data_time,0,n_int_on,0,0,0,0,0,n_cycles,load_interval}); // Call first part of the timing computer {int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int} pre_timing = PositionSwitch_pre_timing(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {double,double} refPosition = {raoff,decoff}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,int,int,int,int,int,int} tpar = PositionSwitch_telescope(naifid,onPosition,refPosition,band,lo_freq,pre_timing,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = nodding_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},true); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int},double,double} post_timing = PositionSwitch_post_timing(pre_timing,telescopetimes,n_cycles); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = PositionSwitch_telescope(naifid,onPosition,refPosition,band,lo_freq,post_timing{1},n_cycles); // Call telescope command telescopetimes = nodding_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},true); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{4}; int n_loadinterval = post_timing{1}{7}; bool final_load = post_timing{1}{12}; double tscan = post_timing{2}; double tdead = post_timing{3}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { PositionSwitch_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,startobs,telescopetimes,n_loadinterval,loadlength,final_load); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument double tdead_tot = PositionSwitch_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = PositionSwitch_noisecomputer(band,lo_freq,effResolution,oneGHzReference,n_cycles,tscan,tdead_tot); // Evaluate performance PositionSwitch_performance(band,lo_freq,effResolution,noisevalues,timeTaken,n_cycles,tscan,tdead_tot); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } ////////////////////////////////////////////////////////////////////// // Procedure to display performance parameters of the observing mode procedure DBS_performance { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {double,double,double,double,double} noisevalues = {1.0,1.0,1.0,1.0,0.0}; // Noise values from noisecomputer int totaltime = 200; // Total observing time int n_cycles = 1; // Number of nodding cycles int n_chop = 1; // number of chop cycles double tscan = 60.0; // Total average duration of one scan {double,double,double} tact = {10.0,4.9,0.05}; // Field of actual dead and integration times }{ double inttimeperphase = tact{1}; // Actual integration time in ON phase // Get performance of ideal instrument for comparison {int,double,double,double,double,double} idealvalues = IdealInstrument(band,lo_freq,eff_resolution,totaltime); double idealnoise = idealvalues{1} * idealvalues{1}; double obsnoise = noisevalues{0} * noisevalues{0}; double efficiency = idealnoise / obsnoise; // Compute the actual integration time double posinttime = double(n_cycles * 2 * n_chop) * inttimeperphase; int instrumenttime = iceil(double(n_cycles) * tscan); // Check total integration time double timeefficiency = 2.0 * posinttime / double(totaltime); // Noise contribution double relnoise = noisevalues{4} / (1.0 + noisevalues{4}); // General messages PerformanceMessages(band,lo_freq,totaltime,posinttime,posinttime,timeefficiency,efficiency,relnoise,false); } //////////////////////////////////// // Routine to provide initial guesses for sequence parameters // Frequency switch observing mode // {string,double,double}[] procedure HifiPointProcFSwitchNoRefSequencerInit { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz double freq_throw = -40.0; // throw of frequency switch in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rates int n_cycles = 2 in [1,3600]; // number of half nu1-nu2-nu2-nu1 cycles on ON int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode // inherit from load-chop mode {string,double,double}[] retvalues = HifiPointProcLoadChopNoRefSequencerInit(naifid,ra,dec,band,lo_freq,effResolution,oneGHzReference,hrs1,hrs2,wbs1,wbs2,data_time,n_cycles,load_interval,docommands); return retvalues; } // // WBS configuration, block // Both polarizations are treated block WBS_config_block_fm HIFI 3625 { string band = "1a"; // HIFI band }{ //Start_block(); //H-Polarization // {double,string}[] result_d = ConfigurationReader("name_configwbs",["hwh_laser1_s","hwh_laser2_s","hwh_heater","hwh_latchup_s","hwh_att_band4","hwh_att_band3","hwh_att_band2","hwh_att_band1","hwh_att_in"],band,0.0); string hwh_laser1_s = result_d[0]{1}; string hwh_laser2_s = result_d[1]{1}; int hwh_heater = iround(result_d[2]{0}); string hwh_latchup_s = result_d[3]{1}; int hwh_att_band4 = iround(result_d[4]{0}); int hwh_att_band3 = iround(result_d[5]{0}); int hwh_att_band2 = iround(result_d[6]{0}); int hwh_att_band1 = iround(result_d[7]{0}); int hwh_att_in = iround(result_d[8]{0}); // result_d = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result_d[0]{0}); // //Configure WBS-H Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); // //delay(wbs_config_delay); //Wait for configuration to be applied // //V-Polarization // result_d = ConfigurationReader("name_configwbs",["hwv_laser1_s","hwv_laser2_s","hwv_heater","hwv_latchup_s","hwv_att_band4","hwv_att_band3","hwv_att_band2","hwv_att_band1","hwv_att_in"],band,0.0); string hwv_laser1_s = result_d[0]{1}; string hwv_laser2_s = result_d[1]{1}; int hwv_heater = iround(result_d[2]{0}); string hwv_latchup_s = result_d[3]{1}; int hwv_att_band4 = iround(result_d[4]{0}); int hwv_att_band3 = iround(result_d[5]{0}); int hwv_att_band2 = iround(result_d[6]{0}); int hwv_att_band1 = iround(result_d[7]{0}); int hwv_att_in = iround(result_d[8]{0}); // //Configure WBS-V Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); // delay(wbs_config_delay); //Wait for configuration to be applied // } //TM to control heater values of LOU, block block HL_heater_block_aot HIFI 6615 { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band. string context = "nominal" in ["nominal","stby"]; //whether heater applies to stby or nominal context }{ double[] cresult = CalibrationReader("name_loheater",["heater_nominal","heater_stby"],band,0.0); double hifi_HL_heater = cresult[0]; if(context == "stby") { hifi_HL_heater = cresult[1]; } Hifi_HIFI_HL_heater($BBID,hifi_HL_heater); } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // CUS scripts for ICU operations. // // DT - 17-Feb-06 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // The modes //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //See fm_testmodes.cus //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // The blocks //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //HIFI HK control, block block Switch_HK_block_fm HIFI 3905 { string hk_FCU = "ON" in ["ON","OFF"]; //Status of FCU HK string hk_LCU = "ON" in ["ON","OFF"]; //Status of LCU HK string hk_WBSV = "ON" in ["ON","OFF"]; //Status of WBSV HK string hk_WBSH = "ON" in ["ON","OFF"]; //Status of WBSH HK string hk_HRSV = "ON" in ["ON","OFF"]; //Status of HRSV HK string hk_HRSH = "ON" in ["ON","OFF"]; //Status of HRSH HK }{ Start_block_no_hk_request(); //Get applicable HK rate {double,string}[] result_d = ConfigurationReader("name_delays",["hk_rate"],"0",0.0); string hk_rate = result_d[0]{1}; Hifi_HIFI_Housekeeping_on(hk_rate,hk_FCU,hk_LCU,hk_WBSV,hk_WBSH,hk_HRSV,hk_HRSH); delay(1); } //FSW Integration on Internal cold, block block Cold_spectra_FSW_fm HIFI 3234 { string band = "1a"; int integ_time = 8; //Total integration time in sec.: at least 2sec ! string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); //Rotate chopper: assume we come from M3 Chopper_Rotation_proc_fm(band,"chop_M3_ang","chop_cold_ang"); // //Compute data-rate double[] rates = ILT_datarate_proc_fm(band,backend,"fsw",integ_time); //Take spectrum // set data rates non_ess_hk_data_rate(rates[2] / 1024.0); data_rate(rates[0] / 1024.0); // Hifi_HIFI_Spectr_freq_switch($BBID); Apply_Slow_Chop_delay(integ_time,band,backend); // reset data rates non_ess_hk_data_rate(rates[1] / 1024.0); data_rate(0.0); } //HIFI LO configuration only for M1/M2 investigation in 7b, block block LCU_config_w_M1M2D2_block_fm HIFI 3924 { string band = "7b" in ["5a","5b","7a","7b"]; // HIFI band double lo_freq = 1880.0; //LO frequency double m1 = -8.0; //M1 multiplier voltage double m2 = -8.0; //M2 multiplier voltage double drain2_v = 1.5; //Vd2 voltage }{ //Clear potential failure mode Set_LO_Nominal_proc_fm(); // //Start_block(); {double,string}[] result = ConfigurationReader("name_confpolar4lotune",[band],band,lo_freq); string mixer_polarization = result[0]{1}; // //Get target mixer current result = ConfigurationReader("name_confilmix",["target_mx_c_h","target_mx_c_v"],band,lo_freq); double target_current = result[0]{0}; if(mixer_polarization == "V") { target_current = result[1]{0}; } if(mixer_polarization == "B") { target_current = 0.5 * (result[1]{0} + result[0]{0}); } // //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; string name_configlcutune = "name_configlcutune_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; name_configlcutune = "name_configlcutune_b"; } // result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = m1; //result[1]{0}; double m2_v = m2; //result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; //double drain2_v = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // result = ConfigurationReader(name_configlotune,["step_drain2_v","nsteps","step_time"],band,lo_freq); double step_drain2_v = result[0]{0}; int nsteps = iround(result[1]{0}); double step_time = result[2]{0}; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); // if(band == "5a") { Hifi_HIFI_Conf_nom_LCU_ch7a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v,curlim2,macro_checksum); // } if(band == "5b") { Hifi_HIFI_Conf_nom_LCU_ch7a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v,curlim2,macro_checksum); // } if(band == "7a") { Hifi_HIFI_Conf_nom_LCU_ch7a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v,curlim2,macro_checksum); // } if(band == "7b") { Hifi_HIFI_Conf_nom_LCU_ch7b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v,curlim2,macro_checksum); // } delay(config_lo_delay); // //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); // } //Notify PDU status OFF, block block HIFI_notify_PDU_status_off_block_ops HIFI 7654 { string status_FCU = "OFF" in ["ON","OFF"]; //Status of FCU string status_LCU = "OFF" in ["ON","OFF"]; //Status of LCU string status_WBSV = "OFF" in ["ON","OFF"]; //Status of WBSV string status_WBSH = "OFF" in ["ON","OFF"]; //Status of WBSH string status_HRSV = "OFF" in ["ON","OFF"]; //Status of HRSV string status_HRSH = "OFF" in ["ON","OFF"]; //Status of HRSH }{ StartBlock_ops(); //This has no delay Hifi_HIFI_notify_PDU_status(status_FCU,status_LCU,status_WBSV,status_WBSH,status_HRSV,status_HRSH); //Prepare message for operator: we will check whether one particular HK is ON if(status_FCU == "OFF") { string subsyst_off = "HI_FCU_S"; } if(status_WBSH == "OFF") { subsyst_off = "HI_WBSH_S"; } if(status_WBSV == "OFF") { subsyst_off = "HI_WBSV_S"; } if(status_HRSH == "OFF") { subsyst_off = "HI_HRSH_S"; } if(status_HRSV == "OFF") { subsyst_off = "HI_HRSV_S"; } if(status_LCU == "OFF") { subsyst_off = "HI_LCU_S"; } mois_tmcheck("Check that the HK parameter " + subsyst_off + " is OFF."); delay(1); } ///////////////////////////////////////////////////////////////// // Routine for spectral scans // // Get the length of the possible frequency steps without recalibration double procedure GetFNoCalibLength { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency }{ double[] nocaliblen = CalibrationReader("fscangroup",["step_nocalib"],band,lo_freq); return nocaliblen[0]; } {int,double,double,double,double,double} obs HifiMappingModeDBSRaster { string modeName = "raster"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_switch_on = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode OpenMessages("HIFI Mapping - DBS Raster Map slowChop",{data_time,0,0,n_switch_on,0,0,n_pointsperscan,0,n_cycles,load_interval}); // Call first part of the timing computer {int,int,int,int,int,int,int,int,int,int,int,int,int} pre_timing = DBSRaster_pre_timing(nlines,npoints,band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_switch_on,n_pointsperscan,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; // Check for NoddingInRaster or NoddingOfRaster int scansize = pre_timing{10}; if(scansize > 1) { {int,int,int,string,int,double,double,bool,double,double,double,int,int,double,double,int,int,double,double,int,int,int,int,int} tmpar = DBSMultiRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",pre_timing,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = nodding_of_raster_pointing(false,tmpar{0},tmpar{1},tmpar{2},tmpar{3},tmpar{4},tmpar{5},tmpar{6},tmpar{7},tmpar{8},tmpar{9},tmpar{10},tmpar{11},tmpar{12},tmpar{13},tmpar{14},tmpar{15},tmpar{16},tmpar{17},tmpar{18},tmpar{19},tmpar{20},tmpar{21},tmpar{22},tmpar{23}); } else { {int,int,int,string,int,double,double,bool,double,double,double,int,int,double,double,int,int,int,double,double,int,int,int,double,double,int,int,int,int} tpar = DBSRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",pre_timing,n_cycles); telescopetimes = nodding_raster_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23},tpar{24},tpar{25},tpar{26},tpar{27},tpar{28}); } ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,int},bool,double,double} post_timing = DBSRaster_post_timing(pre_timing,telescopetimes,nlines,npoints,n_switch_on,n_cycles,load_interval,false); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command if(scansize > 1) { tmpar = DBSMultiRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",post_timing{1},n_cycles); // Call telescope command telescopetimes = nodding_of_raster_pointing(true,tmpar{0},tmpar{1},tmpar{2},tmpar{3},tmpar{4},tmpar{5},tmpar{6},tmpar{7},tmpar{8},tmpar{9},tmpar{10},tmpar{11},tmpar{12},tmpar{13},tmpar{14},tmpar{15},tmpar{16},tmpar{17},tmpar{18},tmpar{19},tmpar{20},tmpar{21},tmpar{22},tmpar{23}); } else { tpar = DBSRaster_telescope(naifid,onPosition,lineDistance,stepsize,nlines,npoints,band,lo_freq,"",post_timing{1},n_cycles); telescopetimes = nodding_raster_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},tpar{19},tpar{20},tpar{21},tpar{22},tpar{23},tpar{24},tpar{25},tpar{26},tpar{27},tpar{28}); } // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{3}; int n_load = post_timing{1}{6}; int n_loadinterval = post_timing{1}{7}; int n_seq = post_timing{1}{8}; int initlength = post_timing{1}{11}; int dangling = post_timing{1}{12}; bool final_load = post_timing{2}; double tscan = post_timing{3}; double tdead = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { DBSRaster_commanding(band,lo_freq,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_seq,n_cycles,scansize,n_loadinterval,n_load,final_load,startobs,telescopetimes,loadlength,false); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the noise // // First get additional dead times from instrument {double,double,double} tact = DBSRaster_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_seq,n_load,scansize,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = DBS_noisecomputer(band,lo_freq,effResolution,continuumDetection,oneGHzReference,n_cycles,tscan,tact); // Evaluate performance DBSRaster_performance(band,lo_freq,effResolution,noisevalues,timeTaken,nlines,npoints,n_cycles,n_seq * imax(n_load,1),tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // Stability test, procedure // Measurement of internal cold in FSW mode procedure Proc_stability_freqswitch { string band = "1a"; // HIFI band double lo_freq = 522.0; //The LO frequency double freq_throw = 50.0; //The frequency throw in MHz int n = 100; //Number of load pairs to be measured string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code int integ_time = 4; //Total (co-added) integration time of a phase in sec. string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ // Chopper_Rotation_block_fm(band,"chop_M3_ang","chop_cold_ang"); //Look at CBB // //Tune to the two frequencies: the first frequency is the one //used to tune the backends // //Set Diplexer to the one corresponding to the middle frequency Set_Diplexer_current_FSW_block_fm(band,lo_freq + freq_throw / 2000.0); // //Set to FSW1 LO_tuning_FSW_block_fm(band,lo_freq,lo_freq + freq_throw / 2000.0,true); //The frequency settings are automatically stored in register FSW1 // //Configure backends if(backend == "hrs" || backend == "both" || backend == "hrsFast") { HRS_config_block_fm(band,hrs_mode); HRS_tune_block_fm(band); } if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { //WBS calibration WBS_calib_fm(band); WBS_tune_proc_fm(band); } // //set to FSW2 LO_tuning_FSW_block_fm(band,lo_freq + freq_throw / 1000.0,lo_freq + freq_throw / 2000.0,false); //The frequency settings are automatically stored in register FSW2 // //Configure spectrometers integration after tuning: done later //Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); // Stability_freqswitch_fm(band,n,integ_time,hrs_mode,backend); //Configure spectrometers integration back to default in tp mode Configure_Spectrometer_proc_fm(band,4,hrs_mode,backend); //2 sec. integration } //HIFI-COP-3-Deflux //Systematic deflux at beginning of each OD, or band switch obs HifiEng_Deflux_COP { string band = "1a" in ["ALL","1a","1b","2a","2b","3a","3b","4a","4b"]; // HIFI band. ALL does all mixer bands }{ // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Deflux_COP_proc_ops(band)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Deflux_COP_proc_ops(band); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } {string,double,double}[] procedure HifiPointModeLoadChopNoRefSequencerInit { string modeName = "load"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rates int n_cycles = 2 in [1,3600]; // number of half load-sky-sky-load cycles on ON int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode // limit on data rate {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // limits from noise section // Get the drift parameters to compute the drift noise // System Allan variance double[] allanparms = InterpolateSpecAllan(band,lo_freq,oneGHzReference); // rescale to frequency resolution double alpha = allanparms[1]; double binningexp = 1.0 / allanparms[2]; double allan_time_lores = allanparms[0] * pow(1.0 / effResolution{1},binningexp); // Compute derived quantities int data_time_guess = imin(imax(iceil(0.3 * allan_time_lores),datalimit),20); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } // Contruct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)}]; return retvalues; } ///////////////////////////////////////////////////////////////// // Calibration file reader for spectral scans. This is a variant of the // CalibrationReader including the dependence on the redundancy instead // of the LO frequency // double[] procedure SpectralScanReader { string topicname = "fscanedge"; // Name of entry in master file string[] objectnames = ["edgelength"]; // Names of calibration objects to be read string band = "4a"; // HIFI band int redundancy = 4; // Redundancy factor }{ // first step: read master file string calibfile = slookup("spectralscan_masterfile",topicname,"filename"); int dep = ilookup("spectralscan_masterfile",topicname,"dependence"); string sredun = "" + redundancy; int readnum = length(objectnames); double[] retvalues = []; if(dep == 0) { // Quantity is constant // Read from single file by name for(int i = 1 .. readnum) { retvalues[i - 1] = dlookup(calibfile,objectnames[i - 1],"value"); } } else { if(dep == 1) { // Quantity is only redundancy dependent // directly read from file for(int k = 1 .. readnum) { retvalues[k - 1] = dlookup(calibfile,sredun,objectnames[k - 1]); } } else { // Quantity is band and redundancy dependent // second step step: band look up, get name of responsible data file string actualfile = slookup(calibfile,band,"filename"); // Now lookup data according to redundancy for(int j = 1 .. readnum) { retvalues[j - 1] = dlookup(actualfile,sredun,objectnames[j - 1]); } } } return retvalues; } //////////////////////////////////// // Routine to provide initial guesses for sequence parameters // Load chop observing mode // {string,double,double}[] procedure HifiPointProcLoadChopSequencerInit { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source double raoff = 0.0; // RA coordinate of the OFF position double decoff = 0.0; // DEC coordinate of the OFF position string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rates int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 2 in [1,900]; // number of half load-sky-sky-load cycles on ON int n_switch_off = 2 in [1,900]; // number of half load-sky-sky-load cycles on OFF int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF calibration cycles int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode // limit on data rate {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // limits from noise section {double,double,double,double} phaselengths = LoadChopPhaseLengths(band,lo_freq,effResolution,oneGHzReference); // Compute derived quantities int data_time_guess = imin(imax(iceil(phaselengths{1}),datalimit),20); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } int n_switch_on_guess = imax(iceil(phaselengths{0} / (2.0 * double(data_time_guess))),1); int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } // OFF phase int data_time_off_guess = imin(imax(iceil(phaselengths{2}),datalimit),20); int data_time_off_range = datalimit - data_time_off_guess; if(data_time_off_range == 0) { data_time_off_range = 1; } int n_switch_off_guess = imax(iceil(double(data_time_guess * n_switch_on_guess) / (double(data_time_off_guess) * sqrt(phaselengths{3} / effResolution{1}))),1); int n_switch_off_range = 1 - n_switch_off_guess; if(n_switch_off_range == 0) { n_switch_off_range = 1; } // Add pointing requirements condition: >=10s {int,int} new_data_time = MatchMinPointing(data_time_guess,data_time_range,2 * n_switch_on_guess); data_time_guess = new_data_time{0}; data_time_range = new_data_time{1}; new_data_time = MatchMinPointing(data_time_off_guess,data_time_off_range,2 * n_switch_off_guess); data_time_off_guess = new_data_time{0}; data_time_off_range = new_data_time{1}; // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"data_time_off",double(data_time_off_guess),double(data_time_off_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)},{"n_switch_off",double(n_switch_off_guess),double(n_switch_off_range)}]; return retvalues; } ////////////////////////////////////////////////////////////////// // Procedure to compute detailed pre timing for the version of the // load chop mode without baseline measurement // {int,int,int,int,int,int,bool,int,int} procedure LoadChopNoRef_pre_timing { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4 in [1,20]; // data dump interval limited by the data rates int n_chop_on = 2 in [1,3600]; // number of half load-sky-sky-load cycles on ON int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // First check validity of frequencies CheckLOFrequencies(band,lo_freq,lo_freq); // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // First perform consistency checks // Check chunk size given by the data rates CheckDataTaking(backendreadoutparms,data_time); int jitterdead = GetMaxTimeJitter(band,lo_freq); // Compute parameters for the instrument timing int on_inttime = 2 * n_chop_on * data_time; // compute load integration time int loadlength = duration(LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms)); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); loadlength = loadlength + readoutdead; // Compare load interval with duration of the observation int load_spacing = CheckedLoadSpacing(load_interval - loadlength,8); int n_load_on = on_inttime / load_spacing; // This determines the order of the loops if(load_spacing > 2 * on_inttime) { int n_per_on = n_chop_on; bool end_load_on = false; int on_pointing = on_inttime + jitterdead; } else { n_per_on = n_chop_on / (n_load_on + 1); if(n_per_on < 1) { SError("Chop phase length on source too long relative to load period."); } end_load_on = true; on_inttime = 2 * n_per_on * (n_load_on + 1) * data_time; on_pointing = on_inttime + n_load_on * loadlength + jitterdead; } // Duration of initial set up // determine exact duration only in case of full commanding if(docommands) { int initlength = duration(HIFIInitObs()); initlength = initlength + duration(TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal")); // Add time for HK readout int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); initlength = initlength + hkduration; } else { initlength = GetRoughInitLength(band,lo_freq,false); } initlength = initlength + loadlength; // dangling time given by readout dead time int dangling = readoutdead; // Return all the times needed for telescope call and post_timing processing return {on_inttime,on_pointing,loadlength,load_spacing,n_per_on,n_load_on,end_load_on,initlength,dangling}; } // Wrapper to read configuration parameters for fixed instrument configurations // // Procedure for configuration parameters for the WARM instrument // {double,string}[] procedure ConfigurationReaderWarm { string topicname = "name_confilfpu"; // Name of entry in master file string[] objectnames = ["bias_standby_h"]; // Names of calibration objects to be read string band = "1a"; // HIFI band double lo_freq = 522000.0; // LO frequency }{ string mainmasterfile = "configuration_masterfile_warm"; {double,string}[] retvalues = FlexibleConfigurationReader(mainmasterfile,topicname,objectnames,band,lo_freq); return retvalues; } // Broadcast OBSID for gascell operations procedure StartMode_Gascell { }{ //These are ILT-EGSE commands, not ruled by the 2TC/sec. //HifiIltEgse_GAS_set_OBS_ID($OBSID); //delay(1); } ////////////////////////////////////////////////////////////////// // Procedure to compute detailed pre timing for the version of the // load chop mode without baseline measurement // {int,int,int,int,int,int,bool,int,int} procedure LoadChopNoRef_FCal_pre_timing { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4 in [1,20]; // data dump interval limited by the data rates int n_chop_on = 2 in [1,3600]; // number of half load-sky-sky-load cycles on ON int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // First check validity of frequencies CheckLOFrequencies(band,lo_freq,lo_freq); // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // First perform consistency checks // Check chunk size given by the data rates CheckDataTaking(backendreadoutparms,data_time); int jitterdead = GetMaxTimeJitter(band,lo_freq); // Compute parameters for the instrument timing int on_inttime = 2 * n_chop_on * data_time; // compute load integration time int loadlength = duration(LoadMeasurement_FCal(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms)); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); loadlength = loadlength + readoutdead; // Compare load interval with duration of the observation int load_spacing = CheckedLoadSpacing(load_interval - loadlength,8); int n_load_on = on_inttime / load_spacing; // This determines the order of the loops if(load_spacing > 2 * on_inttime) { int n_per_on = n_chop_on; bool end_load_on = false; int on_pointing = on_inttime + jitterdead; } else { n_per_on = n_chop_on / (n_load_on + 1); if(n_per_on < 1) { SError("Chop phase length on source too long relative to load period."); } end_load_on = true; on_inttime = 2 * n_per_on * (n_load_on + 1) * data_time; on_pointing = on_inttime + n_load_on * loadlength + jitterdead; } // Duration of initial set up // determine exact duration only in case of full commanding if(docommands) { int initlength = duration(HIFIInitObs()); initlength = initlength + duration(TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal")); // Add time for HK readout int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); initlength = initlength + hkduration; } else { initlength = GetRoughInitLength(band,lo_freq,false); } initlength = initlength + loadlength; // dangling time given by readout dead time int dangling = readoutdead; // Return all the times needed for telescope call and post_timing processing return {on_inttime,on_pointing,loadlength,load_spacing,n_per_on,n_load_on,end_load_on,initlength,dangling}; } // Diplexer scan, slow, procedure. // IF power as function of diplexer current. Takes 3 seconds per point // Readouts from spectrometers procedure Diplexer_scan_slow_proc { string band = "3a"; // HIFI band //Setting file double diplexer_current_min_h = -2.24; //minimum diplexer current H double diplexer_current_max_h = 2.24; //maximum diplexer current H double diplexer_current_min_v = -2.24; //minimum diplexer current V double diplexer_current_max_v = 2.24; //maximum diplexer current V int n_steps = 100; //number of steps string[] hrs_mode = ["wb1","wb1"]; //HRS resolution code: hr,mr,lr,wb1,wb2,wb3,wb4,etc double lo_freq = 807.0; //LO frequency int integ_time = 4; //Total integration time in sec.: at least 2sec ! string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast string chopmode = "tp" in ["tp","slowchop","fastchop"]; //modulation mode between hot/cold: tp, slowchop, fastchop double chop_phase = 1.0 in [0.2,2.0]; // Chop phase length }{ //In case of band 6 or 7, use special biases if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { {double,string}[] result = ConfigurationReader("name_confilfpu",["bias_dipscan_h","bias_dipscan_v","bias_max_h","bias_max_v"],band,lo_freq); //First go to 4mV Mixerbias_block_fm(result[2]{0},result[3]{0}); //Then to 3mV Mixerbias_block_fm(result[0]{0},result[1]{0}); } // Chopper_Rotation_block_fm(band,"chop_M3_ang","chop_hot_ang"); //Prepare for backend attenuators and calibration //ASSUMES HOT LOAD INTERNAL !! //Configure and tune backends //Shall be done on the worst diplexer setting double worst_diplex_current_h = 0.0; double worst_diplex_current_v = 0.0; //Fetch diplexer settings double[] result_dip = Get_Diplexer_setting(band,lo_freq); double diplex_H = result_dip[0]; double diplex_V = result_dip[1]; //Check which polarisation is used: the unused polarisation has a constant setting if(diplexer_current_min_v == diplexer_current_max_v) { //H polar is in use if(abs(diplex_H - diplexer_current_min_h) > abs(diplex_H - diplexer_current_max_h)) { worst_diplex_current_h = diplexer_current_min_h; } else { worst_diplex_current_h = diplexer_current_max_h; } } if(diplexer_current_min_h == diplexer_current_max_h) { //V polar is in use if(abs(diplex_V - diplexer_current_min_v) > abs(diplex_V - diplexer_current_max_v)) { worst_diplex_current_v = diplexer_current_min_v; } else { worst_diplex_current_v = diplexer_current_max_v; } } // Set_Diplexer_current_block_fm(worst_diplex_current_h,worst_diplex_current_v); // //Configure backends //16/11/05: NOT ANYMORE, THIS SHOULD BE DONE INDEPENDENTLY //HRS_config_block_fm(band,hrs_mode); //WBS_config_block_fm(band); //WBS calibration if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { WBS_calib_fm(band); WBS_tune_proc_fm(band); } if(backend == "hrs" || backend == "both") { HRS_tune_block_fm(band); } // //Configure spectrometers integration after tuning int[] res = [0,0]; int n_wbs1 = 0; int n_hrs_trans = 0; int total_time = 0; if(chopmode == "tp") { res = Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); total_time = res[0] * res[1]; } if(chopmode == "slowchop") { res = Configure_Spectrometer_hc_slow_chop_proc_fm(band,integ_time * 2,hrs_mode,backend); total_time = res[0] * res[1]; } if(chopmode == "fastchop") { //Integ_time expected here is the TOTAL integration time with both phases + residual HRS time res = Configure_Spectrometer_fast_chop_proc_fm(band,integ_time * 2,chop_phase,hrs_mode,backend); total_time = iceil(chop_phase * double(res[1] * res[2])); n_wbs1 = res[2]; n_hrs_trans = res[3]; //debug_print("Fast chop parameters: n_wbs1 = "+res[2]+", n_hrs_trans = "+res[3]); } // //Start loop on diplexer settings int steps = 0; int steps_done = 0; int steps_wanted = n_steps; if(steps_wanted < 1) { steps_wanted = 1; } double diplexer_current_h = 0.0; double diplexer_current_v = 0.0; double stepsize_h = 0.0; double stepsize_v = 0.0; // if(steps_wanted > 1) { stepsize_h = (diplexer_current_max_h - diplexer_current_min_h) / (double(steps_wanted) - 1.0); stepsize_v = (diplexer_current_max_v - diplexer_current_min_v) / (double(steps_wanted) - 1.0); } while(steps_done < steps_wanted) { steps = steps_wanted - steps_done; if(steps > n_steps) { steps = n_steps; } diplexer_current_h = diplexer_current_min_h + double(steps_done) * stepsize_h; diplexer_current_v = diplexer_current_min_v + double(steps_done) * stepsize_v; Set_Diplexer_current_block_fm(diplexer_current_h,diplexer_current_v); //Y-factor Hot_cold(band,hrs_mode,backend,total_time,chopmode,n_wbs1,n_hrs_trans); // steps_done = steps_done + 1; } //Get back to optimal settings Set_Diplexer_current_block_fm(diplex_H,diplex_V); // //In case of band 6 or 7,go back to nominal values if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { result = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,lo_freq); //First go to 4mV Mixerbias_block_fm(result[0]{0},result[1]{0}); //Then to nominal result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); Mixerbias_block_fm(result[0]{0},result[1]{0}); } // //Configure spectrometers integration back to default in tp mode Configure_Spectrometer_proc_fm(band,integ_time,hrs_mode,backend); } ///////////////////////////////////////////////////////////////// // Fast chop dual beam switch observing mode - special version for Jupiter // // Implemented as procedure returning time and noise levels for HSPOT {int,double,double,double,double,double} obs HifiPointProcJupiterFastDBS { /* Setup parameters */ int naifid = 0; // Tracing object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 10 in [4,80]; // data dump interval int n_int_on = 20 in [1,640]; // number chop cycles to integrate in ICU before transfer int n_switch_on = 1 in [1,1800]; // number of data transfer cycles per pointing int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Engineering - Jupiter - DBS fastChop",{data_time,0,n_int_on,n_switch_on,0,0,0,0,n_cycles,load_interval}); // Call first part of the timing computer // Two changes relative to the normal DBS // 1) The longer load duration is enforced by zero resolution {double,double} loadResolution = {0.0,effResolution{1}}; // 2) I assume that the tuning duration does not depend on the tuning level // so that the normal pre_timing can be reused. {int,int,int,int,int,int,int,int,int,bool,int,int,int} pre_timing = FastDBS_pre_timing(band,lo_freq,loadResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_switch_on,n_cycles,load_interval,docommands); ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,int,int,int,int,int,int} tpar = DBS_telescope(naifid,onPosition,band,lo_freq,"",pre_timing,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = nodding_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},false); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,bool,int,int,int},bool,double,double} post_timing = DBS_post_timing(pre_timing,telescopetimes,n_cycles); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = DBS_telescope(naifid,onPosition,band,lo_freq,"",post_timing{1},n_cycles); // Call telescope command telescopetimes = nodding_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},false); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following int loadlength = post_timing{1}{3}; int n_load = post_timing{1}{6}; int n_loadinterval = post_timing{1}{7}; int n_seq = post_timing{1}{8}; bool end_load = post_timing{1}{9}; int shiftlength = post_timing{1}{10}; bool final_load = post_timing{2}; double tscan = post_timing{3}; double tdead = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { JupiterFastDBS_commanding(band,lo_freq,loadResolution,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_seq,n_load,n_loadinterval,end_load,final_load,startobs,telescopetimes,loadlength,shiftlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double} tact = FastDBS_deadtimes(band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,n_int_on,n_seq,n_load,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = DBS_noisecomputer(band,lo_freq,effResolution,continuumDetection,oneGHzReference,n_cycles,tscan,tact); // Evaluate performance DBS_performance(band,lo_freq,effResolution,noisevalues,timeTaken,n_cycles,n_seq * n_int_on * (n_load + 1),tscan,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // Continuous HIFI integration with given backend settings at line scan block HIFIContOtfIntegration HIFI 6023 { int n_int = 1; // Integration time counter int data_time = 4; // Integration time between two data readouts double[] rates = [120.0,1.0,2.0]; // Data rates between and during integrations }{ HIFI_Spectr_tp_proc_aot(n_int,data_time,rates); } // Fast chop integration OFF-ON-OFF-ON... with telescope at ON position block HIFIFastChopOnIntegration HIFI 6042 { int data_time = 4; // Integration time between two data readouts int n_cycle = 1; // readout cycle number string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz int[] parms = [1,0]; // Parameters for chop cycles double[] rates = [120.0,1.0,2.0]; // Data rates between and during integrations }{ HIFI_Spectr_fast_chop_proc_aot(data_time,n_cycle,band,lo_freq,["chop_M3left","chop_M3right"],parms,rates); } // Set diplexer currents for both polarizations, block block Set_Diplexer_current_block_fm HIFI 3643 { double dipl_curr_h = 1.0; //Diplexer current H polarization double dipl_curr_v = 1.0; //Diplexer current V polarization }{ //Start_block(); Hifi_HIFI_CH1_DPACT_C($BBID,dipl_curr_h); Hifi_HIFI_CV1_DPACT_C($BBID,dipl_curr_v); delay(1); } /////////////////////////// //OBSOLETE // Stability test, procedure, only backends procedure Proc_stability_backend_fastchop { }{ error("Stability_backend_fastchop_fm mode is removed. Do not use"); } ///////////////////////////////////////////////////////////////// // Spectral scan in DBS observing modes // // Combination of four modules implementing the new structure // // Implemented as procedure returning time and noise levels for HSPOT {int,double,double,double,double,double} obs HifiSScanProcDBS { /* Setup parameters */ int naifid = 0; // Tracing object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz int redundancy = 4 in [1,12]; // Frequency scan redundancy {double,double} effResolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool wbs1Used = true; // whether WBS1 is used bool wbs2Used = true; // whether WBS2 is used /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_switch_on = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per frequency and pointing int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int n_cycles = 1 in [1,600]; // Number of half OFF-ON-ON-OFF cycles at one frequency int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = true; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode OpenMessages("HIFI Spectral Scan - DBS slowChop",{data_time,0,0,n_switch_on,0,0,0,n_freq_point,n_cycles,load_interval}); // First get the backend configuration {{bool,int,double[],bool[]},{bool,int,double[],bool[]},{bool,int[][]},{bool,int[][]}} backends = SScanBackendSettings(band,redundancy,wbs1Used,wbs2Used,data_time); {bool,int,double[],bool[]} hr1 = backends{0}; {bool,int,double[],bool[]} hr2 = backends{1}; {bool,int[][]} wb1 = backends{2}; {bool,int[][]} wb2 = backends{3}; ////////////////////////////////////////////////////////////////////// // Call first part of the timing computer {{int,int,int,int,int,int,int,int,int,bool,int,int,int},{int,double,double[],int[][],bool,double[],int,bool}} pre_timing = SScanDBS_pre_timing(band,lo_freq,lo_freq_up,redundancy,effResolution,hr1,hr2,wb1,wb2,data_time,n_switch_on,n_freq_point,n_cycles,load_interval,docommands); // frequency parameters int groupnumber = pre_timing{1}{0}; double reffreq = pre_timing{1}{1}; double[] freqgrid = pre_timing{1}{2}; int[][] grouporder = pre_timing{1}{3}; bool retuning = pre_timing{1}{4}; double[] targetlevels = pre_timing{1}{5}; int nfreq_if = pre_timing{1}{6}; bool dsb = pre_timing{1}{7}; int n_total = groupnumber * n_cycles; ////////////////////////////////////////////////////////////////////// // Prepare telescope command {double,double} onPosition = {ra,dec}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,int,int,int,int,int,int} tpar = DBS_telescope(naifid,onPosition,band,reffreq,"",pre_timing{0},n_total); // Dummy call to spacecraft command int[] telescopetimes = nodding_pointing(false,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},false); ////////////////////////////////////////////////////////////////////// // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,bool,int,int,int},double,double,double} post_timing = SScanDBS_post_timing(pre_timing{0},telescopetimes,n_freq_point,groupnumber,n_cycles,false); ////////////////////////////////////////////////////////////////////// // Now the observation starts for the telescope // Prepare telescope command tpar = DBS_telescope(naifid,onPosition,band,reffreq,"",post_timing{1},n_total); // Call telescope command telescopetimes = nodding_pointing(true,tpar{0},tpar{1},tpar{2},tpar{3},tpar{4},tpar{5},tpar{6},tpar{7},tpar{8},tpar{9},tpar{10},tpar{11},tpar{12},tpar{13},tpar{14},tpar{15},tpar{16},tpar{17},tpar{18},false); // Consistency check int totaltime = post_timing{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following // normal pre_timing values int n_loadinterval = post_timing{1}{7}; int n_bchop = post_timing{1}{8}; int shiftlength = post_timing{1}{10}; int initlength = post_timing{1}{11}; double avnumchop = post_timing{2}; // efficiency parameters double tscan = post_timing{3}; double tdead = post_timing{4}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands /////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { SScanDBS_commanding(band,reffreq,effResolution,hr1,hr2,wb1,wb2,n_freq_point,grouporder,freqgrid,retuning,targetlevels,data_time,n_cycles,n_total,n_bchop,n_switch_on,n_loadinterval,startobs,telescopetimes,shiftlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double} tact = SScanDBS_deadtimes(band,reffreq,hr1,hr2,wb1,wb2,n_freq_point,data_time,n_bchop,n_switch_on,n_cycles,avnumchop,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = SScanDBS_noisecomputer(band,reffreq,nfreq_if,dsb,effResolution,continuumDetection,n_cycles,tscan,tact); // Evaluate performance SScanDBS_performance(band,reffreq,nfreq_if,dsb,effResolution,noisevalues,timeTaken,n_total,groupnumber * n_freq_point,avnumchop,tscan,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // Conversion from string band name to band code (index) // for further use in LSU frequency setting // DT - 22 Aug 2006 double procedure GetBandCode { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band }{ //Loop on band names double band_code = 1.0; if(band == "1b") { //Band 1b band_code = 2.0; } if(band == "2a") { //Band 2a band_code = 3.0; } if(band == "2b") { //Band 2b band_code = 4.0; } if(band == "3a") { //Band 3a band_code = 5.0; } if(band == "3b") { //Band 3b band_code = 6.0; } if(band == "4a") { //Band 4a band_code = 7.0; } if(band == "4b") { //Band 4b band_code = 8.0; } if(band == "5a") { //Band 5a band_code = 9.0; } if(band == "5b") { //Band 5b band_code = 10.0; } if(band == "6a") { //Band 6a band_code = 11.0; } if(band == "6b") { //Band 6b band_code = 12.0; } if(band == "7a") { //Band 7a band_code = 13.0; } if(band == "7b") { //Band 7b band_code = 14.0; } // return band_code; } //////////////////////////////////// // Function to estimate the initial overhead used within CUS // // From the current implementation of the pointing modes it seems // that the initail slew is never used as part of the total time // This needs confirmation for cases with tuning+load > required slew int procedure InitialCusOverhead { /* Setup parameters */ {double,double} onPosition = {0.0,0.0}; // Coordinates of the source {double,double} refPosition = {0.2,0.2}; // Coordinates of the OFF position string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int clustered = 0; // whether observation is part of spatial/frequency cluster int data_time = 4; // data dump interval limited by the data rates; a value of 0 will be interpreted as fast-chop mode where we use a default rate }{ ////////////////////////////////////////////////////////////////////// // Call timing computer // // With the new pointing modes the initial overhead is always // excluded from the total observing time now // // int timing=Overhead_timing( // onPosition,refPosition,band,lo_freq,effResolution, // hrs1,hrs2,wbs1,wbs2,clustered,data_time); int timing = 0; return timing; } // WBS overall attenuator FM functional test, block block FT_WBS_att_individual_COMB_fm HIFI 3715 { string band = "1a"; // HIFI band int integ_time = 4; //Total integration time in sec. string laser_H = "Laser1" in ["Laser1","Laser2"]; //WBS-H laser to be set ON string laser_V = "Laser1" in ["Laser1","Laser2"]; //WBS-V laser to be set ON string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Start_block(); // //Set zero and comb off Hifi_HIFI_Single_cmd($BBID,"HWH_ZERO_ON"); Hifi_HIFI_Single_cmd($BBID,"HWV_ZERO_ON"); Hifi_HIFI_Single_cmd($BBID,"HWH_COMB_ON"); Hifi_HIFI_Single_cmd($BBID,"HWV_COMB_ON"); delay(2); // //Initial configuration: overall attenuators set to 0, individual attenuators to max. //H-Polarization // {double,string}[] result = ConfigurationReader("name_configwbs",["hwh_heater","hwh_latchup_s"],band,0.0); string hwh_laser1_s = "OFF"; string hwh_laser2_s = "OFF"; if(laser_H == "Laser1") { hwh_laser1_s = "ON"; } if(laser_H == "Laser2") { hwh_laser2_s = "ON"; } int hwh_heater = iround(result[0]{0}); string hwh_latchup_s = result[1]{1}; int hwh_att_band4 = 8; int hwh_att_band3 = 8; int hwh_att_band2 = 8; int hwh_att_band1 = 8; int hwh_att_in = 7; // result = ConfigurationReader("name_delays",["wbs_config_delay"],band,0.0); int wbs_config_delay = iround(result[0]{0}); // //V-Polarization // result = ConfigurationReader("name_configwbs",["hwv_heater","hwv_latchup_s"],band,0.0); string hwv_laser1_s = "OFF"; string hwv_laser2_s = "OFF"; if(laser_V == "Laser1") { hwv_laser1_s = "ON"; } if(laser_V == "Laser2") { hwv_laser2_s = "ON"; } int hwv_heater = iround(result[0]{0}); string hwv_latchup_s = result[1]{1}; int hwv_att_band4 = 8; int hwv_att_band3 = 8; int hwv_att_band2 = 8; int hwv_att_band1 = 8; int hwv_att_in = 7; // //Loop on overall attenuators for(int i = 0 .. 7) { // Change the value of the individual attenuators //=============================================== hwh_att_band4 = hwh_att_band4 - 1; hwh_att_band3 = hwh_att_band3 - 1; hwh_att_band2 = hwh_att_band2 - 1; hwh_att_band1 = hwh_att_band1 - 1; hwv_att_band4 = hwv_att_band4 - 1; hwv_att_band3 = hwv_att_band3 - 1; hwv_att_band2 = hwv_att_band2 - 1; hwv_att_band1 = hwv_att_band1 - 1; // Set WBS //======== Hifi_HIFI_Configure_WBS_H($BBID,hwh_laser1_s,hwh_laser2_s,hwh_heater,hwh_latchup_s,hwh_att_band4,hwh_att_band3,hwh_att_band2,hwh_att_band1,hwh_att_in); delay(wbs_config_delay); //Wait for configuration to be applied // Hifi_HIFI_Configure_WBS_V($BBID,hwv_laser1_s,hwv_laser2_s,hwv_heater,hwv_latchup_s,hwv_att_band4,hwv_att_band3,hwv_att_band2,hwv_att_band1,hwv_att_in); delay(wbs_config_delay); //Wait for configuration to be applied // HIFI_Spectr_total_power_proc_fm(band,backend,integ_time); // } //Set att. to max. WBS_config_proc_max_att_w_laser_fm(band,laser_H,laser_V); // } // Vector scan calibration for a given LO band // uses a list of pre-defined frequencies where to measure // the vector scans. procedure Vecscan_calibration_proc_fm { string band = "1a" in ["0","1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band }{ // //Get list of frequencies for given band double[] cresult = CalibrationReader("name_keyfreq",["keyfreq","minfreq","maxfreq","midfreq","badfreq"],band,0.0); // string current_subband = "0"; //Start loop on vector scans for(int i = 0 .. 4) { //Configure FPU at that frequency Init_MSA_fm(band,"CLOSE",cresult[i],"ON"); // //Perform vector scan within BLUE limits at that frequency Vector_scan_BLUE_LIMIT_block_fm(band,cresult[i]); //LCU_CLEAR_ERROR_block_fm(); // } // } //HIFI vector scan, block //Does a vector scan around the best D2 guess from vectorscan_BLUE_LIMIT block Vector_scan_AroundBestGuess_block_fm HIFI 3673 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency }{ //Clear potential failure mode Set_LO_Nominal_proc_fm(); // //Start_block(); //Fetch LO parameters string name_configlo = "name_configlo_a"; string name_configlcu = "name_configlcu_a"; string name_confindex = "name_confindex_a"; string name_configlotune = "name_configlotune_a"; string name_configlcutune = "name_configlcu_a"; if(band == "1b" || band == "2b" || band == "3b" || band == "4b" || band == "5b" || band == "6b" || band == "7b") { name_configlo = "name_configlo_b"; name_configlcu = "name_configlcu_b"; name_confindex = "name_confindex_b"; name_configlotune = "name_configlotune_b"; name_configlcutune = "name_configlcu_b"; } // {double,string}[] result = ConfigurationReader(name_configlcu,["plevel_v","m1_v","m2_v","m3_v","d2_step"],band,lo_freq); double plevel_v = result[0]{0}; double m1_v = result[1]{0}; double m2_v = result[2]{0}; double m3_v = result[3]{0}; int d2_step = iround(result[4]{0}); // double[] cresult = CalibrationReader("name_lcu_safe_values",["g1_v","g2_v","d1_v","d2_v"],band,lo_freq); double gate1_v = cresult[0]; double gate2_v = cresult[1]; double drain1_v = cresult[2]; double drain2_v_start = cresult[3]; // result = ConfigurationReader(name_confindex,["freq_nx"],band,lo_freq); int freq_nx = ifloor(result[0]{0}); //Compute lsu_main and offset int[] resu = ComputeLSU_A_M_R(band,lo_freq); int lsu_main = resu[0]; int lsu_offset = resu[1]; //Get checksum result = ConfigurationReader("name_delays",["cus_checksum"],band,lo_freq); int macro_checksum = iround(result[0]{0}); // cresult = CalibrationReader("name_lcu_safe_values",["d2_v"],band,lo_freq); double drain2_safe = cresult[0]; // //The best guess is taken from look-up table result = ConfigurationReader(name_configlcutune,["drain2_v"],band,lo_freq); double drain2_bestguess = result[0]{0}; //We will scan +/- 5% around the best guess drain2_v_start = drain2_bestguess * 0.95; if(drain2_v_start < drain2_safe) { drain2_v_start = drain2_safe; } double drain2_max = drain2_bestguess * 1.05; double drain2_bluemax = Get_BLUE_LIMIT_D2_proc_fm(band,lo_freq); if(drain2_max > drain2_bluemax) { drain2_max = drain2_bluemax; } // // result = ConfigurationReader(name_configlo,["curlim1_v","curlim2_v"],band,lo_freq); string curlim1 = result[0]{1}; string curlim2 = result[1]{1}; // result = ConfigurationReader(name_configlotune,["step_drain2_v","nsteps","step_time"],band,lo_freq); int nsteps = iround(result[1]{0}); double step_drain2_v = (drain2_max - drain2_v_start) / double(nsteps); //result[0]{0}; double step_time = 5.0; //result[2]{0}; //We will scan from max to min drain2_v_start = drain2_max; step_drain2_v = -1.0 * step_drain2_v; // double step_PL_C = 0.0; double step_m1_v = 0.0; double step_m2_v = 0.0; double step_m3_v = 0.0; double step_gate1_v = 0.0; double step_gate2_v = 0.0; double step_drain1_v = 0.0; // //First we will set the LO to the max of the scan, and wait 20 sec to settle. result = ConfigurationReader("name_delays",["config_lo_delay"],band,lo_freq); int config_lo_delay = iround(result[0]{0}); //Send command HIFI_Configure_LCU_proc_fm(band,lo_freq,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_max,curlim2,macro_checksum,config_lo_delay); // delay(20); //to settle at this value //For bands 1 to 5, scan will be done with increasing drain2 voltages // //For bands 6 to 7, scan will be done with decreasing drain2 voltages if(band == "6a" || band == "7a" || band == "6b" || band == "7b") { //step_drain2_v = -1.0*step_drain2_v; //drain2_v_start = drain2_max; } // //Load vector scan //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Load_vector_safe_1a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "1b") { //Band 1b Hifi_HIFI_Load_vector_safe_1b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2a") { //Band 2a Hifi_HIFI_Load_vector_safe_2a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "2b") { //Band 2b Hifi_HIFI_Load_vector_safe_2b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3a") { //Band 3a Hifi_HIFI_Load_vector_safe_3a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "3b") { //Band 3b Hifi_HIFI_Load_vector_nom_3b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "4a") { //Band 4a Hifi_HIFI_Load_vector_safe_4a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "4b") { //Band 4b Hifi_HIFI_Load_vector_safe_4b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v_start,curlim2,macro_checksum,step_drain2_v); } if(band == "5a") { //Band 5a Hifi_HIFI_Load_vector_nom_5a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "5b") { //Band 5b Hifi_HIFI_Load_vector_nom_5b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6a") { //Band 6a Hifi_HIFI_Load_vector_nom_6a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_m3_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "6b") { //Band 6b Hifi_HIFI_Load_vector_nom_6b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7a") { //Band 7a Hifi_HIFI_Load_vector_nom_7a($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } if(band == "7b") { //Band 7b Hifi_HIFI_Load_vector_nom_7b($BBID,nsteps,step_time,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1,drain2_v_start,curlim2,step_PL_C,step_m1_v,step_m2_v,step_gate1_v,step_gate2_v,step_drain1_v,step_drain2_v); } // //delay(1); //Execute vector scan Hifi_HIFI_vector_scan($BBID); double time_needed = double(nsteps) * step_time; delay(iround(time_needed + 2.0 + 0.5)); //0.5s added for completion of load_vector //Additional read of TM pages LCU_Read_TM_pages_proc_fm(); } ////////////////////////////////////////////////////////////////////// // Procedure to perform the noise level evaluation for the observing mode {double,double,double,double,double} procedure LoadChop_noisecomputer { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF int on_inttime = 16; // Integration time per ON phase int off_inttime = 16; // Integration time per OFF phase int n_cycles = 1; // Number of half OFF-ON-ON-OFF calibration cycles double tscan = 60.0; // Total average duration of one scan {double,double,double,double,double} tact = {10.0,4.9,4.9,0.05,0.05}; // Field of actual dead and integration times }{ double tdead = tact{0}; // Average total dead time in one scan double inttimeperonphase = tact{1}; // Actual integration time in ON phase double inttimeperoffphase = tact{2}; // Actual integration time in OFF phase double deadtimeperonphase = tact{3}; // Dead time per switch phase on ON // Get parameters which are needed double tsys = InterpolateTsys(band,lo_freq); double eta_mb = InterpolateCoupling(band,lo_freq); double[] gssb = InterpolateGssb(band,lo_freq); // Get the drift parameters to compute the drift noise // System Allan variance double[] allanparms = InterpolateSpecAllan(band,lo_freq,oneGHzReference); // rescale to frequency resolution double alpha = allanparms[1]; double binningexp = 1.0 / allanparms[2]; double allan_time_lores = allanparms[0] * pow(1.0 / eff_resolution{1},binningexp); double allan_time_hires = allanparms[0] * pow(1.0 / eff_resolution{0},binningexp); // Differential Allan variance allanparms = InterpolateSpecLChopAllan(band,lo_freq,oneGHzReference); // rescale to frequency resolution double dalpha = allanparms[1]; binningexp = 1.0 / allanparms[2]; double dallan_time_lores = allanparms[0] * pow(1.0 / eff_resolution{1},binningexp); double dallan_time_hires = allanparms[0] * pow(1.0 / eff_resolution{0},binningexp); // resolution of OFF phase double sw_resolution = GetLoadChopSWResolution(band,lo_freq); double sw_resolution_lores = max(eff_resolution{1},sw_resolution); double sw_resolution_hires = max(eff_resolution{0},sw_resolution); // Compute the relative noise for the detailed timing double on_int = double(on_inttime); double off_int = double(off_inttime); // The dead time per switch might deviate between ON and OFF - ignored double deadtimeperswitch = deadtimeperonphase; // Get actual noise // This is returned twice: for both limiting resolutions double systemnoise_lores = DoubleDifferenceNoise(inttimeperonphase / allan_time_lores,[inttimeperoffphase / inttimeperonphase,sw_resolution_lores / eff_resolution{1},on_int / allan_time_lores,off_int / allan_time_lores,deadtimeperswitch / allan_time_lores,tdead / allan_time_lores,alpha,dallan_time_lores / allan_time_lores,dalpha]); double systemnoise_hires = DoubleDifferenceNoise(inttimeperonphase / allan_time_hires,[inttimeperoffphase / inttimeperonphase,sw_resolution_hires / eff_resolution{0},on_int / allan_time_hires,off_int / allan_time_hires,deadtimeperswitch / allan_time_hires,tdead / allan_time_hires,alpha,dallan_time_hires / allan_time_hires,dalpha]); double noiseratio = DoubleDifferenceNoiseRatio(inttimeperonphase / allan_time_lores,[inttimeperoffphase / inttimeperonphase,sw_resolution_lores / eff_resolution{1},on_int / allan_time_lores,off_int / allan_time_lores,deadtimeperswitch / allan_time_lores,tdead / allan_time_lores,alpha,dallan_time_lores / allan_time_lores,dalpha]); // Compute total double sideband noise double dsbnoise_lores = tsys * sqrt(systemnoise_lores / (eff_resolution{1} * 1000000.0 * double(n_cycles) * tscan)); double dsbnoise_hires = tsys * sqrt(systemnoise_hires / (eff_resolution{0} * 1000000.0 * double(n_cycles) * tscan)); // Translate to the main beam scale, correct for eta_mb // (This is typically not done at ground based telescopes, // but leads often to problems there - to be discussed.) dsbnoise_lores = dsbnoise_lores / eta_mb; dsbnoise_hires = dsbnoise_hires / eta_mb; // Get single sideband noise equivalent double usbnoise_lores = dsbnoise_lores / gssb[0]; double usbnoise_hires = dsbnoise_hires / gssb[0]; double lsbnoise_lores = dsbnoise_lores / gssb[1]; double lsbnoise_hires = dsbnoise_hires / gssb[1]; // Return noise values and the maximum ratio of drift to radiometric noise return {usbnoise_lores,usbnoise_hires,lsbnoise_lores,lsbnoise_hires,noiseratio}; } //////////////////////////////////// // DBS raster observing mode // // Return time and noise levels {string,double,double}[] procedure HifiMappingProcDBSRasterSequencerInit { /* Setup parameters */ int naifid = 0; // Tracking object ID double ra = 0.0; // RA coordinate of the source double dec = 0.0; // DEC coordinate of the source {double,double} lineDistance = {0.0050,0.0050}; // Distance between subsequent rows int nlines = 1 in [1,100]; // Number of rows in the map double stepsize = 0.0050 in [5.5556E-4,0.13333]; // Distance between subsequent points in the raster line int npoints = 10 in [2,100]; // Number of points per row string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} effResolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz bool continuumDetection = false; // Whether timing is for total-power level bool oneGHzReference = true; // 1GHz reference bandwith instead of full IF {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_switch_on = 2 in [1,900]; // number of half sky1-sky0-sky0-sky1 cycles per pointing int n_pointsperscan = 1 in [1,1024]; // Number of points measured before moving to the second pointing phase int n_cycles = 1 in [1,32]; // Number of half OFF-ON-ON-OFF pointing cycles int load_interval = 1800 in [10,7200]; // load period = f(band,lo_freq,effResolution{1}) bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Start of observing mode {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); int datalimit = dataparms{0}; // Get the drift parameters to compute the drift noise {double,double} phaselengths = DBSPhaseLengths(band,lo_freq,effResolution,continuumDetection,oneGHzReference); // Compute derived quantities int data_time_guess = imin(imax(iceil(phaselengths{1}),datalimit),20); int data_time_range = datalimit - data_time_guess; if(data_time_range == 0) { data_time_range = 1; } // Combine points for n_switch=1 int main_phase = iceil(phaselengths{0}); int n_pointsperscan_guess = imin(imax(main_phase / (2 * data_time_guess),1),npoints * nlines); int n_pointsperscan_range = 1 - n_pointsperscan_guess; if(n_pointsperscan_range == 0) { n_pointsperscan_range = 1; } // remaining part for n_switch int n_switch_on_guess = main_phase / (n_pointsperscan_guess * 2 * data_time_guess) + 1; int n_switch_on_range = 1 - n_switch_on_guess; if(n_switch_on_range == 0) { n_switch_on_range = 1; } // Add pointing requirements condition: >=10s {int,int} new_data_time = MatchMinPointing(data_time_guess,data_time_range,2 * n_switch_on_guess); data_time_guess = new_data_time{0}; data_time_range = new_data_time{1}; // Construct return tuple {string,double,double}[] retvalues = [{"data_time",double(data_time_guess),double(data_time_range)},{"n_switch_on",double(n_switch_on_guess),double(n_switch_on_range)},{"n_pointsperscan",double(n_pointsperscan_guess),double(n_pointsperscan_range)}]; return retvalues; } //Find out stepsize double procedure Stepsize { double low = 0.0; double high = 10.0; int n_steps = 100; string parameter = "hifi_HIF_mx_mg_step_C"; }{ double range = high - low; int range_raw = convert_to_raw(parameter,range); if(range_raw < 1) { range_raw = 1; } double bitsize = range / double(range_raw); int step_raw = iround(double(range_raw) / double(n_steps)); if(step_raw == 0) { step_raw = 1; } double step = double(step_raw) * bitsize; return step; } //TPF maker for LCU patch and checksum recalc procedure LCU_patch_TPF_maker { string section = "P" in ["P","R"]; }{ //Patch upload: 150 FP involved //{int, int[]}[] runs = LcuGetMemoryRuns_ops( section); {int,int[]}[] runs = LcuGetMemoryRuns(section,1); int runcount = length(runs); if(runcount > 50) { error("LCU memory patch has more than 50 lines. This will not fit in the procedure."); } if(runcount != 0) { } else { //Empty patch } for(int i = 0 .. runcount - 1) { {int}[] par = []; int[] values = runs[i]{1}; int count = length(values); for(int j = 0 .. count - 1) { par[j] = {values[j]}; } int val = par[0]{0}; int crc = checksum("short",values); //Cannot use the Hifi_HIFI_load_LCU because tupples not supported in TPF generation Hifi_HIFI_WBS_Zero(runs[i]{0}); //Call from Ralph 04/03/09: group repeaters can be declared as FP //This value is 1 anyway //Hifi_HIFI_WBS_Zero(count); Hifi_HIFI_WBS_Zero(val); Hifi_HIFI_WBS_Zero(crc); //delay(2); } //Complement the number of TCs sent to reach the fixed TC pattern needed for TPF int nb_TC_needed = 50; //subjective choice - may be extended in the future int remaining_TC = nb_TC_needed - runcount; //Compute parameters for constant inputs values = runs[0]{1}; count = length(values); for(int jj = 0 .. count - 1) { par[jj] = {values[jj]}; } val = par[0]{0}; crc = checksum("short",values); for(int ii = 1 .. remaining_TC) { //Cannot use the Hifi_HIFI_load_LCU because tupples not supported in TPF generation Hifi_HIFI_WBS_Zero(runs[0]{0}); //Call from Ralph 04/03/09: group repeaters can be declared as FP //This value is 1 anyway //Hifi_HIFI_WBS_Zero(count); Hifi_HIFI_WBS_Zero(val); Hifi_HIFI_WBS_Zero(crc); //delay(2); } // } //Magnet tune coarse, procedure procedure Magnet_tune_coarse { string band = "1a"; // HIFI band }{ Magnet_scan_coarse_fm(band); Magnet_set_coarse_with_IVcurve_fm(band); } // Initialisation of FPU, block with both MSA in use // Looks at the hot load ! // It is for cold context ! block Init_MSA_HBB_fm HIFI 3999 { string band = "1a"; // HIFI band string chop_loop = "CLOSE"; double lo_freq = 522.0; //LO frequency string hbb_heater = "ON" in ["ON","OFF"]; //hot source on/off }{ //Start_block(); //Get parameters {double,string}[] result_d = ConfigurationReader("name_confilfpu",["band","fif1v_h","fif1c_h","fif2v_h","fif2c_h","sif1v_h","sif1c_h","sif2v_h","sif2c_h","sif3v_h","sif3c_h"],band,lo_freq); int band_nb = iround(result_d[0]{0}); double diplex_H = 0.0; double diplex_V = 0.0; int diplex_h_ctrl_mode = 0; int diplex_v_ctrl_mode = 0; // double volt_H_FIF_1 = result_d[1]{0}; double curr_H_FIF_1 = result_d[2]{0}; double volt_H_FIF_2 = result_d[3]{0}; double curr_H_FIF_2 = result_d[4]{0}; // double volt_H_SIF_1 = result_d[5]{0}; double curr_H_SIF_1 = result_d[6]{0}; double volt_H_SIF_2 = result_d[7]{0}; double curr_H_SIF_2 = result_d[8]{0}; double volt_H_SIF_3 = result_d[9]{0}; double curr_H_SIF_3 = result_d[10]{0}; // result_d = ConfigurationReader("name_confilfpu",["fif1v_v","fif1c_v","fif2v_v","fif2c_v","sif1v_v","sif1c_v","sif2v_v","sif2c_v","sif3v_v","sif3c_v"],band,lo_freq); // double volt_V_FIF_1 = result_d[0]{0}; double curr_V_FIF_1 = result_d[1]{0}; double volt_V_FIF_2 = result_d[2]{0}; double curr_V_FIF_2 = result_d[3]{0}; // double volt_V_SIF_1 = result_d[4]{0}; double curr_V_SIF_1 = result_d[5]{0}; double volt_V_SIF_2 = result_d[6]{0}; double curr_V_SIF_2 = result_d[7]{0}; double volt_V_SIF_3 = result_d[8]{0}; double curr_V_SIF_3 = result_d[9]{0}; // string chop_sine_s = "ON"; // string chop_loop = "CLOSE" ; result_d = ConfigurationReader("name_confilfpu",["chop_g1","chop_g2","chop_z1","chop_z2","chop_p2","chop_g3","chop_p3","calibrator_current"],band,lo_freq); // int chop_G1 = iround(result_d[0]{0}); int chop_G2 = iround(result_d[1]{0}); int chop_Z1 = iround(result_d[2]{0}); int chop_Z2 = iround(result_d[3]{0}); int chop_P2 = iround(result_d[4]{0}); // // // double calibcurrent = result_d[7]{0}; if(hbb_heater == "ON") { result_d = ConfigurationReader("name_confilfpu",["calibrator_current_on"],band,lo_freq); calibcurrent = result_d[0]{0}; } // //Get biases result_d = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); double bias_H = result_d[0]{0}; double bias_V = result_d[1]{0}; //For bands 6 and 7, first set to 4mV if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { result_d = ConfigurationReader("name_confilfpu",["bias_max_h","bias_max_v"],band,lo_freq); bias_H = result_d[0]{0}; bias_V = result_d[1]{0}; } // //Get magnets: not applicable to bands 6 and 7 double magnetcurrent_H = 0.0; double magnetcurrent_V = 0.0; if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilfpu",["magnet_current_max_h","magnet_current_max_v"],band,lo_freq); magnetcurrent_H = result_d[0]{0}; magnetcurrent_V = result_d[1]{0}; } //Diplexer is interpolated from a table for Bands 3, 4, 6L and 6H if(band_nb <= 2 || band_nb == 5) { diplex_H = 0.0; //For bands 1, 2 and 5 diplex_V = 0.0; diplex_h_ctrl_mode = 0; diplex_v_ctrl_mode = 0; } else { //Get diplexer currents result_d = ConfigurationReader("name_confilfpu",["diplex_h_ctrl_mode","diplex_v_ctrl_mode"],band,lo_freq); diplex_h_ctrl_mode = iround(result_d[0]{0}); diplex_v_ctrl_mode = iround(result_d[1]{0}); double[] result_dip = Get_Diplexer_setting(band,lo_freq); diplex_H = result_dip[0]; diplex_V = result_dip[1]; } // result_d = ConfigurationReader("name_confilfpu",["chop_hot"],band,0.0); //result_d = ConfigurationReader("name_chopper",["chop_startup_cold"], // band,0.0); if(chop_loop == "OPEN") { result_d = ConfigurationReader("name_chopper",["chop_startup_warm"],band,0.0); } double chopper = result_d[0]{0}; //For this configuration we won't convert prime chopper voltage into redundant voltage //Just checking we are in range. //chopper = Check_Chopper_Prime_Redundant(chopper); chopper = Check_Chopper_Range(chopper); // //Switch on upconverter, assuming chopper and mixers are also ON Hifi_HIFI_Configure_FCU_Power($BBID,"ON","ON","ON","ON","ON"); // HIFI_Configure_FCU_proc_fm(band_nb,diplex_h_ctrl_mode,volt_H_FIF_1,curr_H_FIF_1,volt_H_FIF_2,curr_H_FIF_2,volt_H_SIF_1,curr_H_SIF_1,volt_H_SIF_2,curr_H_SIF_2,volt_H_SIF_3,curr_H_SIF_3,diplex_v_ctrl_mode,volt_V_FIF_1,curr_V_FIF_1,volt_V_FIF_2,curr_V_FIF_2,volt_V_SIF_1,curr_V_SIF_1,volt_V_SIF_2,curr_V_SIF_2,volt_V_SIF_3,curr_V_SIF_3,chop_sine_s,chop_loop,chop_G1,chop_G2,chop_Z1,chop_Z2,chop_P2,calibcurrent,bias_H,magnetcurrent_H,bias_V,magnetcurrent_V,chopper,diplex_H,diplex_V); // result_d = ConfigurationReader("name_delays",["config_fpu_delay"],band,lo_freq); int config_fpu_delay = iround(result_d[0]{0}); delay(config_fpu_delay); // //In case of band 6 or 7, bias have been set to 4mV. Now set to nominal if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { {double,string}[] result = ConfigurationReader("name_confilmix",["norm_bias_h","norm_bias_v"],band,lo_freq); Mixerbias(result[0]{0},result[1]{0}); } // //Magnet are so far at maximum value. Now set to nominal if(band != "6a" && band != "6b" && band != "7a" && band != "7b") { result_d = ConfigurationReader("name_confilmix",["norm_magn_h","norm_magn_v"],band,lo_freq); Hifi_HIFI_CH1_MX_MG_C($BBID,result_d[0]{0}); Hifi_HIFI_CV1_MX_MG_C($BBID,result_d[1]{0}); delay(1); } // //Hifi_HIFI_non_periodic_hk_FCU (); } {int,double,double,double,double,double} obs HifiPointModeFSwitch { string modeName = "fs"; int goalTime = 180; double goalNoise = 0.1; bool doingTime = true; double ra = 0.0; double dec = 0.0; double raoff = 0.0; double decoff = 0.0; bool refSelected = true; int naifid = 0; string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band string spectrometer = "both"; bool hrsSeparatePol = false; string hrsModeH = "Nominal"; string hrsModeV = "Nominal"; double fe_lof_0 = 978.2; double fe_hrs1_h_0 = 0.0; double fe_hrs2_h_0 = 0.0; double fe_hrs3_h_0 = 0.0; double fe_hrs4_h_0 = 0.0; double fe_hrs1_v_0 = 0.0; double fe_hrs2_v_0 = 0.0; double fe_hrs3_v_0 = 0.0; double fe_hrs4_v_0 = 0.0; double fe_eff_res_min_0 = 1.1; double fe_eff_res_max_0 = 1.1; bool resolutionMhz = true; bool singleWbs = false; int redundancy = 4; bool dbsContinuum = true; bool oneGHzReference = true; double lo_freq1 = 978.2; double lo_freq2 = 979.6; bool fullRange = true; string fsThrow = "small-negative"; double flyX = 0.0; double flyY = 0.0; double flyAngle = 0.0; bool flyNyquistSel = false; double flyCrossStep = 10.0; string crossStepSize = "jitter" in ["jitter","nyquist","10","20","40"]; /* HSPOT-only parameters beyond this line. */ bool dbsFast = true; bool fastChop = true; string frame = "LSR"; string redshiftFrame = "heliocentric"; string redshiftType = "redshift"; double redshift = 0.0; string fe_wbs_line_0 = "-No Lines-"; string fe_wbs_trans_0 = "-No Lines-"; double fe_wbs_freq_0 = -1.0; bool fe_wbs_usb_0 = true; string fe_hrs1_h_line_0 = "-No Lines-"; string fe_hrs1_h_trans_0 = "-No Lines-"; double fe_hrs1_h_freq_0 = -1.0; bool fe_hrs1_h_usb_0 = true; string fe_hrs2_h_line_0 = "-No Lines-"; string fe_hrs2_h_trans_0 = "-No Lines-"; double fe_hrs2_h_freq_0 = -1.0; bool fe_hrs2_h_usb_0 = true; string fe_hrs3_h_line_0 = "-No Lines-"; string fe_hrs3_h_trans_0 = "-No Lines-"; double fe_hrs3_h_freq_0 = -1.0; bool fe_hrs3_h_usb_0 = true; string fe_hrs4_h_line_0 = "-No Lines-"; string fe_hrs4_h_trans_0 = "-No Lines-"; double fe_hrs4_h_freq_0 = -1.0; bool fe_hrs4_h_usb_0 = true; string fe_hrs1_v_line_0 = "-No Lines-"; string fe_hrs1_v_trans_0 = "-No Lines-"; double fe_hrs1_v_freq_0 = -1.0; bool fe_hrs1_v_usb_0 = true; string fe_hrs2_v_line_0 = "-No Lines-"; string fe_hrs2_v_trans_0 = "-No Lines-"; double fe_hrs2_v_freq_0 = -1.0; bool fe_hrs2_v_usb_0 = true; string fe_hrs3_v_line_0 = "-No Lines-"; string fe_hrs3_v_trans_0 = "-No Lines-"; double fe_hrs3_v_freq_0 = -1.0; bool fe_hrs3_v_usb_0 = true; string fe_hrs4_v_line_0 = "-No Lines-"; string fe_hrs4_v_trans_0 = "-No Lines-"; double fe_hrs4_v_freq_0 = -1.0; bool fe_hrs4_v_usb_0 = true; bool docommands = true; // Whether instrument commands are generated /* Sequence parameters */ int data_time = 4 in [1,20]; // data dump interval limited by the data rates int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_switch_on = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles on ON int n_switch_off = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles on OFF int n_cycles = 1 in [1,1200]; // Number of half OFF-ON-ON-OFF calibration cycles int load_interval = 1800 in [10,7200]; // load period in seconds }{ // start Volkers list {double,double} lineDistance = {0.0,0.0}; int nlines = 1; double stepsize = 0.0; int npoints = 1; double lo_freq = 1000.0; double lo_freq_up = 1000.0; double av_lo_freq = 1000.0; double freq_throw = 0.0; double redundancy_C = 4.0; {double,double} effResolution = {1.0,1.0}; bool continuumDetection = true; {bool,int,double[],bool[]} hrs1 = {true,1,[1.0],[true]}; {bool,int,double[],bool[]} hrs2 = {true,1,[1.0],[true]}; {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // int data_time = 1 ; // double data_chop = 0.0 ; // int n_int_on = 1 ; // int n_int_off = 1 ; // int n_switch_on = 1 ; // int n_switch_off = 1 ; // int n_linesperscan = 1 ; // int n_pointsperscan = 1 ; // int n_freq_point = 1 ; // int n_cycles = 1; // int load_interval = 1 ; // end of Volkers list // start general definitions {int,double,double,double,double,double} result = {1,0.0,0.0,0.0,0.0,0.0}; double degreesPerRadian = 57.2957795; double degreesPerArcmin = 1.0 / 60.0; double degreesPerArcsec = 1.0 / 3600.0; double factorMHzPerGHz = 1000.0; double factorMHzPerkHz = 0.0010; double[] hrs1aux = [0.0]; double[] hrs2aux = [0.0]; double[] sortarr = [0.0]; // end general definitions // start translation // frequencies lo_freq = fe_lof_0 * factorMHzPerGHz; if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { lo_freq = lo_freq1 * factorMHzPerGHz; lo_freq_up = lo_freq2 * factorMHzPerGHz; av_lo_freq = 0.5 * (lo_freq + lo_freq_up); } else { av_lo_freq = lo_freq; lo_freq_up = lo_freq; } redundancy_C = double(redundancy); freq_throw = GetTrueFsThrow(band,av_lo_freq,fsThrow); // An additional function is needed here to compute the // actual LO frequency from the redshift correction // This needs to be provided by Mission Planning // double lo_shift=function(redshift,frame,redshiftframe); // pointing stepsize = flyCrossStep * degreesPerArcsec; if(flyNyquistSel) { double[] s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } // Setup for maps if(modeName == "raster" || modeName == "cross" || modeName == "fly" || modeName == "fs-raster" || modeName == "load-raster") { // line distance measured 90deg ccw to lines lineDistance = {stepsize * cos(flyAngle / degreesPerRadian),stepsize * -sin(flyAngle / degreesPerRadian)}; npoints = imax(iceil(flyX * degreesPerArcmin / stepsize),2); nlines = imax(iceil(flyY * degreesPerArcmin / stepsize),1); // exception handling for raster maps if(modeName == "raster") { if(npoints > 32 || nlines > 32) { IError("Map too large." + " Raster maps are restricted to <= 32x32 points."); } } // special treatment for cross map mode if(modeName == "cross") { npoints = 3; nlines = 2; if(crossStepSize == "nyquist") { s = CalibrationReader("beam",["nyquist"],band,av_lo_freq); stepsize = s[0]; } else { s = CalibrationReader("crossstep",[crossStepSize],band,av_lo_freq); stepsize = s[0]; } } } else { npoints = 1; nlines = 1; } // backends // assume none used unless proven otherwise hrs1{0} = false; hrs2{0} = false; wbs1{0} = false; wbs2{0} = false; if(spectrometer == "hrs" || spectrometer == "hrsFast" || spectrometer == "both") { hrs1{0} = true; hrs2{0} = true; } // no HRS in spectral scan modes - only serendipity backend if(modeName == "fs-freq" || modeName == "freq" || modeName == "load-freq") { hrs1{0} = false; hrs2{0} = false; // put minimum resolution explicitely to WBS resolution fe_eff_res_min_0 = max(1.1,fe_eff_res_min_0); } double[] x = CalibrationReader("backendselect",["bestwbs"],band,av_lo_freq); int bestWbs = iround(x[0]); x = CalibrationReader("backendselect",["window1_lo","window1_up","window2_lo","window2_up","window3_lo","window3_up","window4_lo","window4_up"],band,av_lo_freq); int[] stdWbsWindow1 = [iround(x[0]),iround(x[1])]; int[] stdWbsWindow2 = [iround(x[2]),iround(x[3])]; int[] stdWbsWindow3 = [iround(x[4]),iround(x[5])]; int[] stdWbsWindow4 = [iround(x[6]),iround(x[7])]; if(spectrometer == "wbs" || spectrometer == "both") { if(!singleWbs) { wbs1{0} = true; wbs2{0} = true; } else { if(bestWbs == 1) { wbs1{0} = true; } else { wbs2{0} = true; } } } // for spectral scans bool wbs1Used = wbs1{0}; bool wbs2Used = wbs2{0}; string[] hrsModes = ["High","Nominal","Low","Wide"]; if(spectrometer == "hrsFast") { bool[][] hrsUseMap = [[true,false,false,false],[true,false,false,false],[true,true,false,false],[true,true,false,false]]; int[] hrsUseBands = [1,1,2,2]; } else { hrsUseMap = [[true,false,false,false],[true,true,false,false],[true,true,true,true],[true,true,true,true]]; hrsUseBands = [1,2,4,4]; } hrs1{1} = -1; hrs2{1} = -1; for(int i = 0 .. 3) { if(hrsModeH == hrsModes[i]) { hrs1{1} = i; } if(hrsModeV == hrsModes[i]) { hrs2{1} = i; } } // Special treatment for band 6 due to weired definition in HSPOT // Check whether IF is out of subband I if(stdWbsWindow1[1] - stdWbsWindow1[0] == 0) { double mix = 0.8; // mixing point relative to Andrew's scale hrs1aux = [mix - fe_hrs1_h_0,mix - fe_hrs2_h_0,mix - fe_hrs3_h_0,mix - fe_hrs4_h_0]; hrs2aux = [mix - fe_hrs1_v_0,mix - fe_hrs2_v_0,mix - fe_hrs3_v_0,mix - fe_hrs4_v_0]; } else { hrs1aux = [fe_hrs1_h_0,fe_hrs2_h_0,fe_hrs3_h_0,fe_hrs4_h_0]; hrs2aux = [fe_hrs1_v_0,fe_hrs2_v_0,fe_hrs3_v_0,fe_hrs4_v_0]; } // Order HRS subbands to assign USB frequencies to first subbands sortarr = DSort(hrs1aux,hrsUseBands[hrs1{1}]); for(int j1 = 0 .. 3) { hrs1{2}[j1] = sortarr[j1] * factorMHzPerGHz; } sortarr = DSort(hrs2aux,hrsUseBands[hrs2{1}]); for(int j2 = 0 .. 3) { hrs2{2}[j2] = sortarr[j2] * factorMHzPerGHz; } hrs1{3} = hrsUseMap[hrs1{1}]; hrs2{3} = hrsUseMap[hrs2{1}]; wbs1{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; wbs2{1} = [stdWbsWindow1,stdWbsWindow2,stdWbsWindow3,stdWbsWindow4]; // resolution effResolution = EffectiveResolution(band,av_lo_freq,{fe_eff_res_min_0,fe_eff_res_max_0},resolutionMhz,wbs1{0},wbs2{0},{hrs1{0},hrs1{1}},{hrs2{0},hrs2{1}}); continuumDetection = dbsContinuum; // no need to translate any sequencer-determined values // end of translation // end of generic code // Start of observing mode OpenMessages("HIFI Single Point - Frequency Switch Ref",{data_time,data_time_off,0,n_switch_on,n_switch_off,0,0,0,n_cycles,load_interval}); // position switch // Call first part of the timing computer {int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int} pre_timing_ps = FSwitch_pre_timing(band,lo_freq,freq_throw,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,n_switch_on,n_switch_off,n_cycles,load_interval,docommands); // Prepare telescope command {double,double} onPosition = {ra,dec}; {double,double} refPosition = {raoff,decoff}; {int,int,int,string,int,double,double,bool,double,double,double,int,double,int,int,int,int,int,int} tpar_ps = PositionSwitch_telescope(naifid,onPosition,refPosition,band,lo_freq,pre_timing_ps,n_cycles); // Dummy call to spacecraft command int[] telescopetimes = nodding_pointing(false,tpar_ps{0},tpar_ps{1},tpar_ps{2},tpar_ps{3},tpar_ps{4},tpar_ps{5},tpar_ps{6},tpar_ps{7},tpar_ps{8},tpar_ps{9},tpar_ps{10},tpar_ps{11},tpar_ps{12},tpar_ps{13},tpar_ps{14},tpar_ps{15},tpar_ps{16},tpar_ps{17},tpar_ps{18},true); // Call second part of timing computer using results // from telescope command {int,{int,int,int,int,int,int,int,int,int,int,int,int,bool,bool,int,int},int,bool,double,double} post_timing_ps = DoubleChop_post_timing(pre_timing_ps,telescopetimes,n_cycles); // Now the actual observation starts // Prepare telescope command tpar_ps = PositionSwitch_telescope(naifid,onPosition,refPosition,band,lo_freq,post_timing_ps{1},n_cycles); // Call telescope command telescopetimes = nodding_pointing(true,tpar_ps{0},tpar_ps{1},tpar_ps{2},tpar_ps{3},tpar_ps{4},tpar_ps{5},tpar_ps{6},tpar_ps{7},tpar_ps{8},tpar_ps{9},tpar_ps{10},tpar_ps{11},tpar_ps{12},tpar_ps{13},tpar_ps{14},tpar_ps{15},tpar_ps{16},tpar_ps{17},tpar_ps{18},true); // Consistency check int totaltime = post_timing_ps{0}; if(totaltime != telescopetimes[0]) { CError("Mismatch between instrument time of " + totaltime + "s and" + " telescope time of " + telescopetimes[0] + "s detected."); } }{ ////////////////////////////////////////////////////////////////////// // Instrument section // Get all values from post_timing needed in the following ////////////////////////////////////////////////////////////////////// int on_inttime = post_timing_ps{1}{0}; int off_inttime = post_timing_ps{1}{1}; int on_pointing = post_timing_ps{1}{2}; int off_pointing = post_timing_ps{1}{3}; int loadlength = post_timing_ps{1}{4}; int n_loadinterval = post_timing_ps{1}{7}; int n_per_on = post_timing_ps{1}{8}; int n_per_off = post_timing_ps{1}{9}; int n_load_on = post_timing_ps{1}{10}; int n_load_off = post_timing_ps{1}{11}; bool end_load_on = post_timing_ps{1}{12}; bool end_load_off = post_timing_ps{1}{13}; int initshiftlength = post_timing_ps{2}; bool final_load = post_timing_ps{3}; double tscan = post_timing_ps{4}; double tdead = post_timing_ps{5}; ////////////////////////////////////////////////////////////////////// // Now the observation starts for the instrument // Initialize time sync(); int startobs = time(); // Call instrument commands ////////////////////////////////////////////////////////////////////// // Don't do anything if docommand=false // if(docommands) { FSwitch_commanding(band,lo_freq,freq_throw,effResolution,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,n_per_on,n_per_off,n_loadinterval,n_load_on,n_load_off,end_load_on,end_load_off,final_load,startobs,telescopetimes,loadlength,initshiftlength); } else { delay(telescopetimes[0] + telescopetimes[1]); } // Second consistency check int timeTaken = time() - startobs - telescopetimes[1]; if(timeTaken != totaltime) { CError("Mismatch between instrument time of " + totaltime + "s and" + " command duration of " + timeTaken + "s detected."); } ////////////////////////////////////////////////////////////////////// // Compute the total rms we got out of this // // First get additional dead times from instrument {double,double,double,double,double} tact = DoubleChop_deadtimes("fs",band,lo_freq,hrs1,hrs2,wbs1,wbs2,data_time,data_time_off,n_per_on,n_per_off,n_load_on,n_load_off,tdead); // // Call noise computer {double,double,double,double,double} noisevalues = FSwitch_noisecomputer(band,lo_freq,effResolution,oneGHzReference,on_inttime,off_inttime,n_cycles,tscan,tact); // Evaluate performance DoubleChop_performance(band,lo_freq,effResolution,noisevalues,timeTaken,n_cycles,n_per_on * (n_load_on + 1),n_per_off * (n_load_off + 1),true,tscan,on_pointing,tact); // Return everything noise_level([noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3}]); // Auxiliary construct for HSPOT - return total time and noise values // Also return the maximum ratio of drift to radiometric noise return {timeTaken,noisevalues{0},noisevalues{1},noisevalues{2},noisevalues{3},noisevalues{4}}; } // Change LO frequency by a small step in FSW mode // // Externally it has to be guaranteed that this never uses a step larger // than one index in the LO table procedure HIFIChangeFreqFsw { string band = "4a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 978200.0; // LO frequency ion MHz double freq_throw = -40.0; // throw of frequency switch in MHz }{ ConfigureFPU(band,lo_freq + freq_throw / 2.0,false); HIFITuneFreqNoretuneFsw(band,lo_freq,lo_freq + freq_throw); } // procedure called to get the WBS into standby procedure HifiIntoStandby_II { }{ //LO is switched off -> is superfluous if from stbyI to stbyII LCU_switch_off_block_aot(); //Will only switch heaters //LO is switched to standby -> is superfluous if from stbyI to stbyII LCU_standby_block_aot(); //FPU stand-by: HBB is ON, chopper to rest position Init_MSA_aot("0","CLOSE",0.0,true,"ON"); //HRS stand-by -> is superfluous if from stbyI to stbyII HRS_config_max_att_block_aot("0",["wb","wb"]); //WBS stand-by with laser ON WBS_standby_block_aot("ON"); } //HIFI-COP-2.3-CPR-Scan1 obs HifiEng_Chopper_calibration_COP { int band = 1 in [1,7]; // HIFI mixer band int freq_index = 1 in [1,3]; //Frequency index: 2 is forbidden if sky=true bool sky = true; //whether or not we scan over M3 area }{ //General parameters in use int integ_time = 4; //Integration time PER PHASE for the slowchop measurement bool shutter_used = false; string[] hrs_mode = ["wb1","wb1"]; //For bands 6 and 7, use wb8 if(band == 6 || band == 7) { hrs_mode = ["wb8","wb8"]; } // // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Chopper_calibration_COP_proc_ops(band,sky,integ_time,shutter_used,hrs_mode,freq_index)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Chopper_calibration_COP_proc_ops(band,sky,integ_time,shutter_used,hrs_mode,freq_index); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } //////////////////////////////////////////////////////////////////////////// // Procedure to generate the instrument commands for the OTF observing mode procedure OTFLoadChop_commanding { string band = "4a"; // HIFI band double lo_freq = 978200.0; // LO frequency in MHz {double,double} eff_resolution = {1.0,1.0}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4; // chunk size given by the data rates and optimum speed int data_time_off = 4 in [1,20]; // data dump interval on OFF int n_perline = 10; // Number of frequency switch cycles per line int n_switch_off = 3; // Number of frequency switch cycles on OFF int nlines_tot = 1; // Total number of lines to scan int n_linesperscan = 1; // Number of lines between two OFFs int n_loadinterval = 1; // number of nods before a load measurement int startobs = 0; // Actual starting time of observation int[] telescopetimes = [300,180,2,2,40,10,20,21,0]; // Timing of the observation from telescope int loadlength = 21; // Load duration }{ // Auxiliary variables // Create a composite readout structure for simpler handling {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // get time values from the telescope structure int tinitslew = telescopetimes[1]; // Initial slew time int toffslew = telescopetimes[6]; // slew dead time between points //////////////////////////////////////////////////////////////////////// // Instrument Initialization: The instrument tuning is done as early as // possible, the load calibration as late as possible // // Clustering is currently not implemented in MPS - switched off here int clustered = 0; // data rates {int,double[]} dataparms = DataTaking(backendreadoutparms,data_time); double[] onrates = dataparms{1}; dataparms = DataTaking(backendreadoutparms,data_time_off); double[] offrates = dataparms{1}; int hkduration = HkReadoutTime(band,lo_freq,backendreadoutparms,false); int readoutdead = SlowChopReadoutDelay(band,lo_freq,backendreadoutparms); // Count OFFs by hand, their counter is not returned in the state array int ioff = 0; //////////////////////////////////////////////////////////////////////// // start state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 1) { // Initialization if(clustered != 1) { HIFIInitObs(); TuneHIFI(band,lo_freq,hrs1,hrs2,wbs1{0},wbs2{0},"normal"); } delay(tinitslew - (time() - startobs) - loadlength - hkduration); // First load measurement HIFISetHK("normal",false); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } if(state[0] == 4) { // OFF Integration HIFIConfigureLoadChopIntegration(data_time_off,n_switch_off,band,lo_freq,backendreadoutparms); HIFILoadChopOffIntegration(data_time_off,n_switch_off,band,lo_freq,offrates); // OFF counter ioff = ioff + 1; // Check for normal slew after OFF if(state[2] * state[3] < nlines_tot) { HIFIActiveHK("normal",toffslew); } } if(state[0] == 8) { // OTF integration // Check whether we come from the OFF if((state[2] + n_linesperscan - 1) % n_linesperscan == 0) { HIFIConfigureLoadChopIntegration(data_time,n_perline,band,lo_freq,backendreadoutparms); } HIFILoadChopOnIntegration(data_time,n_perline,band,lo_freq,onrates); // Check for normal slew towards the OFF if(state[2] % n_linesperscan == 0) { if(ioff % n_loadinterval > 0) { HIFIActiveHK("normal",toffslew); } } } if(state[0] == 9) { // Load slew delay(readoutdead); LoadMeasurement(band,lo_freq,eff_resolution{0},data_time,backendreadoutparms); } if(state[0] == 5) { delay(readoutdead); HIFICloseObs(); } } } //HIFI-COP-X-FastImix: 21Hz oscillation investigation obs HifiEng_Fast_Imix { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band }{ // //General parameters in use for Fast_Imix string polarization = "B"; //mixer to be sampled: H, V or B. If B, they are done successively int milliSecSample = 3; // interval between samples int samplesBefore = 50; int samplesAfter = 1000; // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Fast_Imix_proc_ops(band,polarization,milliSecSample,samplesBefore,samplesAfter)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Fast_Imix_proc_ops(band,polarization,milliSecSample,samplesBefore,samplesAfter); } if(state[0] == 5) { HIFISetHK("normal",true); HIFICloseObs(); } } } // Compute Fast Chop delay necessary for integration, procedure procedure Apply_Fast_Chop_delay { int total_time = 12; //single readout time * n_wbs_start * n_wbs1 int n_wbs_start = 1; //Number of global loop string band = "1a"; // HIFI band string backend = "both" in ["both","hrs","wbs","hrsFast","wbsFast","wbsFast2"]; //Backend in use: both, hrs, wbs, hrsFast or wbsFast }{ //Packet transfer time {double,string}[] result = ConfigurationReader("name_delays",["wbs_transfer_delay"],band,0.0); // int wbs_packet_transfer_time = iround(result[0]{0}); // //In case less channels are used, one must adapt the transfer time if(backend == "hrs" || backend == "wbs") { //wbs_packet_transfer_time = 0; //3000; } if(backend == "wbs" || backend == "both" || backend == "wbsFast" || backend == "wbsFast2") { //expect half backend //wbs_packet_transfer_time = 0; //2000; } // //Compute delay: the 2 sec. contain 2x900sec for the extra HRS time, + some margin for the wbs_init of 115 msec int delay_fast_chop = total_time + n_wbs_start * 2 + wbs_packet_transfer_time / 1000; //debug_print("Fast Chop delay: " + delay_fast_chop + " sec"); // //Apply delay delay(delay_fast_chop); // } ///////////////////////////////////////////////////////////////// // Procedure to compute detailed timing for a // Spectral Scan Load-chop observing mode // {{int,int,int,int,int,int,bool,int,int},{int,double,double[],int[][],bool,double[],int,bool}} procedure SScanLoadChopNoRef_pre_timing { string band = "4a"; // HIFI band double lo_freq_low = 978200.0; // Lower LO frequency limit in MHz double lo_freq_up = 979600.0; // Upper LO frequency limit in MHz int redundancy = 4; // Frequency scan redundancy {double,double} eff_resolution = {1.1,1.1}; // Minimum and maximum goal resolution of the calibrated data in MHz {bool,int,double[],bool[]} hrs1 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS1 parameters={used,resolution,frequency offsets, subbands used} {bool,int,double[],bool[]} hrs2 = {true,1,[-110.0,110.0,0.0,0.0],[true,true,true,true]}; // HRS2 parameters={used,resolution,frequency offsets, subbands used} {bool,int[][]} wbs1 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS1 parameters ={used, channel windows} {bool,int[][]} wbs2 = {true,[[0,2048],[0,2048],[0,2048],[0,2048]]}; // WBS2 parameters ={used, channel windows} int data_time = 4 in [1,20]; // data dump interval limited by the data rate/stability int n_chop_on = 2 in [1,900]; // number of half nu1-nu2-nu2-nu1 cycles per frequency and pointing int n_freq_point = 1 in [1,12]; // Number of frequency steps before pointing to second phase int load_interval = 1800 in [10,7200]; // load period in seconds bool docommands = false; // Whether instrument command loop is executed }{ ////////////////////////////////////////////////////////////////////// // Create composite readout structure for backends {{bool,int,bool[]},{bool,int,bool[]},{bool,int[][]},{bool,int[][]}} backendreadoutparms = {{hrs1{0},hrs1{1},hrs1{3}},{hrs2{0},hrs2{1},hrs2{3}},wbs1,wbs2}; // Get frequency grid characteristic parameters {int,double,double[],int[][],int,bool} fqparms = MakeFreqGrid(band,lo_freq_low,lo_freq_up,redundancy,0.0,n_freq_point); int groupnumber = fqparms{0}; double reffreq = fqparms{1}; double[] freqgrid = fqparms{2}; int[][] grouporder = fqparms{3}; // Process tuning level grid double[][] levelgrid = GetSScanLevelGrid(band,wbs1,wbs2,freqgrid,fqparms{0},grouporder); {bool,double[]} targets = TargetLevels(band,reffreq,levelgrid); bool retuning = targets{0}; double[] targetgrid = targets{1}; string reftarget = ""; if(retuning) { reftarget = "sscan_normal"; } {int,double,double[],int[][],bool,double[],int,bool} spectralparms = {fqparms{0},reffreq,freqgrid,grouporder,retuning,targetgrid,fqparms{4},fqparms{5}}; ////////////////////////////////////////////////////////////////////// int jitterdead = GetMaxTimeJitter(band,reffreq); // Integration time per frequency and pointing int on_inttime = 2 * n_chop_on * data_time; // Tuning delays int bigtunestep = duration(HIFIRetuneFreq(band,reffreq,reftarget)); // Correct for variation within the band int tunediff = ComputeLOTimeDifference(band,lo_freq_low,lo_freq_up,reffreq); bigtunestep = bigtunestep + tunediff; // A step within a group could be faster than a large step if(n_freq_point > 1) { int smallstep = duration(HIFIChangeFreq(band,reffreq)); } else { smallstep = bigtunestep; } int grouptime = n_freq_point * on_inttime + (n_freq_point - 1) * smallstep; // Compute load integration time int loadlength = duration(SScanLoadMeasurement(band,reffreq,reffreq,true,eff_resolution{0},data_time,backendreadoutparms)); int readoutdead = SlowChopReadoutDelay(band,reffreq,backendreadoutparms); loadlength = loadlength + readoutdead; // Duration of initial set up // Staying at the same frequency makes no sense here. // First frequency point double runningfreq = freqgrid[grouporder[0][0]]; // determine exact duration only in case of full commanding if(docommands) { int initlength = duration(HIFIInitObs()); initlength = initlength + duration(TuneHIFI(band,runningfreq,hrs1,hrs2,wbs1{0},wbs2{0},"sscan_normal")); // Add time for HK readout int hkduration = HkReadoutTime(band,reffreq,backendreadoutparms,false); initlength = initlength + hkduration; } else { initlength = GetRoughInitLength(band,runningfreq,true); } initlength = initlength + loadlength; int initloadlength = loadlength; // Compare load interval with duration of the observation int load_spacing = CheckedLoadSpacing(load_interval - loadlength,8); if(load_spacing < grouptime && n_freq_point > 1) { SError("Load period too short for frequency group size."); } // Here we bracket each cycle by loads, this leads to a grace period int n_load_on = on_inttime / load_spacing; // In the following the definition of n_load_on is higher by 1 relative to // that used in normal load-chop! // This determines the order of the loops if(n_load_on == 0) { int n_per_on = n_chop_on; bool end_load_on = false; // recompute load length in case of short integrations loadlength = duration(SScanLoadMeasurement(band,reffreq,reffreq,false,eff_resolution{0},data_time,backendreadoutparms)); loadlength = loadlength + readoutdead; } else { // grace condition if(double(on_inttime) > 1.2 * double(load_spacing)) { n_load_on = n_load_on + 1; } n_per_on = n_chop_on / n_load_on; if(n_per_on < 1) { SError("FS phase length on source too long relative to load period."); } end_load_on = true; on_inttime = 2 * n_per_on * n_load_on * data_time; // This cannot happen for n_freq_point > 1 grouptime = on_inttime + n_load_on * loadlength; } int on_pointing = groupnumber * (grouptime + bigtunestep + loadlength) - bigtunestep - loadlength + jitterdead; // dangling time given by readout dead time int dangling = readoutdead; // Return all the times needed for telescope call and post_timing processing return {{on_inttime,on_pointing,initloadlength,load_spacing,n_per_on,n_load_on,end_load_on,initlength,dangling},spectralparms}; } //HIFI-COP-2.3-Param-Scan: used to compute full duration obs HifiManCmd_Parameter_Scan_MOIS { string warning_message = "WARNING: THIS MODE IS NOT DESIGNED TO BE SCHEDULED - ONLY HERE FOR MANUAL COMMANDING !!"; //READ THIS CAREFULLY! int index = 1 in [1,7]; // Test case index as of config_paramscan_COP.config int phase = 1 in [1,2]; //Measurement phase bool config_only = true; //whether we only configure ("true") or run also Stab and Tsys }{ //Read corresponding band string tab = "config_paramscan_COP.config"; string band = slookup(tab,"" + index,"band"); //General parameters in use int integ_time = 4; //Integration time PER PHASE for the slowchop measurement string[] hrs_mode = ["wb1","wb1"]; //For bands 6 and 7, use wb8 if(band == "6a" || band == "6b" || band == "7a" || band == "7b") { hrs_mode = ["wb8","wb8"]; } // // pre_timing {int,int} pre_timing = Eng_pre_timing(); int initlength = pre_timing{0}; int closelength = pre_timing{1}; int mainduration = duration(Parameter_Scan_MOIS_proc_ops(index,phase,integ_time,hrs_mode,config_only)); // telescope command int[] ts = no_pointing(true,initlength,closelength,mainduration); }{ // Instrument commanding - use state machine int[] state = [0]; while(state[0] >= 0) { state = next_state(); if(state[0] == 2) { // Initialization HIFIInitObs(); HIFISetHK("fast",true); } if(state[0] == 3) { // Test execution Parameter_Scan_MOIS_proc_ops(index,phase,integ_time,hrs_mode,config_only); } if(state[0] == 5) { HIFISetHK("normal",true); StopMode_block_ops(); } } } //General LO configuration command block HIFI_Configure_LCU_w_TMPageDump_block_fm HIFI 3917 { string band = "1a" in ["1a","1b","2a","2b","3a","3b","4a","4b","5a","5b","6a","6b","7a","7b"]; // HIFI band double lo_freq = 500.0; //LO frequency int freq_nx = 0; // HL_freq_nx int lsu_main = 0; // HL_LSU_main int lsu_offset = 0; // HL_LSU_offset int d2_step = 1; // HL_D2_step double plevel_v = 0.0; double m1_v = 9.0; double m2_v = -2.0; double m3_v = 0.0; double gate1_v = -2.5; double gate2_v = -2.5; double drain1_v = 2.8; string curlim1_v = "1.4"; double drain2_v = 2.6; string curlim2_v = "1.4"; int macro_checksum = 0; // HL_macro_checksum int config_lo_delay = 6; }{ //Check that Vd2 is within the blue limits drain2_v = Check_BLUE_LIMIT_D2_proc_fm(band,lo_freq,drain2_v); // //Start_block(); // //Execute configuration //Check which LO band is used if(band == "1a") { //Band 1a Hifi_HIFI_Conf_safe_LCU_ch1a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "1b") { //Band 1b Hifi_HIFI_Conf_safe_LCU_ch1b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "2a") { //Band 2a Hifi_HIFI_Conf_safe_LCU_ch2a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "2b") { //Band 2b Hifi_HIFI_Conf_safe_LCU_ch2b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "3a") { //Band 3a Hifi_HIFI_Conf_safe_LCU_ch3a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "3b") { //Band 3b Hifi_HIFI_Conf_nom_LCU_ch3b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "4a") { //Band 4a Hifi_HIFI_Conf_safe_LCU_ch4a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "4b") { //Band 4b Hifi_HIFI_Conf_safe_LCU_ch4b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,drain2_v,curlim2_v,macro_checksum); } if(band == "5a") { //Band 5a Hifi_HIFI_Conf_nom_LCU_ch5a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "5b") { //Band 5b Hifi_HIFI_Conf_nom_LCU_ch5b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "6a") { //Band 6a Hifi_HIFI_Conf_nom_LCU_ch6a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,m3_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "6b") { //Band 6b Hifi_HIFI_Conf_nom_LCU_ch6b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "7a") { //Band 7a Hifi_HIFI_Conf_nom_LCU_ch7a($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } if(band == "7b") { //Band 7b Hifi_HIFI_Conf_nom_LCU_ch7b($BBID,freq_nx,lsu_main,lsu_offset,d2_step,plevel_v,m1_v,m2_v,gate1_v,gate2_v,drain1_v,curlim1_v,drain2_v,curlim2_v,macro_checksum); } // delay(config_lo_delay); // //Store settings into available register //HIFI_HL_store_tm_proc_fm(); // //Additional read of TM pages //Normal series of 5 TCs Hifi_HIFI_LCU_macro_tuning_hk("HSK_TM1"); delay(2); Hifi_HIFI_LCU_macro_tuning_hk("HSK_TM2"); delay(2); Hifi_HIFI_LCU_macro_tuning_hk("HSK_TM3"); delay(2); Hifi_HIFI_LCU_macro_tuning_hk("HSK_TM"); delay(2); Hifi_HIFI_LCU_macro_tuning_hk("HSK_G"); delay(2); //Try with 2 delays //Additional read of TM pages: use new TC Hifi_HIFI_LCU_all_tuning_hk(); delay(2); //Additional read of TM pages: use new TC Hifi_HIFI_LCU_all_tuning_hk(); delay(1); } block HKrate HIFI 901 { double rate = 0.25; }{ Start_block_no_hk_request(); string hk_rate = "1_pkt_per_10_s"; if(rate < 0.2) { hk_rate = "1_pkt_per_10_s"; } if(rate >= 0.2 && rate < 0.25) { hk_rate = "1_pkt_per_5_s"; } if(rate >= 0.25 && rate < 0.33) { hk_rate = "1_pkt_per_4_s"; } if(rate >= 0.33 && rate < 1.0) { hk_rate = "1_pkt_per_3_s"; } if(rate >= 1.0) { hk_rate = "1_pkt_per_s"; } Hifi_HIFI_Housekeeping_on(hk_rate,"ON","ON","ON","ON","ON","ON"); delay(1); } //HIFI HK control, procedure procedure Switch_HK_proc_ops { string hk_FCU = "ON" in ["ON","OFF"]; //Status of FCU HK string hk_LCU = "ON" in ["ON","OFF"]; //Status of LCU HK string hk_WBSV = "ON" in ["ON","OFF"]; //Status of WBSV HK string hk_WBSH = "ON" in ["ON","OFF"]; //Status of WBSH HK string hk_HRSV = "ON" in ["ON","OFF"]; //Status of HRSV HK string hk_HRSH = "ON" in ["ON","OFF"]; //Status of HRSH HK }{ //Get applicable HK rate {double,string}[] result_d = ConfigurationReader("name_delays",["hk_rate"],"0",0.0); string hk_rate = result_d[0]{1}; Hifi_HIFI_Housekeeping_on(hk_rate,hk_FCU,hk_LCU,hk_WBSV,hk_WBSH,hk_HRSV,hk_HRSH); delay(1); } // Routine to check whether loadlength is short compared to // load interval, so that loadspacing is reasonably long int procedure CheckedLoadSpacing { int load_spacing = 100; // time interval between load measurements int minspacing = 8; // minimum interval }{ if(load_spacing < minspacing) { IError("Required load calibration time too long. " + "Increase lower goal resolution limit."); } return load_spacing; } // LCU2a configuration into SAFE mode, procedure procedure LCU2a_config_safe_proc_fm { string band = "2a"; // HIFI band double lo_freq = 700.0 in [647.0,710.0]; //LO frequency }{ error("This module is obsolete: use LCU_config_nominal_proc_fm instead"); }