source: trunk/FACT++/src/smartfact.cc@ 13759

Last change on this file since 13759 was 13759, checked in by tbretz, 12 years ago
Show message 'Ratescan in progress.'
File size: 47.7 KB
Line 
1#include "Dim.h"
2#include "Event.h"
3#include "Shell.h"
4#include "StateMachineDim.h"
5#include "Connection.h"
6#include "Configuration.h"
7#include "Console.h"
8#include "Converter.h"
9#include "DimServiceInfoList.h"
10#include "PixelMap.h"
11
12#include "tools.h"
13#include "DimData.h"
14
15#include "LocalControl.h"
16
17#include "HeadersFAD.h"
18#include "HeadersBIAS.h"
19#include "HeadersFTM.h"
20
21using namespace std;
22
23// ------------------------------------------------------------------------
24
25#include "DimDescriptionService.h"
26
27// ------------------------------------------------------------------------
28
29const static string kHtmlWhite = "#ffffff";
30const static string kHtmlYellow = "#fffff0";
31const static string kHtmlRed = "#fff8f0";
32const static string kHtmlGreen = "#f0fff0";
33const static string kHtmlBlue = "#f0f0ff";
34
35class StateMachineSmartFACT : public StateMachineDim, public DimInfoHandler
36{
37private:
38 enum states_t
39 {
40 kStateDimNetworkNA = 1,
41 kStateRunning,
42 };
43
44 // ------------------------- Internal variables -----------------------
45
46 PixelMap fPixelMap;
47
48 Time fLastUpdate;
49
50 string fPath;
51
52 // ----------------------------- Data storage -------------------------
53
54 uint32_t fMcpConfigurationState;
55 int64_t fMcpConfigurationMaxTime;
56 int64_t fMcpConfigurationMaxEvents;
57 string fMcpConfigurationName;
58 Time fMcpConfigurationRunStart;
59
60 enum weather_t { kWeatherBegin=0, kTemp = kWeatherBegin, kDew, kHum, kPress, kWind, kGusts, kDir, kWeatherEnd = kDir+1 };
61 deque<float> fMagicWeatherHist[kWeatherEnd];
62
63 vector<float> fFeedbackCalibration;
64
65 float fFeedbackTempOffset;
66 float fFeedbackUserOffset;
67
68 vector<float> fBiasControlVoltageVec;
69
70 float fBiasControlVoltageMed;
71 float fBiasControlCurrentMed;
72 float fBiasControlCurrentMax;
73
74 deque<float> fBiasControlCurrentHist;
75 deque<float> fFscControlTemperatureHist;
76
77 float fFscControlTemperatureAvg;
78 float fFscControlHumidityAvg;
79
80 float fDriveControlPointingZd;
81 string fDriveControlPointingAz;
82 float fDriveControlTrackingDev;
83 string fDriveControlSourceName;
84
85 int64_t fFadControlNumEvents;
86
87 float fFtmControlTriggerRateCam;
88 deque<float> fFtmControlTriggerRateHist;
89
90 vector<float> fFtmPatchThresholds;
91
92 uint64_t fRateScanDataId;
93 deque<float> fRateScanDataHist;
94
95 // ------------- Initialize variables before the Dim stuff ------------
96
97 DimServiceInfoList fNetwork;
98
99 class DimState : public DimInfoHandler
100 {
101 public:
102 DimState(const string &n, const string s="STATE") :
103 server(n), info(make_pair(Time(), -4)),
104 dim((n+"/"+s).c_str(), (void*)NULL, 0, this) { }
105
106 string server;
107 pair<Time, int> info;
108 string msg;
109
110 DimStampedInfo dim;
111
112 void infoHandler()
113 {
114 DimInfo *curr = getInfo(); // get current DimInfo address
115 if (!curr || curr != &dim)
116 return;
117
118 const bool disconnected = dim.getSize()==0;
119
120 // Make sure getTimestamp is called _before_ getTimestampMillisecs
121 const int tsec = dim.getTimestamp();
122 const int tms = dim.getTimestampMillisecs();
123
124 info = make_pair(Time(tsec, tms*1000),
125 disconnected ? -4 : dim.getQuality());
126
127 msg = disconnected ? "" : dim.getString();
128 }
129
130 const Time &time() const { return info.first; }
131 const int &state() const { return info.second; }
132
133 bool online() const { return info.second>-4; }
134
135 const string &name() const { return server; }
136 };
137
138 class DimVersion : public DimState
139 {
140 public:
141 DimVersion() : DimState("DIS_DNS", "VERSION_NUMBER") { }
142
143 void infoHandler()
144 {
145 DimInfo *curr = getInfo(); // get current DimInfo address
146 if (!curr || curr != &dim)
147 return;
148
149 DimState::infoHandler();
150
151 info.second = dim.getSize()==4 ? dim.getInt() : 0;
152 }
153
154 string version() const
155 {
156 if (info.second==0)
157 return "Offline";
158
159 ostringstream out;
160 out << "V" << info.second/100 << 'r' << info.second%100;
161 return out.str();
162 }
163 };
164
165
166 DimVersion fDim;
167 DimState fDimMcp;
168 DimState fDimControl;
169 DimState fDimDataLogger;
170 DimState fDimDriveControl;
171 DimState fDimMagicWeather;
172 DimState fDimFeedback;
173 DimState fDimBiasControl;
174 DimState fDimFtmControl;
175 DimState fDimFadControl;
176 DimState fDimFscControl;
177 DimState fDimRateControl;
178 DimState fDimRateScan;
179 DimState fDimChatServer;
180
181 DimStampedInfo fDimMcpConfiguration;
182
183 DimStampedInfo fDimDriveControlPointing;
184 DimStampedInfo fDimDriveControlTracking;
185 DimStampedInfo fDimDriveControlSource;
186
187 DimStampedInfo fDimFscControlTemperature;
188 DimStampedInfo fDimFscControlHumidity;
189
190 DimStampedInfo fDimMagicWeatherData;
191
192 DimStampedInfo fDimFeedbackDeviation;
193 DimStampedInfo fDimFeedbackCalibration;
194
195 DimStampedInfo fDimBiasControlVoltage;
196 DimStampedInfo fDimBiasControlCurrent;
197
198 DimStampedInfo fDimFadConnections;
199 DimStampedInfo fDimFadEvents;
200
201 DimStampedInfo fDimFtmControlTriggerRates;
202 DimStampedInfo fDimFtmControlStaticData;
203
204 DimStampedInfo fDimRateScanData;
205
206 DimStampedInfo *fDimFadControlEventData;
207
208 // -------------------------------------------------------------------
209
210 const State GetState(const DimState &s) const
211 {
212 return fNetwork.GetState(s.name(), s.state());
213 }
214
215 // -------------------------------------------------------------------
216
217 bool HandleService(DimInfo *curr, const DimInfo &service, void (StateMachineSmartFACT::*handle)(const DimData &))
218 {
219 if (curr!=&service)
220 return false;
221
222 (this->*handle)(DimData(curr));
223 return true;
224 }
225
226
227 bool CheckDataSize(const DimData &d, const char *name, size_t size, bool min=false)
228 {
229 if ((!min && d.data.size()==size) || (min && d.data.size()>size))
230 return true;
231
232 ostringstream msg;
233 msg << name << " - Received service has " << d.data.size() << " bytes, but expected ";
234 if (min)
235 msg << "more than ";
236 msg << size << ".";
237 Warn(msg);
238 return false;
239 }
240
241
242 // -------------------------------------------------------------------
243
244 template<class T>
245 void WriteBinary(const DimData &d, const string &fname, const T &t, double scale, double offset=0)
246 {
247 vector<uint8_t> val(t.size(), 0);
248 for (uint64_t i=0; i<t.size(); i++)
249 {
250 float range = nearbyint(128*(t[i]-offset)/scale); // [-2V; 2V]
251 if (range>127)
252 range=127;
253 if (range<0)
254 range=0;
255 val[i] = (uint8_t)range;
256 }
257
258 const char *ptr = reinterpret_cast<char*>(val.data());
259
260 ofstream fout(fPath+"/"+fname+".bin");
261 fout << d.time.JavaDate() << '\n';
262 fout << offset << '\n';
263 fout << offset+scale << '\n';
264 fout.write(ptr, val.size()*sizeof(uint8_t));
265 }
266
267 // -------------------------------------------------------------------
268
269 struct Statistics
270 {
271 float min;
272 float max;
273 float med;
274 float avg;
275 //float rms;
276
277 template<class T>
278 Statistics(const T &t, size_t offset_min=0, size_t offset_max=0)
279 : min(0), max(0), med(0), avg(0)
280 {
281 if (t.size()==0)
282 return;
283
284 T copy(t);
285 sort(copy.begin(), copy.end());
286
287 if (offset_min>t.size())
288 offset_min = 0;
289 if (offset_max>t.size())
290 offset_max = 0;
291
292 min = copy[offset_min];
293 max = copy[copy.size()-1-offset_max];
294 avg = accumulate (t.begin(), t.end(), 0.)/t.size();
295
296 const size_t p = t.size()/2;
297
298 med = copy[p];
299 }
300 };
301
302 void HandleMcpConfiguration(const DimData &d)
303 {
304 if (!CheckDataSize(d, "Mcp:Configuration", 16, true))
305 return;
306
307 fMcpConfigurationState = d.qos;
308 fMcpConfigurationMaxTime = d.get<uint64_t>();
309 fMcpConfigurationMaxEvents = d.get<uint64_t>(8);
310 fMcpConfigurationName = d.ptr<char>(16);
311
312 if (d.qos==12)
313 fMcpConfigurationRunStart = Time();
314 }
315
316 void WriteWeather(const DimData &d, const string &name, int i, float min, float max)
317 {
318 const Statistics stat(fMagicWeatherHist[i]);
319
320 ostringstream out;
321 out << setprecision(3);
322 out << d.time.JavaDate() << '\n';
323
324 out << "#ffffff\t" << fMagicWeatherHist[i].back() << '\n';
325 out << "#ffffff\t" << stat.min << '\n';
326 out << "#ffffff\t" << stat.avg << '\n';
327 out << "#ffffff\t" << stat.max << '\n';
328
329 ofstream(fPath+"/"+name+".txt") << out.str();
330
331 WriteBinary(d, "magicweather-"+name+"-hist", fMagicWeatherHist[i], max-min, min);
332 }
333
334 void HandleMagicWeatherData(const DimData &d)
335 {
336 if (!CheckDataSize(d, "MagicWeather:Data", 7*4+2))
337 return;
338
339 // Store a history of the last 300 entries
340 for (int i=kWeatherBegin; i<kWeatherEnd; i++)
341 {
342 fMagicWeatherHist[i].push_back(d.ptr<float>(2)[i]);
343 if (fMagicWeatherHist[i].size()>300)
344 fMagicWeatherHist[i].pop_front();
345 }
346
347 static const char *dir[] =
348 {
349 "N", "NNE", "NE", "ENE",
350 "E", "ESE", "SE", "SSE",
351 "S", "SSW", "SW", "WSW",
352 "W", "WNW", "NW", "NNW"
353 };
354
355 const uint16_t idx = uint16_t(floor(fmod(fMagicWeatherHist[kDir].back()+360+11.25, 360)/22.5));
356
357 ostringstream out;
358 out << d.time.JavaDate() << '\n';
359 for (int i=0; i<6; i++)
360 out << "#ffffff\t" << fMagicWeatherHist[i].back() << '\n';
361 out << "#ffffff\t" << dir[idx] << '\n';
362
363
364 ofstream(fPath+"/magicweather.txt") << out.str();
365
366 WriteWeather(d, "temp", kTemp, -5, 35);
367 WriteWeather(d, "dew", kDew, -5, 35);
368 WriteWeather(d, "hum", kHum, 0, 100);
369 WriteWeather(d, "wind", kWind, 0, 100);
370 WriteWeather(d, "gusts", kGusts, 0, 100);
371 WriteWeather(d, "press", kPress, 700, 1000);
372 }
373
374 void HandleDriveControlPointing(const DimData &d)
375 {
376 if (!CheckDataSize(d, "DriveControl:Pointing", 16))
377 return;
378
379 fDriveControlPointingZd = d.get<double>();
380
381 const double az = d.get<double>(8);
382
383 static const char *dir[] =
384 {
385 "N", "NNE", "NE", "ENE",
386 "E", "ESE", "SE", "SSE",
387 "S", "SSW", "SW", "WSW",
388 "W", "WNW", "NW", "NNW"
389 };
390
391 const uint16_t i = uint16_t(floor(fmod(az+360+11.25, 360)/22.5));
392 fDriveControlPointingAz = dir[i];
393
394 ostringstream out;
395 out << d.time.JavaDate() << '\n';
396
397 out << setprecision(5);
398 out << fDriveControlPointingZd << '\n';
399 out << az << '\n';
400
401 ofstream(fPath+"/drive-pointing.txt") << out.str();
402 }
403
404 void HandleDriveControlTracking(const DimData &d)
405 {
406 if (!CheckDataSize(d, "DriveControl:Tracking", 56))
407 return;
408
409 const double zd = d.get<double>(3*8) * M_PI / 180;
410 const double dzd = d.get<double>(5*8) * M_PI / 180;
411 const double daz = d.get<double>(6*8) * M_PI / 180;
412
413 // Correct:
414 // const double d = cos(del) - sin(zd+dzd)*sin(zd)*(1.-cos(daz));
415
416 // Simplified:
417 const double dev = cos(dzd) - sin(zd+dzd)*sin(zd)*(1.-cos(daz));
418 fDriveControlTrackingDev = acos(dev) * 180 / M_PI * 3600;
419
420 if (fDriveControlTrackingDev<0.01)
421 fDriveControlTrackingDev=0;
422 }
423
424 void HandleDriveControlSource(const DimData &d)
425 {
426 if (!CheckDataSize(d, "DriveControl:Source", 7*4+2, true))
427 return;
428
429 const double *ptr = d.ptr<double>();
430
431 const double ra = ptr[0]; // Ra[h]
432 const double dec = ptr[1]; // Dec[deg]
433 const double woff = ptr[4]; // Wobble offset [deg]
434 const double wang = ptr[5]; // Wobble angle [deg]
435
436 fDriveControlSourceName = d.ptr<char>(6*8);
437
438 ostringstream out;
439 out << d.time.JavaDate() << '\n';
440
441 out << "#ffffff\t" << fDriveControlSourceName << '\n';
442 out << setprecision(5);
443 out << "#ffffff\t" << ra << '\n';
444 out << "#ffffff\t" << dec << '\n';
445 out << setprecision(3);
446 out << "#ffffff\t" << woff << '\n';
447 out << "#ffffff\t" << wang << '\n';
448
449 ofstream(fPath+"/drive.txt") << out.str();
450 }
451
452 void HandleFeedbackCalibration(const DimData &d)
453 {
454 if (!CheckDataSize(d, "Feedback:Calibration", 3*4*416))
455 {
456 fFeedbackCalibration.clear();
457 return;
458 }
459
460 const float *ptr = d.ptr<float>();
461 fFeedbackCalibration.assign(ptr+2*416, ptr+3*416);
462 }
463
464 void HandleFeedbackDeviation(const DimData &d)
465 {
466 if (!CheckDataSize(d, "Feedback:Deviation", 2*4*416+8))
467 return;
468
469 const float *ptr = d.ptr<float>();
470 vector<float> dev(ptr+416, ptr+416+320);
471
472 fFeedbackTempOffset = ptr[2*416];
473 fFeedbackUserOffset = ptr[2*416+1];
474
475 for (int i=0; i<320; i++)
476 dev[i] -= fFeedbackTempOffset+fFeedbackUserOffset;
477
478 // Write the 160 patch values to a file
479 WriteBinary(d, "feedback-deviation", dev, 1);
480
481 const Statistics stat(dev, 3);
482
483 ostringstream out;
484 out << d.time.JavaDate() << '\n';
485 out << kHtmlWhite << '\t' << fFeedbackUserOffset << '\n';
486 out << setprecision(3);
487 out << kHtmlWhite << '\t' << fFeedbackTempOffset << '\n';
488 out << kHtmlWhite << '\t' << stat.min << '\n';
489 out << kHtmlWhite << '\t' << stat.med << '\n';
490 out << kHtmlWhite << '\t' << stat.avg << '\n';
491 out << kHtmlWhite << '\t' << stat.max << '\n';
492 ofstream(fPath+"/feedback.txt") << out.str();
493 }
494
495 void HandleBiasControlVoltage(const DimData &d)
496 {
497 if (!CheckDataSize(d, "BiasControl:Voltage", 1664))
498 {
499 fBiasControlVoltageVec.clear();
500 return;
501 }
502
503 fBiasControlVoltageVec.assign(d.ptr<float>(), d.ptr<float>()+320);
504
505 const Statistics stat(fBiasControlVoltageVec);
506
507 fBiasControlVoltageMed = stat.med;
508
509 vector<float> val(320, 0);
510 for (int i=0; i<320; i++)
511 {
512 const int idx = (fPixelMap.hv(i).hw()/9)*2+fPixelMap.hv(i).group();
513 val[idx] = fBiasControlVoltageVec[i];
514 }
515
516 if (fDimBiasControl.state()==BIAS::kVoltageOn)
517 WriteBinary(d, "biascontrol-voltage", val, 10, 65);
518 else
519 WriteBinary(d, "biascontrol-voltage", val, 75);
520
521 ostringstream out;
522 out << setprecision(3);
523 out << d.time.JavaDate() << '\n';
524 out << kHtmlWhite << '\t' << stat.min << '\n';
525 out << kHtmlWhite << '\t' << stat.med << '\n';
526 out << kHtmlWhite << '\t' << stat.avg << '\n';
527 out << kHtmlWhite << '\t' << stat.max << '\n';
528 ofstream(fPath+"/voltage.txt") << out.str();
529
530 }
531
532 void HandleBiasControlCurrent(const DimData &d)
533 {
534 if (!CheckDataSize(d, "BiasControl:Current", 832))
535 return;
536
537 // Convert dac counts to uA
538 vector<float> v(320);
539 for (int i=0; i<320; i++)
540 v[i] = d.ptr<uint16_t>()[i] * 5000./4096;
541
542 const bool cal = fFeedbackCalibration.size()>0 && fBiasControlVoltageVec.size()>0;
543
544 double power_tot = 0;
545 double power_apd = 0;
546
547 // 3900 Ohm/n + 1000 Ohm + 1100 Ohm (with n=4 or n=5)
548 const double R[2] = { 3075, 2870 };
549
550 // Calibrate the data (subtract offset)
551 if (cal)
552 for (int i=0; i<320; i++)
553 {
554 // Measued current minus leakage current (bias crate calibration)
555 v[i] -= fBiasControlVoltageVec[i]/fFeedbackCalibration[i]*1e6;
556
557 // Total power participated in the camera at the G-APD
558 // and the serial resistors (total voltage minus voltage
559 // drop at resistors in bias crate)
560 power_tot += v[i]*(fBiasControlVoltageVec[i] - 1100e-6*v[i])*1e-6;
561
562 // Group index (0 or 1) of the of the pixel (4 or 5 pixel patch)
563 const int g = fPixelMap.hv(i).group();
564
565 // Current per G-APD
566 v[i] /= g ? 5 : 4;
567
568 // Power consumption per G-APD
569 if (i!=66 && i!=191 && i!=193)
570 power_apd += v[i]*(fBiasControlVoltageVec[i]-R[g]*v[i]*1e-6)*1e-6;
571 }
572
573 // Divide by number of summed channels, concert to mW
574 power_apd /= 317e-3; // [mW]
575
576 if (power_tot<1e-3)
577 power_tot = 0;
578 if (power_apd<1e-3)
579 power_apd = 0;
580
581 // Get the maximum of each patch
582 vector<float> val(320, 0);
583 for (int i=0; i<320; i++)
584 {
585 const int idx = (fPixelMap.hv(i).hw()/9)*2+fPixelMap.hv(i).group();
586 val[idx] = v[i];
587 }
588
589 // Write the 160 patch values to a file
590 WriteBinary(d, "biascontrol-current", val, 100);
591
592 const Statistics stat(v, 0, 3);
593
594 // Exclude the three crazy channels
595 fBiasControlCurrentMed = stat.med;
596 fBiasControlCurrentMax = stat.max;
597
598 // Store a history of the last 60 entries
599 fBiasControlCurrentHist.push_back(fBiasControlCurrentMed);
600 if (fBiasControlCurrentHist.size()>360)
601 fBiasControlCurrentHist.pop_front();
602
603 // write the history to a file
604 WriteBinary(d, "biascontrol-current-hist", fBiasControlCurrentHist, 100);
605
606 const string col0 = cal ? kHtmlGreen : kHtmlWhite;
607
608 string col1 = col0;
609 string col2 = col0;
610 string col3 = col0;
611 string col4 = col0;
612
613 if (cal && stat.min>65)
614 col1 = kYellow;
615 if (cal && stat.min>80)
616 col1 = kRed;
617
618 if (cal && stat.med>65)
619 col2 = kYellow;
620 if (cal && stat.med>80)
621 col2 = kRed;
622
623 if (cal && stat.avg>65)
624 col3 = kYellow;
625 if (cal && stat.avg>80)
626 col3 = kRed;
627
628 if (cal && stat.max>65)
629 col4 = kYellow;
630 if (cal && stat.max>80)
631 col4 = kRed;
632
633 ostringstream out;
634 out << setprecision(2);
635 out << d.time.JavaDate() << '\n';
636 out << col0 << '\t' << (cal?"yes":"no") << '\n';
637 out << col1 << '\t' << stat.min << '\n';
638 out << col2 << '\t' << stat.med << '\n';
639 out << col3 << '\t' << stat.avg << '\n';
640 out << col4 << '\t' << stat.max << '\n';
641 out << kHtmlWhite << '\t' << power_tot << "W [" << power_apd << "mW]\n";
642 ofstream(fPath+"/current.txt") << out.str();
643 }
644
645 void HandleFadEvents(const DimData &d)
646 {
647 if (!CheckDataSize(d, "FadControl:Events", 4*4))
648 {
649 fFadControlNumEvents = -1;
650 return;
651 }
652
653 fFadControlNumEvents = d.get<uint32_t>();
654 }
655
656 void HandleFadConnections(const DimData &d)
657 {
658 if (!CheckDataSize(d, "FadControl:Connections", 41))
659 {
660 //fStatusEventBuilderLabel->setText("Offline");
661 return;
662 }
663
664 string rc(40, '-'); // orange/red [45]
665
666 const uint8_t *ptr = d.ptr<uint8_t>();
667
668 int c[4] = { '.', '.', '.', '.' };
669
670 for (int i=0; i<40; i++)
671 {
672 const uint8_t stat1 = ptr[i]&3;
673 const uint8_t stat2 = ptr[i]>>3;
674
675 if (stat1==0 && stat2==0)
676 rc[i] = '.'; // gray [46]
677 else
678 if (stat1>=2 && stat2==8)
679 rc[i] = stat1==2?'+':'*'; // green [43] : check [42]
680
681 if (rc[i]<c[i/10])
682 c[i/10] = rc[i];
683 }
684
685 string col[4];
686 for (int i=0; i<4; i++)
687 switch (c[i])
688 {
689 case '.': col[i]=kHtmlWhite; break;
690 case '-': col[i]=kHtmlRed; break;
691 case '+': col[i]=kHtmlYellow; break;
692 case '*': col[i]=kHtmlGreen; break;
693 }
694
695 ostringstream out;
696 out << setprecision(3);
697 out << d.time.JavaDate() << '\n';
698 out << col[0] << '\t' << rc.substr( 0, 10) << '\n';
699 out << col[1] << '\t' << rc.substr(10, 10) << '\n';
700 out << col[2] << '\t' << rc.substr(20, 10) << '\n';
701 out << col[3] << '\t' << rc.substr(30, 10) << '\n';
702 ofstream(fPath+"/fad.txt") << out.str();
703 }
704
705 void HandleFtmControlTriggerRates(const DimData &d)
706 {
707 if (!CheckDataSize(d, "FtmControl:TriggerRates", 24+160+640+8))
708 return;
709
710 // New run started
711 if (d.get<float>(20)<0)
712 return;
713
714 fFtmControlTriggerRateCam = d.get<float>(20);
715
716 const float *brates = d.ptr<float>(24); // Board rate
717 const float *prates = d.ptr<float>(24+160); // Patch rate
718
719 // Store a history of the last 60 entries
720 fFtmControlTriggerRateHist.push_back(fFtmControlTriggerRateCam);
721 if (fFtmControlTriggerRateHist.size()>60)
722 fFtmControlTriggerRateHist.pop_front();
723
724 // FIXME: Add statistics for all kind of rates
725
726 WriteBinary(d, "ftmcontrol-triggerrate-hist",
727 fFtmControlTriggerRateHist, 100);
728 WriteBinary(d, "ftmcontrol-boardrates",
729 vector<float>(brates, brates+40), 10);
730 WriteBinary(d, "ftmcontrol-patchrates",
731 vector<float>(prates, prates+160), 10);
732
733 ostringstream out;
734 out << setprecision(3);
735 out << d.time.JavaDate() << '\n';
736 out << "#ffffff\t" << fFtmControlTriggerRateCam << '\n';
737
738 ofstream(fPath+"/trigger.txt") << out.str();
739
740 const Statistics bstat(vector<float>(brates, brates+40));
741 const Statistics pstat(vector<float>(prates, prates+160));
742
743 out.str("");
744 out << d.time.JavaDate() << '\n';
745 out << kHtmlWhite << '\t' << bstat.min << '\n';
746 out << kHtmlWhite << '\t' << bstat.med << '\n';
747 out << kHtmlWhite << '\t' << bstat.avg << '\n';
748 out << kHtmlWhite << '\t' << bstat.max << '\n';
749 ofstream(fPath+"/boardrates.txt") << out.str();
750
751 out.str("");
752 out << d.time.JavaDate() << '\n';
753 out << kHtmlWhite << '\t' << pstat.min << '\n';
754 out << kHtmlWhite << '\t' << pstat.med << '\n';
755 out << kHtmlWhite << '\t' << pstat.avg << '\n';
756 out << kHtmlWhite << '\t' << pstat.max << '\n';
757 ofstream(fPath+"/patchrates.txt") << out.str();
758 }
759
760 void HandleFtmControlStaticData(const DimData &d)
761 {
762 if (!CheckDataSize(d, "FtmControl:StaticData", 740))
763 return;
764
765 const uint16_t *ptr = d.ptr<uint16_t>(260);
766 vector<uint16_t> vec(ptr, ptr+160);
767
768 WriteBinary(d, "ftmcontrol-thresholds", vec, 1000);
769
770 const Statistics stat(vec);
771
772 ostringstream out;
773 out << d.time.JavaDate() << '\n';
774 out << kHtmlWhite << '\t' << stat.min << '\n';
775 out << kHtmlWhite << '\t' << stat.med << '\n';
776 out << kHtmlWhite << '\t' << stat.avg << '\n';
777 out << kHtmlWhite << '\t' << stat.max << '\n';
778 ofstream(fPath+"/thresholds.txt") << out.str();
779 }
780
781 void HandleFadControlEventData(const DimData &d)
782 {
783 if (!CheckDataSize(d, "FadControl:EventData", 23040))
784 return;
785
786 //const float *avg = d.ptr<float>();
787 //const float *rms = d.ptr<float>(1440*sizeof(float));
788 const float *dat = d.ptr<float>(1440*sizeof(float)*2);
789 //const float *pos = d.ptr<float>(1440*sizeof(float)*3);
790
791 vector<float> max(320, -2);
792 for (int i=0; i<1440; i++)
793 {
794 if (i%9==8)
795 continue;
796
797 const int idx = (fPixelMap.hw(i).hw()/9)*2+fPixelMap.hw(i).group();
798 const double v = dat[i]/1000;
799 if (v>max[idx])
800 max[idx]=v;
801 }
802
803 switch (d.qos)
804 {
805 case 0: WriteBinary(d, "fadcontrol-eventdata", max, 2, -1); break;
806 case 1: WriteBinary(d, "fadcontrol-eventdata", max, 2, 0); break;
807 default: WriteBinary(d, "fadcontrol-eventdata", max, 0.25, 0); break;
808 }
809 }
810
811 void HandleFscControlTemperature(const DimData &d)
812 {
813 if (!CheckDataSize(d, "FscControl:Temperature", 240))
814 return;
815
816 const float *ptr = d.ptr<float>(4);
817
818 double avg = 0;
819 double rms = 0;
820 double min = 99;
821 double max = -99;
822
823 int num = 0;
824 for (const float *t=ptr; t<ptr+31; t++)
825 {
826 if (*t==0)
827 continue;
828
829 if (*t>max)
830 max = *t;
831
832 if (*t<min)
833 min = *t;
834
835 avg += *t;
836 rms += *t * *t;
837
838 num++;
839 }
840
841 avg /= num;
842 rms = sqrt(rms/num-avg*avg);
843
844 fFscControlTemperatureAvg = avg;
845
846 fFscControlTemperatureHist.push_back(avg);
847 if (fFscControlTemperatureHist.size()>300)
848 fFscControlTemperatureHist.pop_front();
849
850 const Statistics stat(fFscControlTemperatureHist);
851
852 ostringstream out;
853 out << setprecision(3);
854 out << d.time.JavaDate() << '\n';
855 out << "#ffffff\t" << min << '\n';
856 out << "#ffffff\t" << avg << '\n';
857 out << "#ffffff\t" << max << '\n';
858 out << "#ffffff\t" << stat.min << '\n';
859 out << "#ffffff\t" << stat.avg << '\n';
860 out << "#ffffff\t" << stat.max << '\n';
861
862 ofstream(fPath+"/fsc.txt") << out.str();
863
864 WriteBinary(d, "fsccontrol-temperature-hist",
865 fFscControlTemperatureHist, 30);
866 }
867
868 void HandleFscControlHumidity(const DimData &d)
869 {
870 if (!CheckDataSize(d, "FscControl:Humidity", 5*4))
871 return;
872
873 const float *ptr = d.ptr<float>(4);
874
875 double avg = 0;
876 int num = 0;
877
878 for (const float *t=ptr; t<ptr+4; t++)
879 if (*t>0)
880 {
881 avg += *t;
882 num++;
883 }
884
885 fFscControlHumidityAvg = avg/num;
886 }
887
888 void HandleRateScanData(const DimData &d)
889 {
890 if (!CheckDataSize(d, "RateScan:Data", 824))
891 return;
892
893 const uint64_t id = d.get<uint64_t>();
894 const float rate = log10(d.get<float>(20));
895
896 if (fRateScanDataId!=id)
897 {
898 fRateScanDataHist.clear();
899 fRateScanDataId = id;
900 }
901 fRateScanDataHist.push_back(rate);
902
903 WriteBinary(d, "ratescan-hist", fRateScanDataHist, 10, -2);
904 }
905
906 // -------------------------------------------------------------------
907
908 void infoHandler()
909 {
910 DimInfo *curr = getInfo(); // get current DimInfo address
911 if (!curr)
912 return;
913
914 if (HandleService(curr, fDimMcpConfiguration, &StateMachineSmartFACT::HandleMcpConfiguration))
915 return;
916 if (HandleService(curr, fDimMagicWeatherData, &StateMachineSmartFACT::HandleMagicWeatherData))
917 return;
918 if (HandleService(curr, fDimDriveControlPointing, &StateMachineSmartFACT::HandleDriveControlPointing))
919 return;
920 if (HandleService(curr, fDimDriveControlTracking, &StateMachineSmartFACT::HandleDriveControlTracking))
921 return;
922 if (HandleService(curr, fDimDriveControlSource, &StateMachineSmartFACT::HandleDriveControlSource))
923 return;
924 if (HandleService(curr, fDimFeedbackDeviation, &StateMachineSmartFACT::HandleFeedbackDeviation))
925 return;
926 if (HandleService(curr, fDimFeedbackCalibration, &StateMachineSmartFACT::HandleFeedbackCalibration))
927 return;
928 if (HandleService(curr, fDimBiasControlVoltage, &StateMachineSmartFACT::HandleBiasControlVoltage))
929 return;
930 if (HandleService(curr, fDimBiasControlCurrent, &StateMachineSmartFACT::HandleBiasControlCurrent))
931 return;
932 if (HandleService(curr, fDimFadConnections, &StateMachineSmartFACT::HandleFadConnections))
933 return;
934 if (HandleService(curr, fDimFadEvents, &StateMachineSmartFACT::HandleFadEvents))
935 return;
936 if (HandleService(curr, fDimFtmControlTriggerRates, &StateMachineSmartFACT::HandleFtmControlTriggerRates))
937 return;
938 if (HandleService(curr, fDimFtmControlStaticData, &StateMachineSmartFACT::HandleFtmControlStaticData))
939 return;
940 if (HandleService(curr, *fDimFadControlEventData, &StateMachineSmartFACT::HandleFadControlEventData))
941 return;
942 if (HandleService(curr, fDimFscControlTemperature, &StateMachineSmartFACT::HandleFscControlTemperature))
943 return;
944 if (HandleService(curr, fDimFscControlHumidity, &StateMachineSmartFACT::HandleFscControlHumidity))
945 return;
946 if (HandleService(curr, fDimRateScanData, &StateMachineSmartFACT::HandleRateScanData))
947 return;
948 }
949
950 bool CheckEventSize(size_t has, const char *name, size_t size)
951 {
952 if (has==size)
953 return true;
954
955 ostringstream msg;
956 msg << name << " - Received event has " << has << " bytes, but expected " << size << ".";
957 Fatal(msg);
958 return false;
959 }
960
961 void PrintState(const DimState &state) const
962 {
963 const State rc = GetState(state);
964
965 Out() << state.time().GetAsStr("%H:%M:%S.%f").substr(0, 12) << " - ";
966 Out() << kBold << state.name() << ": ";
967 if (rc.index==-3)
968 {
969 Out() << kReset << "Offline" << endl;
970 return;
971 }
972 if (rc.index==-2)
973 Out() << state.state();
974 else
975 Out() << rc.name << "[" << rc.index << "]";
976 Out() << kReset << " - " << kBlue << rc.comment << endl;
977 }
978
979 int Print() const
980 {
981 Out() << fDim.time().GetAsStr("%H:%M:%S.%f").substr(0, 12) << " - ";
982 Out() << kBold << "DIM_DNS: " << fDim.version() << endl;
983
984 PrintState(fDimMcp);
985 PrintState(fDimControl);
986 PrintState(fDimDataLogger);
987 PrintState(fDimDriveControl);
988 PrintState(fDimFadControl);
989 PrintState(fDimFtmControl);
990 PrintState(fDimBiasControl);
991 PrintState(fDimFeedback);
992 PrintState(fDimRateControl);
993 PrintState(fDimFscControl);
994 PrintState(fDimMagicWeather);
995 PrintState(fDimRateScan);
996 PrintState(fDimChatServer);
997
998 return GetCurrentState();
999 }
1000
1001 string GetStateHtml(const DimState &state, int green) const
1002 {
1003 if (!state.online())
1004 return kHtmlWhite+"\t&mdash;\n";
1005
1006 if (&state==&fDimControl)
1007 {
1008 ostringstream out;
1009 out << kHtmlGreen << '\t';
1010 return kHtmlGreen+'\t'+(state.state()==-3?"Idle":state.msg)+'\n';
1011 }
1012
1013 const State rc = GetState(state);
1014
1015 // Sate not found in list, server online (-3: offline; -2: not found)
1016 if (rc.index==-2)
1017 {
1018 ostringstream out;
1019 out << kHtmlWhite << '\t' << state.state() << '\n';
1020 return out.str();
1021 }
1022
1023 //ostringstream msg;
1024 //msg << kHtmlWhite << '\t' << rc.name << " [" << rc.index << "]\n";
1025 //return msg.str();
1026
1027 if (rc.index<1)
1028 return kHtmlWhite + "\t&mdash;\n";
1029
1030
1031 return (rc.index<green?kHtmlYellow:kHtmlGreen) + '\t' + rc.name + '\n';
1032 }
1033
1034 int Execute()
1035 {
1036 // Dispatch (execute) at most one handler from the queue. In contrary
1037 // to run_one(), it doesn't wait until a handler is available
1038 // which can be dispatched, so poll_one() might return with 0
1039 // handlers dispatched. The handlers are always dispatched/executed
1040 // synchronously, i.e. within the call to poll_one()
1041 //poll_one();
1042
1043 if (fDim.state()==0)
1044 return kStateDimNetworkNA;
1045
1046 Time now;
1047 if (now-fLastUpdate<boost::posix_time::seconds(1))
1048 return kStateRunning;
1049
1050 fLastUpdate=now;
1051
1052 ostringstream out;
1053 out << now.JavaDate() << '\t' << fDimControl.online() << '\n';
1054 out << setprecision(3);
1055
1056 // -------------- System status --------------
1057 if (fDimMcp.state()>=5) // Idle
1058 {
1059 string col = kHtmlBlue;
1060 if (fMcpConfigurationState!= 5 && // Idle
1061 fMcpConfigurationState!=11 && // Trigger On
1062 fMcpConfigurationState!=12) // Taking Data
1063 col = kHtmlYellow;
1064 else
1065 if (fDimFadControl.state()==FAD::kWritingData)
1066 col = kHtmlGreen;
1067
1068 out << col << '\t';
1069
1070 if (fMcpConfigurationState!=5 &&
1071 fMcpConfigurationState!=11 &&
1072 fMcpConfigurationState!=12)
1073 out << "Configuring ";
1074 out << fMcpConfigurationName;
1075
1076 if (fDimRateControl.state()==5/*kStateSettingGlobalThreshold*/)
1077 out << "Calibrating threshold";
1078
1079 if (fDimRateScan.state()==5/*kStateSettingGlobalThreshold*/)
1080 out << "Rate scan in progress";
1081
1082 if (fDimMcp.state()>5 && fDimRateControl.state()!=5)
1083 {
1084 if (fMcpConfigurationMaxEvents>0 || fMcpConfigurationMaxTime>0 || fMcpConfigurationState==12)
1085 out << " [";
1086 if (fMcpConfigurationMaxEvents>0)
1087 {
1088 if (fFadControlNumEvents>0 && fMcpConfigurationState==12)
1089 out << fMcpConfigurationMaxEvents-fFadControlNumEvents;
1090 else
1091 out << fMcpConfigurationMaxEvents;
1092 }
1093 if (fMcpConfigurationMaxEvents>0 && (fMcpConfigurationMaxTime>0 || fMcpConfigurationState==12))
1094 out << '/';
1095 if (fMcpConfigurationMaxTime>0)
1096 {
1097 if (fMcpConfigurationState==12)
1098 {
1099
1100 const uint32_t dt = (Time()-fMcpConfigurationRunStart).total_seconds();
1101 if (dt>fMcpConfigurationMaxTime)
1102 out << "---";
1103 else
1104 out << fMcpConfigurationMaxTime-dt << 's';
1105 }
1106 else
1107 out << fMcpConfigurationMaxTime << 's';
1108 }
1109 else
1110 {
1111 if (fMcpConfigurationState==12)
1112 {
1113 ostringstream d;
1114 d << Time()-fMcpConfigurationRunStart;
1115 out << d.str().substr(3, 5);
1116 }
1117 }
1118
1119 if (fMcpConfigurationMaxEvents>0 || fMcpConfigurationMaxTime>0 || fMcpConfigurationState==12)
1120 out << ']';
1121 }
1122 }
1123 else
1124 out << kHtmlWhite;
1125 out << '\n';
1126
1127 // ------------------ Drive -----------------
1128 if (fDimDriveControl.state()>=5) // Armed, Moving, Tracking
1129 {
1130 const State rc = GetState(fDimDriveControl);
1131 string col = kHtmlGreen;
1132 if (rc.index==6) // Moving
1133 col = kHtmlBlue;
1134 if (rc.index==5) // Armed
1135 col = kHtmlWhite;
1136 if (rc.index==7) // Tracking
1137 {
1138 if (fDriveControlTrackingDev>60) // ~1.5mm
1139 col = kHtmlYellow;
1140 if (fDriveControlTrackingDev>100) // ~1/4 of a pixel ~ 2.5mm
1141 col = kHtmlRed;
1142 }
1143 out << col << '\t';
1144
1145 //out << rc.name << '\t';
1146 out << fDriveControlPointingZd << '\t';
1147 out << fDriveControlPointingAz << '\t';
1148 if (fDimDriveControl.state()==7)
1149 {
1150 out << fDriveControlSourceName << '\t';
1151 out << setprecision(2);
1152 out << fDriveControlTrackingDev << '\n';
1153 out << setprecision(3);
1154 }
1155 else
1156 out << "\t\n";
1157 }
1158 else
1159 out << kHtmlWhite << '\n';
1160
1161 // ------------------- FSC ------------------
1162 if (fDimFscControl.state()>1)
1163 {
1164 out << kHtmlGreen << '\t' << fFscControlTemperatureAvg << '\n';
1165 }
1166 else
1167 out << kHtmlWhite << '\n';
1168
1169 // --------------- MagicWeather -------------
1170 if (fDimMagicWeather.state()==3 && fMagicWeatherHist[kWeatherBegin].size()>0)
1171 {
1172 /*
1173 const float diff = fMagicWeatherHist[kTemp].back()-fMagicWeatherHist[kDew].back();
1174 string col1 = kHtmlRed;
1175 if (diff>0.3)
1176 col1 = kHtmlYellow;
1177 if (diff>0.7)
1178 col1 = kHtmlGreen;
1179 */
1180
1181 const float wind = fMagicWeatherHist[kGusts].back();
1182 const float hum = fMagicWeatherHist[kHum].back();
1183 string col = kHtmlGreen;
1184 if (wind>35 || hum>95)
1185 col = kHtmlYellow;
1186 if (wind>50 || hum>98)
1187 col = kHtmlRed;
1188
1189 out << col << '\t';
1190 out << fMagicWeatherHist[kHum].back() << '\t';
1191 out << setprecision(2);
1192 out << fMagicWeatherHist[kGusts].back() << '\n';
1193 out << setprecision(3);
1194 }
1195 else
1196 out << kHtmlWhite << "\n";
1197
1198 // --------------- FtmControl -------------
1199 if (fDimFtmControl.state()==FTM::kTriggerOn)
1200 {
1201 string col = kHtmlGreen;
1202 if (fFtmControlTriggerRateCam<15)
1203 col = kHtmlYellow;
1204 if (fFtmControlTriggerRateCam>100)
1205 col = kHtmlRed;
1206
1207 out << col << '\t' << fFtmControlTriggerRateCam << '\n';
1208 }
1209 else
1210 out << kHtmlWhite << '\n';
1211
1212 // --------------- BiasControl -------------
1213 if (fDimBiasControl.state()==BIAS::kRamping ||
1214 fDimBiasControl.state()==BIAS::kOverCurrent ||
1215 fDimBiasControl.state()==BIAS::kVoltageOn ||
1216 fDimBiasControl.state()==BIAS::kVoltageOff)
1217 {
1218 const bool off = fDimBiasControl.state()==BIAS::kVoltageOff;
1219 const bool oc = fDimBiasControl.state()==BIAS::kOverCurrent;
1220
1221 string col = fBiasControlVoltageMed>3?kHtmlGreen:kHtmlWhite;
1222 if (fBiasControlCurrentMax>65)
1223 col = kHtmlYellow;
1224 if (fBiasControlCurrentMax>80)
1225 col = kHtmlRed;
1226
1227 // Bias in overcurrent => Red
1228 if (fDimBiasControl.state()==BIAS::kOverCurrent)
1229 col = kHtmlRed;
1230
1231 // MCP in ReadyForDatataking/Configuring/Configured/TriggerOn/TakingData
1232 // and Bias not in "data-taking state' => Red
1233 if (fDimMcp.state()>5 &&
1234 fDimBiasControl.state()!=BIAS::kVoltageOn &&
1235 fDimBiasControl.state()!=BIAS::kVoltageOff)
1236 col = kHtmlRed;
1237
1238 const bool cal = fFeedbackCalibration.size();
1239
1240 // Feedback is currently calibrating => Blue
1241 if (fDimFeedback.state()==13)
1242 {
1243 out << kHtmlBlue << '\t';
1244 out << "***\t";
1245 out << "***\t";
1246 }
1247 else
1248 {
1249 out << setprecision(2);
1250 out << col << '\t';
1251 out << (off ? 0 : fBiasControlCurrentMed) << '\t';
1252 if (oc)
1253 out << "(OC) ";
1254 else
1255 {
1256 if (cal)
1257 out << (off ? 0 : fBiasControlCurrentMax);
1258 else
1259 out << "&mdash; ";
1260 }
1261 out << '\t';
1262 out << setprecision(3);
1263 }
1264 out << (off ? 0 : fBiasControlVoltageMed) << '\n';
1265 }
1266 else
1267 out << kHtmlWhite << '\n';
1268
1269
1270 // ------------------------------------------
1271
1272 ofstream(fPath+"/fact.txt") << out.str();
1273
1274 // ==========================================
1275
1276 out.str("");
1277 out << now.JavaDate() << '\t' << fDimControl.online() << '\n';
1278
1279 if (fDim.state()==0)
1280 out << kHtmlWhite << "\tOffline\n\n\n\n\n\n\n\n\n\n\n\n";
1281 else
1282 {
1283 out << kHtmlGreen << '\t' << fDim.version() << '\n';
1284
1285 out << GetStateHtml(fDimMcp, 4);
1286 out << GetStateHtml(fDimControl, 0);
1287 out << GetStateHtml(fDimDataLogger, 1);
1288 out << GetStateHtml(fDimDriveControl, 2);
1289 out << GetStateHtml(fDimFadControl, FAD::kConnected);
1290 out << GetStateHtml(fDimFtmControl, FTM::kConnected);
1291 out << GetStateHtml(fDimBiasControl, BIAS::kConnected);
1292 out << GetStateHtml(fDimFeedback, 4);
1293 out << GetStateHtml(fDimRateControl, 4);
1294 out << GetStateHtml(fDimFscControl, 2);
1295 out << GetStateHtml(fDimMagicWeather, 2);
1296 out << GetStateHtml(fDimRateScan, 4);
1297 out << GetStateHtml(fDimChatServer, 1);
1298 }
1299
1300 ofstream(fPath+"/status.txt") << out.str();
1301
1302 return kStateRunning;
1303 }
1304
1305public:
1306 StateMachineSmartFACT(ostream &out=cout) : StateMachineDim(out, "SMART_FACT"),
1307 fPath("www/smartfact/data"),
1308 fMcpConfigurationMaxTime(0),
1309 fMcpConfigurationMaxEvents(0),
1310 fRateScanDataId(0),
1311 //---
1312 fDimMcp ("MCP"),
1313 fDimControl ("DIM_CONTROL"),
1314 fDimDataLogger ("DATA_LOGGER"),
1315 fDimDriveControl ("DRIVE_CONTROL"),
1316 fDimMagicWeather ("MAGIC_WEATHER"),
1317 fDimFeedback ("FEEDBACK"),
1318 fDimBiasControl ("BIAS_CONTROL"),
1319 fDimFtmControl ("FTM_CONTROL"),
1320 fDimFadControl ("FAD_CONTROL"),
1321 fDimFscControl ("FSC_CONTROL"),
1322 fDimRateControl ("RATE_CONTROL"),
1323 fDimRateScan ("RATE_SCAN"),
1324 fDimChatServer ("CHAT_SERVER"),
1325 //---
1326 fDimMcpConfiguration ("MCP/CONFIGURATION", (void*)NULL, 0, this),
1327 //---
1328 fDimDriveControlPointing ("DRIVE_CONTROL/POINTING_POSITION", (void*)NULL, 0, this),
1329 fDimDriveControlTracking ("DRIVE_CONTROL/TRACKING_POSITION", (void*)NULL, 0, this),
1330 fDimDriveControlSource ("DRIVE_CONTROL/SOURCE_POSITION", (void*)NULL, 0, this),
1331 //---
1332 fDimFscControlTemperature ("FSC_CONTROL/TEMPERATURE", (void*)NULL, 0, this),
1333 fDimFscControlHumidity ("FSC_CONTROL/HUMIDITY", (void*)NULL, 0, this),
1334 //---
1335 fDimMagicWeatherData ("MAGIC_WEATHER/DATA", (void*)NULL, 0, this),
1336 //---
1337 fDimFeedbackDeviation ("FEEDBACK/DEVIATION", (void*)NULL, 0, this),
1338 fDimFeedbackCalibration ("FEEDBACK/CALIBRATION", (void*)NULL, 0, this),
1339 //---
1340 fDimBiasControlVoltage ("BIAS_CONTROL/VOLTAGE", (void*)NULL, 0, this),
1341 fDimBiasControlCurrent ("BIAS_CONTROL/CURRENT", (void*)NULL, 0, this),
1342 //---
1343 fDimFadConnections ("FAD_CONTROL/CONNECTIONS", (void*)NULL, 0, this),
1344 fDimFadEvents ("FAD_CONTROL/EVENTS", (void*)NULL, 0, this),
1345 //---
1346 fDimFtmControlTriggerRates("FTM_CONTROL/TRIGGER_RATES", (void*)NULL, 0, this),
1347 fDimFtmControlStaticData ("FTM_CONTROL/STATIC_DATA", (void*)NULL, 0, this),
1348 //-
1349 fDimRateScanData ("RATE_SCAN/DATA", (void*)NULL, 0, this),
1350 //-
1351 fDimFadControlEventData(0)
1352 {
1353 // State names
1354 AddStateName(kStateDimNetworkNA, "DimNetworkNotAvailable",
1355 "The Dim DNS is not reachable.");
1356
1357 AddStateName(kStateRunning, "Running", "");
1358
1359 // Verbosity commands
1360// AddEvent("SET_VERBOSE", "B:1")
1361// (bind(&StateMachineMCP::SetVerbosity, this, placeholders::_1))
1362// ("set verbosity state"
1363// "|verbosity[bool]:disable or enable verbosity for received data (yes/no), except dynamic data");
1364
1365 AddEvent("PRINT")
1366 (bind(&StateMachineSmartFACT::Print, this))
1367 ("");
1368 }
1369 ~StateMachineSmartFACT()
1370 {
1371 delete fDimFadControlEventData;
1372 }
1373 int EvalOptions(Configuration &conf)
1374 {
1375 if (!fPixelMap.Read(conf.Get<string>("pixel-map-file")))
1376 {
1377 Error("Reading mapping table from "+conf.Get<string>("pixel-map-file")+" failed.");
1378 return 1;
1379 }
1380
1381 // First move all the dim services to another class so that
1382 // they can be instatiated all at once _after_ path was set
1383 //fPath = conf.Get<string>("path");
1384
1385 // Pixel map is needed to deal with this service
1386 fDimFadControlEventData=new DimStampedInfo("FAD_CONTROL/EVENT_DATA", (void*)NULL, 0, this);
1387
1388 return -1;
1389 }
1390};
1391
1392// ------------------------------------------------------------------------
1393
1394#include "Main.h"
1395
1396template<class T>
1397int RunShell(Configuration &conf)
1398{
1399 return Main::execute<T, StateMachineSmartFACT>(conf);
1400}
1401
1402void SetupConfiguration(Configuration &conf)
1403{
1404 po::options_description control("Smart FACT");
1405 control.add_options()
1406 ("pixel-map-file", var<string>("FACTmapV5a.txt"), "Pixel mapping file. Used here to get the default reference voltage")
1407 ("path", var<string>("www/smartfact/data"), "Output path for the data-files")
1408 ;
1409
1410 conf.AddOptions(control);
1411}
1412
1413/*
1414 Extract usage clause(s) [if any] for SYNOPSIS.
1415 Translators: "Usage" and "or" here are patterns (regular expressions) which
1416 are used to match the usage synopsis in program output. An example from cp
1417 (GNU coreutils) which contains both strings:
1418 Usage: cp [OPTION]... [-T] SOURCE DEST
1419 or: cp [OPTION]... SOURCE... DIRECTORY
1420 or: cp [OPTION]... -t DIRECTORY SOURCE...
1421 */
1422void PrintUsage()
1423{
1424 cout <<
1425 "SmartFACT is a tool writing the files needed for the SmartFACT web interface.\n"
1426 "\n"
1427 "The default is that the program is started without user intercation. "
1428 "All actions are supposed to arrive as DimCommands. Using the -c "
1429 "option, a local shell can be initialized. With h or help a short "
1430 "help message about the usuage can be brought to the screen.\n"
1431 "\n"
1432 "Usage: smartfact [-c type] [OPTIONS]\n"
1433 " or: smartfact [OPTIONS]\n";
1434 cout << endl;
1435}
1436
1437void PrintHelp()
1438{
1439 Main::PrintHelp<StateMachineSmartFACT>();
1440
1441 /* Additional help text which is printed after the configuration
1442 options goes here */
1443
1444 /*
1445 cout << "bla bla bla" << endl << endl;
1446 cout << endl;
1447 cout << "Environment:" << endl;
1448 cout << "environment" << endl;
1449 cout << endl;
1450 cout << "Examples:" << endl;
1451 cout << "test exam" << endl;
1452 cout << endl;
1453 cout << "Files:" << endl;
1454 cout << "files" << endl;
1455 cout << endl;
1456 */
1457}
1458
1459int main(int argc, const char* argv[])
1460{
1461 Configuration conf(argv[0]);
1462 conf.SetPrintUsage(PrintUsage);
1463 Main::SetupConfiguration(conf);
1464 SetupConfiguration(conf);
1465
1466 if (!conf.DoParse(argc, argv, PrintHelp))
1467 return -1;
1468
1469 //try
1470 {
1471 // No console access at all
1472 if (!conf.Has("console"))
1473 {
1474// if (conf.Get<bool>("no-dim"))
1475// return RunShell<LocalStream, StateMachine, ConnectionFSC>(conf);
1476// else
1477 return RunShell<LocalStream>(conf);
1478 }
1479 // Cosole access w/ and w/o Dim
1480/* if (conf.Get<bool>("no-dim"))
1481 {
1482 if (conf.Get<int>("console")==0)
1483 return RunShell<LocalShell, StateMachine, ConnectionFSC>(conf);
1484 else
1485 return RunShell<LocalConsole, StateMachine, ConnectionFSC>(conf);
1486 }
1487 else
1488*/ {
1489 if (conf.Get<int>("console")==0)
1490 return RunShell<LocalShell>(conf);
1491 else
1492 return RunShell<LocalConsole>(conf);
1493 }
1494 }
1495 /*catch (std::exception& e)
1496 {
1497 cerr << "Exception: " << e.what() << endl;
1498 return -1;
1499 }*/
1500
1501 return 0;
1502}
Note: See TracBrowser for help on using the repository browser.