// 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"); // } //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","stby"); // StopMode_block_mois(); // -> 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("");
// 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("
");
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 polarization-averaged," + " 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 polarization-averaged," + " single-sideband, main beam temperature scale of a " + fwhm + "'' beam with a main beam efficiency of " + eta_mb * 100.0 + "%.", 1);
}
message("