46 vector<float> fCalibCurrentMes[6];
47 vector<float> fCalibVoltage[6];
93 Info(
"Starting calibration step "+to_string(fCalibStep));
99 return GetCurrentState();
113 msg << name <<
" - Received event has " << has <<
" bytes, but expected " << size <<
".";
125 for (
int i=0;
i<320;
i++)
128 Info(
"Nominal bias voltages and calibration resistor received.");
131 return GetCurrentState();
138 return GetCurrentState();
145 return GetCurrentState();
150 if (!CheckEventSize(evt.
GetSize(),
"HandleCameraTemp", 323*
sizeof(float)))
153 return GetCurrentState();
159 const float *ptr = evt.
Ptr<
float>(4);
162 fTemp = evt.
Get<
float>(321*4);
164 fTempOffsetAvg = (fTemp-25)*fTempCoefficient;
165 fTempOffsetRms = evt.
Get<
float>(322*4)*fTempCoefficient;
167 fTempOffset.resize(320);
168 for (
int i=0;
i<320;
i++)
169 fTempOffset[
i] = (ptr[
i]-25)*fTempCoefficient;
171 return GetCurrentState();
180 fCurrentsAvg[
i] += ptr[
i];
181 fCurrentsRms[
i] += ptr[
i]*ptr[
i];
186 return make_pair(vector<float>(), vector<float>());
188 const double conv = 5e-3/4096;
194 avg[
i] = double(fCurrentsAvg[
i])/fCursorCur * conv;
195 rms[
i] = double(fCurrentsRms[i])/fCursorCur * conv * conv;
196 rms[
i] -= avg[
i]*avg[
i];
197 rms[
i] = rms[
i]<0 ? 0 : sqrt(rms[i]);
200 return make_pair(avg, rms);
206 return GetCurrentState();
208 const uint16_t dac = 256+512*fCalibStep;
213 if (
std::count(fBiasDac.begin(), fBiasDac.end(), dac)!=319)
214 return GetCurrentState();
216 const auto rc = AverageCurrents(evt.
Ptr<int16_t>(), fNumCalibRequests);
217 if (rc.first.size()==0)
220 return GetCurrentState();
223 const vector<float> &avg = rc.first;
224 const vector<float> &rms = rc.second;
227 fCalibCurrentMes[fCalibStep] = avg;
228 fCalibVoltage[fCalibStep] = fBiasVolt;
239 cal_data() { memset(
this, 0,
sizeof(cal_data)); }
249 fDimCalibration2.
Update(fTimeCalib);
255 fCursorCur = -fNumCalibIgnore;
267 return GetCurrentState();
274 float *pavg = fCalibration.data();
281 const double I = fCalibCurrentMes[5][
i];
282 const double U = fBiasVolt[
i];
285 prms[
i] = rms[
i]*1e6;
290 fDimCalibration.
setData(fCalibration);
291 fDimCalibration.
Update(fTimeCalib);
295 fCalibDeltaI.resize(BIAS::kNumChannels);
296 fCalibR8.resize(BIAS::kNumChannels);
311 const int len = end-beg+1;
313 for (
int j=beg; j<=
end; j++)
315 const double Idac = (256+512*j)*1e-3/4096;
319 y += fCalibCurrentMes[j][
i];
320 xy += fCalibCurrentMes[j][
i]*Idac;
323 const double m1 = xy - x*y / len;
324 const double m2 = xx - x*x / len;
326 const double m = m2==0 ? 0 : m1/m2;
328 const double t = (y - m*x) / len;
335 v.reserve(BIAS::kNumChannels*2);
336 v.insert(v.end(), fCalibDeltaI.begin(), fCalibDeltaI.end());
337 v.insert(v.end(), fCalibR8.begin(), fCalibR8.end());
340 fDimCalibrationR8.
Update(fTimeCalib);
344 Info(
"Calibration successfully done.");
352 const float fAbsoluteMedianCurrentLimit = 85;
353 const float fRelativePixelCurrentLimit3 = 20;
354 const float fRelativePixelCurrentLimit0 = 45;
356 const float fAbsolutePixelCurrentLimit3 = fAbsoluteMedianCurrentLimit + fRelativePixelCurrentLimit3;
357 const float fAbsolutePixelCurrentLimit0 = fAbsoluteMedianCurrentLimit + fRelativePixelCurrentLimit0;
359 const float fRelativeCurrentLimitWarning = 10;
360 const float fRelativeCurrentLimitCritical = 15;
361 const float fRelativeCurrentLimitShutdown = 25;
363 fTimeoutCritical = 3000;
366 vector<float> v(I, I+320);
373 sort(v.begin(), v.end());
375 const float &imax0 = v[319];
376 const float &imax3 = v[316];
377 const float &imed = v[161];
379 const bool shutdown =
380 imed >fAbsoluteMedianCurrentLimit+fRelativeCurrentLimitShutdown ||
381 imax3>fAbsolutePixelCurrentLimit3+fRelativeCurrentLimitShutdown ||
382 imax0>fAbsolutePixelCurrentLimit0+fRelativeCurrentLimitShutdown;
384 const bool critical =
385 imed >fAbsoluteMedianCurrentLimit+fRelativeCurrentLimitCritical ||
386 imax3>fAbsolutePixelCurrentLimit3+fRelativeCurrentLimitCritical ||
387 imax0>fAbsolutePixelCurrentLimit0+fRelativeCurrentLimitCritical;
390 imed >fAbsoluteMedianCurrentLimit+fRelativeCurrentLimitWarning ||
391 imax3>fAbsolutePixelCurrentLimit3+fRelativeCurrentLimitWarning ||
392 imax0>fAbsolutePixelCurrentLimit0+fRelativeCurrentLimitWarning;
399 if (fVoltageReduction==0 &&
400 imed <fAbsoluteMedianCurrentLimit &&
401 imax3<fAbsolutePixelCurrentLimit3 &&
402 imax0<fAbsolutePixelCurrentLimit0)
411 if (!standby && shutdown)
419 Error(
"Current limit for shutdown exceeded.... switching to standby mode.");
425 if (!standby && critical)
431 Info(
"Critical current limit exceeded.... waiting for "+to_string(fTimeoutCritical)+
" ms.");
432 fTimeCritical =
Time();
437 if (
Time()<fTimeCritical+boost::posix_time::milliseconds(fTimeoutCritical))
444 Warn(
"Critical current limit exceeded timeout.... switching to standby mode.");
450 if (!standby && warning)
463 return GetCurrentState();
467 return HandleCalibration(evt);
473 (!fTimeTemp.
IsValid() ||
Time()-fTimeTemp>boost::posix_time::minutes(5)))
474 return GetCurrentState();
481 return GetCurrentState();
485 (!fTimeTemp.
IsValid() ||
Time()-fTimeTemp>boost::posix_time::minutes(5)))
487 Warn(
"Current control in progress, but last received temperature older than 5min... switching voltage off.");
496 const vector<float> &Imes = AverageCurrents(evt.
Ptr<int16_t>(), Navg).first;
498 return GetCurrentState();
507 static const array<int, 14> inner0 =
509 62, 63, 130, 131, 132, 133, 134,
510 135, 222, 223, 292, 293, 294, 295,
513 static const array<int, 23> inner1 =
515 58, 59, 60, 61, 129, 138, 139, 140, 141, 142, 143, 218,
516 219, 220, 221, 290, 291, 298, 299, 300, 301, 302, 303,
519 static const array<int, 43> inner2 =
521 42, 43, 44, 45, 55, 56, 57, 70, 71, 78, 79,
522 96, 97, 98, 99, 102, 103, 128, 136, 137, 159, 202,
523 203, 204, 205, 214, 216, 217, 228, 230, 231, 256, 257,
524 258, 259, 262, 263, 288, 289, 296, 297, 310, 318
532 double avg[2] = { 0, 0 };
533 double min[2] = { 90, 90 };
534 double max[2] = { -90, -90 };
535 int num[3] = { 0, 0, 0 };
537 vector<double> med[3];
555 dim_data() { memset(
this, 0,
sizeof(dim_data)); }
558 int Ndev[3] = { 0, 0, 0 };
562 data.Unom = voltageoffset;
563 data.dUtemp = fTempOffsetAvg;
575 for (
int i=0;
i<320;
i++)
584 (fMoonMode>0 && std::find(inner0.begin(), inner0.end(),
i)!=inner0.end()) ||
585 (fMoonMode>1 && std::find(inner1.begin(), inner1.end(),
i)!=inner1.end()) ||
586 (fMoonMode>2 && std::find(inner2.begin(), inner2.end(),
i)!=inner2.end()) ||
590 const int N = hv.
count();
595 const double adc = Imes[
i];
599 const double I8 = adc-fCalibDeltaI[
i];
604 const double I9 = fBiasDac[
i] * (1e-3/4096);
608 const double Iout = I8 - I9*100/fCalibR8[
i];
611 const double U9 = fBiasVolt[
i];
618 const double R4 = 2000;
621 double R5 = 3900./N + 50;
625 R5 = 1./((N-1)/3900.+1/1000.);
627 R5 = 1./((N-1)/3900.+1/390.);
638 const double R = R4 + R5 + R8;
653 const double Udrp = Iout<0 ? 0 : R*Iout;
656 const double Uop = fVoltGapd[
i] + fVoltOffset[
i] + fTempOffset[
i]
657 + (blocked ? -5 : 0);
661 const double Uov = (U9-Udrp)-Uop>-1.4 ? (U9-Udrp)-Uop : -1.4;
665 double Iapd = Iout/N;
716 Uop + voltageoffset + Udrp*exp(0.6*(voltageoffset-Uov))*pow((voltageoffset+1.4), 0.6) :
717 Uop + voltageoffset + Udrp*exp(0.6*(voltageoffset-Uov))*pow((voltageoffset+1.4)/(Uov+1.4), 0.6);
719 if (fabs(voltageoffset-Uov)>0.033)
721 if (fabs(voltageoffset-Uov)>0.022)
723 if (fabs(voltageoffset-Uov)>0.011)
729 const double iapd = Iapd*1e6;
736 const int g = hv.
group();
738 med[g][num[g]] = Uov;
748 data.Irms += iapd*iapd;
750 med[2][num[2]++] = iapd;
753 UdrpRms += Udrp*Udrp;
763 data.Irms -= data.Iavg*data.Iavg;
766 data.Irms = data.Irms<0 ? 0: sqrt(data.Irms);
769 sort(med[2].
data(), med[2].
data()+num[2]);
771 data.Imed = num[2]%2 ? med[2][num[2]/2] : (med[2][num[2]/2-1]+med[2][num[2]/2])/2;
774 for (
int i=0;
i<num[2];
i++)
775 med[2][
i] = fabs(med[2][
i]-data.Imed);
777 sort(med[2].
data(), med[2].
data()+num[2]);
779 data.Idev = med[2][uint32_t(0.682689477208650697*num[2])];
785 const double Uov = (avg[0]+avg[1])/(num[0]+num[1]);
789 int newstate = GetCurrentState();
795 newstate = CheckLimits(data.I);
802 float fAbsoluteMedianCurrentLimit = 85;
803 const double deltaU = (Uov+1.4)*(1-pow(fAbsoluteMedianCurrentLimit/data.Imed, 1./1.7));
805 if (fVoltageReduction+deltaU<0.033)
806 fVoltageReduction = 0;
809 fVoltageReduction += deltaU;
811 for (
int i=0;
i<320;
i++)
812 vec[
i] -= fVoltageReduction;
820 vec[263] = vec[262]-fVoltGapd[262]+fVoltGapd[263];
832 UdrpRms -= UdrpAvg*UdrpAvg;
833 UdrpRms = UdrpRms<0 ? 0 : sqrt(UdrpRms);
837 msg << setprecision(2) <<
"dU(" << fTemp <<
"degC)=" 838 << setprecision(3) << fTempOffsetAvg <<
"V+-" << fTempOffsetRms <<
" Udrp=" 839 << UdrpAvg <<
"V+-" << UdrpRms;
840 msg.unsetf(ios_base::floatfield);
842 if (fVoltageReduction==0)
843 msg <<
" Unom=" << voltageoffset <<
"V";
845 msg <<
" Ured=" << fVoltageReduction <<
"V";
847 msg <<
" Uov=" << Uov;
848 msg <<
" Imed=" << data.Imed <<
"uA [N=" << Ndev[0] <<
"/" << Ndev[1] <<
"/" << Ndev[2] <<
"]";
857 msg << setprecision(4) <<
"Current status: dU(" << fTemp <<
"degC)=" << fTempOffsetAvg <<
"V+-" << fTempOffsetRms <<
", Unom=" << voltageoffset <<
"V, Uov=" << (num[0]+num[1]>0?(avg[0]+avg[1])/(num[0]+num[1]):0) <<
" [N=" << Ndev[0] <<
"/" << Ndev[1] <<
"/" << Ndev[2] <<
"]";
874 msg <<
" Avg0=" << setw(7) << avg[0]/num[0] <<
" | Avg1=" << setw(7) << avg[1]/num[1];
878 msg <<
" Med0=" << setw(7) << med[0][num[0]/2] <<
" | Med1=" << setw(7) << med[1][num[1]/2];
882 msg <<
" Min0=" << setw(7) << min[0] <<
" | Min1=" << setw(7) << min[1];
886 msg <<
" Max0=" << setw(7) << max[0] <<
" | Max1=" << setw(7) << max[1];
898 fDimCurrents.
setData(&data,
sizeof(dim_data));
909 Out() << fDim << endl;
910 Out() << fDimFSC << endl;
911 Out() << fDimBias << endl;
913 return GetCurrentState();
953 return GetCurrentState();
958 if (!CheckEventSize(evt.
GetSize(),
"SetVerbosity", 1))
959 return kSM_FatalError;
963 return GetCurrentState();
968 if (!CheckEventSize(evt.
GetSize(),
"SetCurrentRequestInterval", 2))
969 return kSM_FatalError;
971 fCurrentRequestInterval = evt.
GetUShort();
973 Info(
"New current request interval: "+to_string(fCurrentRequestInterval)+
"ms");
975 return GetCurrentState();
980 if (!CheckEventSize(evt.
GetSize(),
"SetMoonMode", 2))
981 return kSM_FatalError;
987 Info(
"New moon mode: "+to_string(fMoonMode));
989 return GetCurrentState();
996 Warn(
"Calibration can only be started when biasctrl is in state VoltageOff.");
997 return GetCurrentState();
1000 Message(
"Starting calibration (ignore="+to_string(fNumCalibIgnore)+
", N="+to_string(fNumCalibRequests)+
")");
1002 fCursorCur = -fNumCalibIgnore;
1009 fTimeCalib =
Time();
1024 if (!CheckEventSize(evt.
GetSize(),
"Start", 4))
1025 return kSM_FatalError;
1035 fVoltageReduction = 0;
1043 out <<
"Starting feedback with an offset of " << fUserOffset <<
"V";
1047 Message(
"Moon mode "+to_string(fMoonMode)+
" turned on.");
1060 return GetCurrentState();
1070 while (fin && cnt<320)
1075 Error(
"Reading offsets from "+file+
" failed [N="+to_string(cnt-1)+
"]");
1081 fDimOffsets.
Update(fVoltOffset);
1083 Info(
"New voltage offsets loaded from "+file);
1091 return GetCurrentState();
1098 fDimOffsets.
Update(fVoltOffset);
1100 Info(
"Voltage offsets resetted.");
1101 return GetCurrentState();
1106 ofstream fout(
"feedback-calib.bin");
1108 double mjd = fTimeCalib.
Mjd();
1109 fout.write((
char*)&mjd,
sizeof(
double));
1113 return GetCurrentState();
1118 ifstream fin(
"feedback-calib.bin");
1125 fin.read((
char*)&mjd,
sizeof(
double));
1131 Warn(
"Reading of calibration failed.");
1132 return GetCurrentState();
1135 fTimeCalib.
Mjd(mjd);
1164 return GetCurrentState();
1166 return GetCurrentState();
1173 if (fCurrentRequestInterval>0 &&
Time()-past>boost::posix_time::milliseconds(fCurrentRequestInterval))
1180 return GetCurrentState();
1187 fDimFSC(
"FSC_CONTROL"),
1188 fDimBias(
"BIAS_CONTROL"),
1190 fDimCalibration(
"FEEDBACK/CALIBRATION",
"F:416;F:416;F:416;F:416",
1192 "|Avg[uA]:Average offset at dac=256+5*512" 1193 "|Rms[uA]:Rms of Avg" 1194 "|R[Ohm]:Measured calibration resistor" 1195 "|U[V]:Corresponding voltage reported by biasctrl"),
1196 fDimCalibration2(
"FEEDBACK/CALIBRATION_STEPS",
"I:1;F:416;F:416;F:416",
1197 "Calibration of the R8 resistor" 1198 "|DAC[dac]:DAC setting" 1199 "|U[V]:Corresponding voltages reported by biasctrl" 1200 "|Iavg[uA]:Averaged measured current" 1201 "|Irms[uA]:Rms measured current"),
1202 fDimCalibrationR8(
"FEEDBACK/CALIBRATION_R8",
"F:416;F:416",
1204 "|DeltaI[uA]:Average offset" 1205 "|R8[Ohm]:Measured effective resistor R8"),
1206 fDimCurrents(
"FEEDBACK/CALIBRATED_CURRENTS",
"F:416;F:1;F:1;F:1;F:1;I:1;F:1;F:416;F:1;F:1",
1207 "Calibrated currents" 1208 "|I[uA]:Calibrated currents per pixel" 1209 "|I_avg[uA]:Average calibrated current (N channels)" 1210 "|I_rms[uA]:Rms of calibrated current (N channels)" 1211 "|I_med[uA]:Median calibrated current (N channels)" 1212 "|I_dev[uA]:Deviation of calibrated current (N channels)" 1213 "|N[uint16]:Number of valid values" 1214 "|T_diff[s]:Time difference to calibration" 1215 "|U_ov[V]:Calculated overvoltage w.r.t. operation voltage" 1216 "|U_nom[V]:Nominal overvoltage w.r.t. operation voltage" 1217 "|dU_temp[V]:Correction calculated from temperature" 1219 fDimOffsets(
"FEEDBACK/OFFSETS",
"F:416",
1220 "Offsets operation voltages" 1221 "|U[V]:Offset per bias channels"),
1224 fCurrentRequestInterval(0),
1225 fNumCalibIgnore(30),
1226 fNumCalibRequests(300)
1234 Subscribe(
"BIAS_CONTROL/CURRENT")
1236 Subscribe(
"BIAS_CONTROL/VOLTAGE")
1238 Subscribe(
"BIAS_CONTROL/DAC")
1240 Subscribe(
"BIAS_CONTROL/NOMINAL")
1242 Subscribe(
"FSC_CONTROL/BIAS_TEMP")
1247 "The Dim DNS is not reachable.");
1250 "The Dim DNS is reachable, but the required subsystems are not available.");
1252 "Either biasctrl or fscctrl not connected.");
1254 "biasctrl and fscctrl are available and connected with their hardware.");
1257 "Bias crate calibrating in progress.");
1259 "Bias crate calibrated.");
1262 "Current control started, waiting for valid temperature and current data.");
1265 "Current control in progress but with limited voltage.");
1267 "Current control in progress.");
1269 "Current control in progress but current warning level exceeded.");
1271 "Current control in progress but critical current limit exceeded.");
1286 (
"Start the current/temperature control loop" 1287 "|Uov[V]:Overvoltage to be applied (standard value is 1.1V)");
1291 (
"Stop any control loop");
1310 (
"Operate central pixels at 5V below nominal voltage. 0:off, 1:minimal, 2:medium, 3:maximum size.");
1316 AddEvent(
"PRINT_CALIBRATION")
1321 AddEvent(
"SET_VERBOSE",
"B:1")
1323 (
"set verbosity state" 1324 "|verbosity[bool]:disable or enable verbosity when calculating overvoltage");
1329 fIsVerbose = !conf.
Get<
bool>(
"quiet");
1331 if (!fMap.
Read(conf.
Get<
string>(
"pixel-map-file")))
1333 Error(
"Reading mapping table from "+conf.
Get<
string>(
"pixel-map-file")+
" failed.");
1337 fCurrentRequestInterval = conf.
Get<uint16_t>(
"current-request-interval");
1338 fNumCalibIgnore = conf.
Get<uint16_t>(
"num-calib-ignore");
1339 fNumCalibRequests = conf.
Get<uint16_t>(
"num-calib-average");
1340 fTempCoefficient = conf.
Get<
double>(
"temp-coefficient");
1342 if (conf.
Has(
"offset-file"))
1343 LoadOffsets(conf.
Get<
string>(
"offset-file"));
1356 return Main::execute<T, StateMachineFeedback>(conf);
1361 po::options_description control(
"Feedback options");
1362 control.add_options()
1363 (
"quiet,q",
po_bool(
true),
"Disable printing more information on average overvoltagecontents of all received messages (except dynamic data) in clear text.")
1364 (
"pixel-map-file", var<string>()->required(),
"Pixel mapping file. Used here to get the default reference voltage.")
1365 (
"current-request-interval", var<uint16_t>(1000),
"Interval between two current requests.")
1366 (
"num-calib-ignore", var<uint16_t>(30),
"Number of current requests to be ignored before averaging")
1367 (
"num-calib-average", var<uint16_t>(300),
"Number of current requests to be averaged")
1368 (
"temp-coefficient", var<double>()->required(),
"Temp. coefficient [V/K]")
1369 (
"offset-file", var<string>(),
"File with operation voltage offsets")
1387 "The feedback control the BIAS voltages based on the calibration signal.\n" 1389 "The default is that the program is started without user intercation. " 1390 "All actions are supposed to arrive as DimCommands. Using the -c " 1391 "option, a local shell can be initialized. With h or help a short " 1392 "help message about the usuage can be brought to the screen.\n" 1394 "Usage: feedback [-c type] [OPTIONS]\n" 1395 " or: feedback [OPTIONS]\n";
1401 Main::PrintHelp<StateMachineFeedback>();
1421 int main(
int argc,
const char* argv[])
1434 if (!conf.
Has(
"console"))
1439 return RunShell<LocalStream>(conf);
1451 if (conf.
Get<
int>(
"console")==0)
1452 return RunShell<LocalShell>(conf);
1454 return RunShell<LocalConsole>(conf);
DimDescribedService fDimOffsets
DimDescribedState fDimBias
int CheckLimits(const float *I)
bool LoadOffsets(const string &file)
virtual void Subscribe(StateMachineImp &imp)
DimDescribedState fDimFSC
A general base-class describing events issues in a state machine.
const char * GetText() const
bool CheckEventSize(size_t has, const char *name, size_t size)
int HandleCalibration(const EventImp &evt)
void SetupConfiguration(Configuration &conf)
void setQuality(int quality)
DimDescribedService fDimCalibration2
Adds some functionality to boost::posix_time::ptime for our needs.
DimDescribedService fDimCalibration
void SetPrintUsage(const std::function< void(void)> &func)
T Get(const std::string &var)
StateMachineFeedback(ostream &out=cout)
int HandleBiasDac(const EventImp &evt)
const int32_t & state() const
vector< double > fTempOffset
vector< int64_t > fCurrentsAvg
vector< float > fCalibDeltaI
pair< vector< float >, vector< float > > AverageCurrents(const int16_t *ptr, int n)
int EvalOptions(Configuration &conf)
int main(int argc, const char *argv[])
uint16_t GetUShort() const
vector< float > fVoltGapd
int SetCurrentRequestInterval(const EventImp &evt)
uint16_t fCurrentRequestInterval
bool Has(const std::string &var)
uint16_t fTimeoutCritical
void AddOptions(const po::options_description &opt, bool visible=true)
uint16_t fNumCalibRequests
vector< uint16_t > fBiasDac
int HandleBiasStateChange()
void setData(const void *ptr, size_t sz)
int HandleCameraTemp(const EventImp &evt)
virtual Time GetTime() const
static void sendCommandNB(const char *name, int data)
int HandleBiasVoltage(const EventImp &evt)
int Execute()
Is called continously to execute actions in the current state.
DimDescribedService fDimCurrents
vector< int64_t > fCurrentsRms
void SendCommandNB(const std::string &command)
int Start(const EventImp &evt)
vector< double > fVoltOffset
int LoadOffset(const EventImp &evt)
Commandline parsing, resource file parsing and database access.
vector< float > fCalibration
virtual void Subscribe(StateMachineImp &imp)
Class for a state machine implementation within a DIM network.
int SetMoonMode(const EventImp &evt)
int HandleBiasCurrent(const EventImp &evt)
po::typed_value< bool > * po_bool(bool def=false)
vector< float > fBiasVolt
int HandleBiasNom(const EventImp &evt)
T Get(size_t offset=0) const
bool Read(const std::string &fname)
bool DoParse(int argc, const char **argv, const std::function< void()> &func=std::function< void()>())
DimDescribedService fDimCalibrationR8
Do not initialize the time.
int SetVerbosity(const EventImp &evt)
void SetCallback(const callback &cb)
const T * Ptr(size_t offset=0) const
int RunShell(Configuration &conf)
void SetupConfiguration(Configuration &conf)
const PixelMapEntry & hv(int board, int channel) const
virtual size_t GetSize() const