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 | }
|
---|