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