| 1 | 'use strict';
|
|---|
| 2 |
|
|---|
| 3 | include('scripts/CheckStates.js');
|
|---|
| 4 | include('scripts/Hist2D.js');
|
|---|
| 5 | include('scripts/Func.js');
|
|---|
| 6 | include('scripts/takeRun.js');
|
|---|
| 7 | include('scripts/tools.js');
|
|---|
| 8 |
|
|---|
| 9 | if (!("CheckUnderflow" in this)){
|
|---|
| 10 | var CheckUnderflow = {
|
|---|
| 11 |
|
|---|
| 12 | check_power_on_time_and_get_drs_runs : function(){
|
|---|
| 13 | console.out("Checking power on time");
|
|---|
| 14 |
|
|---|
| 15 | var service_drs = new Subscription("FAD_CONTROL/DRS_RUNS");
|
|---|
| 16 | var runs = service_drs.get(5000, false);
|
|---|
| 17 | var power = dim.state("AGILENT_CONTROL_50V").time;
|
|---|
| 18 | var now = new Date();
|
|---|
| 19 |
|
|---|
| 20 | console.out(" * Now: "+now);
|
|---|
| 21 | console.out(" * Last power cycle: "+power);
|
|---|
| 22 | console.out(" * Last DRS calib set: "+(runs.data?runs.time:"none"));
|
|---|
| 23 |
|
|---|
| 24 | service_drs.close();
|
|---|
| 25 | return runs;
|
|---|
| 26 | },
|
|---|
| 27 |
|
|---|
| 28 | // find a GOOD name!
|
|---|
| 29 | check_states_one : function(){
|
|---|
| 30 | var table = [
|
|---|
| 31 | [ "MCP", [ "Idle" ] ],
|
|---|
| 32 | [ "AGILENT_CONTROL_24V", [ "VoltageOn" ] ],
|
|---|
| 33 | [ "AGILENT_CONTROL_50V", [ "VoltageOn" ] ],
|
|---|
| 34 | [ "AGILENT_CONTROL_80V", [ "VoltageOn" ] ],
|
|---|
| 35 | [ "FTM_CONTROL", [ "Valid" ] ],
|
|---|
| 36 | [ "FAD_CONTROL", [ "Connected", "RunInProgress" ] ],
|
|---|
| 37 | [ "BIAS_CONTROL", [ "Disconnected", "VoltageOff" ] ],
|
|---|
| 38 | [ "DATA_LOGGER", [ "WaitForRun", "NightlyFileOpen", "Logging" ] ],
|
|---|
| 39 | ];
|
|---|
| 40 |
|
|---|
| 41 | console.out("Checking states.");
|
|---|
| 42 | if (!CheckStates.checkStates(table))
|
|---|
| 43 | {
|
|---|
| 44 | throw new Error("Something unexpected has happened. One of the servers",
|
|---|
| 45 | "is in a state in which it should not be. Please,",
|
|---|
| 46 | "try to find out what happened...");
|
|---|
| 47 | }
|
|---|
| 48 | },
|
|---|
| 49 |
|
|---|
| 50 | prepare_drs_calibration : function(){
|
|---|
| 51 | dim.send("FAD_CONTROL/START_DRS_CALIBRATION");
|
|---|
| 52 | dim.send("FAD_CONTROL/SET_FILE_FORMAT", 0);
|
|---|
| 53 |
|
|---|
| 54 | var sub_runs = new Subscription("FAD_CONTROL/RUNS");
|
|---|
| 55 | var sruns = sub_runs.get(5000, false);
|
|---|
| 56 |
|
|---|
| 57 | if (dim.state("FAD_CONTROL").name=="RunInProgress" || sruns.qos==1)
|
|---|
| 58 | {
|
|---|
| 59 | dim.send("FAD_CONTROL/CLOSE_OPEN_FILES");
|
|---|
| 60 | dim.wait("FAD_CONTROL", "Connected", 3000);
|
|---|
| 61 |
|
|---|
| 62 | console.out("Waiting for open files to be closed...");
|
|---|
| 63 | v8.timeout(60000, function() { if (sub_runs.get(0, false).qos==0) return true; });
|
|---|
| 64 |
|
|---|
| 65 | // Although the file should be closed now, the processing might still be on-going
|
|---|
| 66 | // and delayed events might be received. The only fix for that issue is to
|
|---|
| 67 | // add the run number to the data we are waiting for
|
|---|
| 68 | v8.sleep(5000);
|
|---|
| 69 | }
|
|---|
| 70 |
|
|---|
| 71 | sub_runs.close();
|
|---|
| 72 | },
|
|---|
| 73 |
|
|---|
| 74 | take_at_least_one_drs_gain_events : function(){
|
|---|
| 75 | console.out("Starting drs-gain... waiting for new event");
|
|---|
| 76 |
|
|---|
| 77 | var fad_event_data_service = new Subscription("FAD_CONTROL/EVENT_DATA");
|
|---|
| 78 | var sub_startrun = new Subscription("FAD_CONTROL/START_RUN");
|
|---|
| 79 | var sub_incomplete = new Subscription("FAD_CONTROL/INCOMPLETE");
|
|---|
| 80 | var sub_connections = new Subscription("FAD_CONTROL/CONNECTIONS");
|
|---|
| 81 | sub_connections.get(5000);
|
|---|
| 82 | sub_startrun.get(5000);
|
|---|
| 83 | takeRun.attachFadControlIncompleteOnChange();
|
|---|
| 84 |
|
|---|
| 85 | while (1)
|
|---|
| 86 | {
|
|---|
| 87 | var event_counter_before_run = fad_event_data_service.get(10000, false).counter;
|
|---|
| 88 |
|
|---|
| 89 | var stop_run_after_first_events_recieved = function ()
|
|---|
| 90 | {
|
|---|
| 91 | while (1)
|
|---|
| 92 | {
|
|---|
| 93 | var current_event_counter = fad_event_data_service.get(0, false).counter;
|
|---|
| 94 | if (dim.state("MCP").name=="TakingData" && current_event_counter > event_counter_before_run)
|
|---|
| 95 | {
|
|---|
| 96 | dim.send("MCP/STOP");
|
|---|
| 97 | console.out("Sent MCP/STOP.");
|
|---|
| 98 | return;
|
|---|
| 99 | }
|
|---|
| 100 | v8.sleep(100);
|
|---|
| 101 | }
|
|---|
| 102 | }
|
|---|
| 103 |
|
|---|
| 104 | var thread = new Thread(250, stop_run_after_first_events_recieved);
|
|---|
| 105 |
|
|---|
| 106 | var run_was_okay = takeRun.takeRun("drs-gain");
|
|---|
| 107 |
|
|---|
| 108 | thread.kill();
|
|---|
| 109 |
|
|---|
| 110 | if (run_was_okay)
|
|---|
| 111 | break;
|
|---|
| 112 | }
|
|---|
| 113 |
|
|---|
| 114 | console.out("Event received.");
|
|---|
| 115 |
|
|---|
| 116 | sub_incomplete.close();
|
|---|
| 117 | sub_connections.close();
|
|---|
| 118 | sub_startrun.close();
|
|---|
| 119 |
|
|---|
| 120 |
|
|---|
| 121 | // FIXME: Restore DRS calibration in case of failure!!
|
|---|
| 122 | // FAD Re-connect in case of failure?
|
|---|
| 123 | // MCP/RESET in case of failure?
|
|---|
| 124 | // Proper error reporting!
|
|---|
| 125 |
|
|---|
| 126 | var event = fad_event_data_service.get(3000);
|
|---|
| 127 | fad_event_data_service.close();
|
|---|
| 128 |
|
|---|
| 129 | console.out("Run stopped.");
|
|---|
| 130 |
|
|---|
| 131 | dim.send("RATE_CONTROL/STOP"); // GlobalThresholdSet -> Connected
|
|---|
| 132 | dim.wait("MCP", "Idle", 3000);
|
|---|
| 133 |
|
|---|
| 134 | return event;
|
|---|
| 135 | },
|
|---|
| 136 |
|
|---|
| 137 | get_max_drs_run_number : function(drs_runs)
|
|---|
| 138 | {
|
|---|
| 139 | if ( drs_runs.data
|
|---|
| 140 | && drs_runs.data.length > 0
|
|---|
| 141 | && drs_runs.obj['roi'] > 0 )
|
|---|
| 142 | return drs_runs.obj['run'].reduce(Func.max):
|
|---|
| 143 | else
|
|---|
| 144 | return -1;
|
|---|
| 145 | },
|
|---|
| 146 |
|
|---|
| 147 | stop_trigger : function(){
|
|---|
| 148 | if (dim.state("FTM_CONTROL").name=="TriggerOn")
|
|---|
| 149 | {
|
|---|
| 150 | dim.send("FTM_CONTROL/STOP_TRIGGER");
|
|---|
| 151 | dim.wait("FTM_CONTROL", "Valid");
|
|---|
| 152 | }
|
|---|
| 153 | },
|
|---|
| 154 |
|
|---|
| 155 | path_from_night_n_run : function(night_int, run_number, extension){
|
|---|
| 156 |
|
|---|
| 157 | var yy = night_int/10000;
|
|---|
| 158 | var mm = (night_int/100)%100;
|
|---|
| 159 | var dd = night_int%100;
|
|---|
| 160 |
|
|---|
| 161 | var filefmt = "/loc_data/raw/%d/%02d/%02d/%8d_%03d."+extension;
|
|---|
| 162 | var path = filefmt.$(yy, mm, dd, night_int, run_number);
|
|---|
| 163 | return path;
|
|---|
| 164 | },
|
|---|
| 165 |
|
|---|
| 166 | drs_path_from_night_n_run : function(night_int, run_number){
|
|---|
| 167 | return path_from_night_n_run(night_int, run_number, "drs.fits"):
|
|---|
| 168 | },
|
|---|
| 169 |
|
|---|
| 170 | restore_drs_calibration : function(drs_runs){
|
|---|
| 171 | var max_drs_run_number = this.get_max_drs_run_number(drs_runs);
|
|---|
| 172 | if (max_drs_run_number > 0)
|
|---|
| 173 | {
|
|---|
| 174 | var night = drs_runs.obj['night'];
|
|---|
| 175 |
|
|---|
| 176 | dim.log("Trying to restore last DRS calibration #"+max_drs_run_number+" ["+drs_runs.time+"; "+night+"]");
|
|---|
| 177 |
|
|---|
| 178 | // FIXME: Timeout
|
|---|
| 179 | var service_drs = Subscription("FAD_CONTROL/DRS_RUNS");
|
|---|
| 180 | if (!service_drs)
|
|---|
| 181 | service_drs = new Subscription("FAD_CONTROL/DRS_RUNS");
|
|---|
| 182 | var drs_counter = service_drs.get(0, false).counter;
|
|---|
| 183 | dim.send("FAD_CONTROL/LOAD_DRS_CALIBRATION", drs_path_from_night_n_run(night, max_drs_run_number));
|
|---|
| 184 |
|
|---|
| 185 | try
|
|---|
| 186 | {
|
|---|
| 187 | var now = new Date();
|
|---|
| 188 | v8.timeout(3000, function() { if (service_drs.get(0, false).counter>drs_counter) return true; });
|
|---|
| 189 | dim.log("Last DRS calibration restored ["+(new Date()-now)/1000+"s]");
|
|---|
| 190 | }
|
|---|
| 191 | catch (e)
|
|---|
| 192 | {
|
|---|
| 193 | console.warn("Restoring last DRS calibration failed.");
|
|---|
| 194 | }
|
|---|
| 195 |
|
|---|
| 196 | service_drs.close();
|
|---|
| 197 | }
|
|---|
| 198 | },
|
|---|
| 199 |
|
|---|
| 200 | analyse_drs_gain_event : function(event){
|
|---|
| 201 | var data = event.obj;
|
|---|
| 202 |
|
|---|
| 203 | var hist = Hist2D.Hist2D(16, -2048.5, 2048.5, 11, -10, 100);
|
|---|
| 204 | for (var i=0; i<1440; i++)
|
|---|
| 205 | hist.fill(data.avg[i], isNaN(data.rms[i])?-1:data.rms[i]);
|
|---|
| 206 |
|
|---|
| 207 | hist.print();
|
|---|
| 208 |
|
|---|
| 209 | var stat0 = Func.stat(data.avg, function(val, idx) { if (val<600) console.out(" PIX[hw="+idx+"]="+val); return val<600; });
|
|---|
| 210 | var stat1 = Func.stat(data.rms);
|
|---|
| 211 |
|
|---|
| 212 | console.out("Avg[min]=%.1f".$(stat0.min));
|
|---|
| 213 | console.out("Avg[avg]=%.1f +- %.1f".$(stat0.avg, stat0.rms));
|
|---|
| 214 | console.out("Avg[max]=%.1f".$(+stat0.max));
|
|---|
| 215 | console.out("Avg[cnt]="+stat0.count);
|
|---|
| 216 | console.out("");
|
|---|
| 217 | console.out("Rms[min]=%.1f".$(stat1.min));
|
|---|
| 218 | console.out("Rms[avg]=%.1f +- %.1f".$(stat1.avg, stat1.rms));
|
|---|
| 219 | console.out("Rms[max]=%.1f".$(stat1.max));
|
|---|
| 220 | console.out(tools.line_of_equal_signs(78));
|
|---|
| 221 |
|
|---|
| 222 | // OK UNDERFLOW
|
|---|
| 223 | // ------------------------------------------------------
|
|---|
| 224 | // Avg[min]=722.0 Avg[min]=-380.0
|
|---|
| 225 | // Avg[avg]=815.9 +- 45.9 Avg[avg]= 808.0 +- 102.0
|
|---|
| 226 | // Avg[max]=930.5 Avg[max]= 931.1
|
|---|
| 227 | // Avg[cnt]=0 Avg[cnt]= 9
|
|---|
| 228 |
|
|---|
| 229 | // Rms[min]=14.0 Rms[min]=13.9
|
|---|
| 230 | // Rms[avg]=16.5 +- 1.6 Rms[avg]=18.8 +- 26.8
|
|---|
| 231 | // Rms[max]=44.0 Rms[max]=382.1
|
|---|
| 232 |
|
|---|
| 233 | if (stat0.count>0)
|
|---|
| 234 | {
|
|---|
| 235 | if (stat0.count>8)
|
|---|
| 236 | throw new Error("Underflow condition detected in about "+parseInt(stat0.count/9+.5)+" DRS.");
|
|---|
| 237 |
|
|---|
| 238 | console.warn("There is probably an underflow condition in one DRS... please check manually.");
|
|---|
| 239 | }
|
|---|
| 240 | },
|
|---|
| 241 |
|
|---|
| 242 | checkUnderflow : function(){
|
|---|
| 243 | console.out( tools.line_of_equal_signs(78) );
|
|---|
| 244 | this.stop_trigger();
|
|---|
| 245 | this.check_states_one();
|
|---|
| 246 | var drs_runs = this.check_power_on_time_and_get_drs_runs();
|
|---|
| 247 | CheckStates.checkSend(["FAD_CONTROL", "MCP", "RATE_CONTROL"], 5000, true);
|
|---|
| 248 | this.prepare_drs_calibration();
|
|---|
| 249 | var event = this.take_at_least_one_drs_gain_events();
|
|---|
| 250 | this.restore_drs_calibration(drs_runs);
|
|---|
| 251 | this.analyse_drs_gain_event(event):
|
|---|
| 252 | },
|
|---|
| 253 | };
|
|---|
| 254 | }
|
|---|
| 255 | else{
|
|---|
| 256 | console.out("multiple include of 'CheckUnderflow.js'")
|
|---|
| 257 | }
|
|---|