22 namespace ba = boost::asio;
23 namespace bs = boost::system;
24 namespace dummy = ba::placeholders;
86 if (
size_t(evt.
GetSize())==size)
93 msg << evt.
GetName() <<
" - Received event has " << evt.
GetSize() <<
" bytes, but expected " << size <<
".";
105 if (fThresholds.empty())
111 Out() <<
"Min. DAC=" << fThresholdMin << endl;
113 for (
int j=0; j<10; j++)
115 for (
int k=0; k<4; k++)
117 for (
int i=0;
i<4;
i++)
119 const int p =
i + k*4 + j*16;
121 if (fThresholds[p]!=fThresholdMin)
122 Out() << setw(3) << fThresholds[p];
142 uint32_t diff = fThresholds[idx]+int16_t(truncf(step));
143 if (diff<fThresholdMin)
148 if (diff==fThresholds[idx])
153 Out() <<
"Apply: Patch " << setw(3) << idx <<
" [" << idx/40 <<
"|" << (idx/4)%10 <<
"|" << idx%4 <<
"]";
154 Out() << (step>0 ?
" += " :
" -= ");
155 Out() << fabs(step) <<
" (old=" << fThresholds[idx] <<
", new=" << diff <<
")" << endl;
158 fThresholds[idx] = diff;
159 fBlock[idx/4] =
true;
171 sort(medb.begin(), medb.end());
172 sort(medp.begin(), medp.end());
174 vector<float> devb(40);
175 for (
int i=0;
i<40;
i++)
178 vector<float> devp(160);
179 for (
int i=0; i<160; i++)
182 sort(devb.begin(), devb.end());
183 sort(devp.begin(), devp.end());
185 const double mb = (medb[19]+medb[20])/2;
186 const double mp = (medp[79]+medp[80])/2;
188 const double db = devb[27];
189 const double dp = devp[109];
192 if (mb==0 || mp==0 || db==0 || dp==0)
196 Out() <<
Tools::Form(
"Boards: Med=%3.1f +- %3.1f Hz Patches: Med=%3.1f +- %3.1f Hz", mb, db, mp, dp) << endl;
198 bool changed =
false;
200 for (
int i=0; i<40; i++)
210 const float dif = fabs(sdata.
fBoardRate[i]-mb)/db;
214 Out() <<
"Board " << setw(3) << i <<
": " << dif <<
" dev away from med" << endl;
219 for (
int j=1; j<4; j++)
227 for (
int j=0; j<4; j++)
236 const float step = (log10(sdata.
fPatchRate[i*4+j])-log10(mp+3.5*dp))/0.039;
238 changed |= Step(i*4+j, step);
245 const float step = (log10(sdata.
fPatchRate[i*4+j])-log10(mp+3.5*dp))/0.039;
246 changed |= Step(i*4+j, step);
250 const float step = -1.5*(log10(mp+dp)-log10(mp))/0.039;
251 changed |= Step(i*4+j, step);
262 return GetCurrentState();
267 sort(medb.begin(), medb.end());
269 vector<float> devb(40);
270 for (
int i=0;
i<40;
i++)
273 sort(devb.begin(), devb.end());
275 double mb = (medb[19]+medb[20])/2;
276 double db = devb[27];
281 Warn(
"The median or the deviation of all board rates is zero... cannot calibrate.");
282 return GetCurrentState();
288 for (
int i=0; i<40; i++)
297 fTriggerRate = avg/num * 40;
301 Out() <<
"Board: Median=" << mb <<
" Dev=" << db << endl;
302 Out() <<
"Camera: " << fTriggerRate <<
" (" << sdata.
fTriggerRate <<
", n=" << num <<
")" << endl;
303 Out() <<
"Target: " << fTargetRate << endl;
321 if (fTriggerRate>0 && fTriggerRate<fTargetRate)
323 fThresholds.assign(160, fThresholdMin);
327 fDimThreshold.
Update(data);
330 out << setprecision(3);
331 out <<
"Measured rate " << fTriggerRate <<
"Hz below target rate " << fTargetRate <<
"... minimum threshold set to " << fThresholdMin;
335 fPhysTriggerEnabled =
false;
341 const float step = (log10(fTriggerRate)-log10(fTargetRate))/0.039 + 1;
343 const uint16_t diff = fThresholdMin+int16_t(truncf(step));
344 if (diff<=fThresholdMin)
348 fDimThreshold.
Update(data);
351 out << setprecision(3);
352 out <<
"Next step would be 0... minimum threshold set to " << fThresholdMin;
356 fPhysTriggerEnabled =
false;
363 Out() << fThresholdMin;
364 Out() << (step>0 ?
" += " :
" -= ");
365 Out() << step <<
" (" << diff <<
")" << endl;
368 const uint32_t val[2] = { uint32_t(-1), diff };
371 fThresholdMin = diff;
373 return GetCurrentState();
379 return GetCurrentState();
385 Out() <<
"\n" << evt.
GetTime() <<
": " << (bool)fTriggerOn <<
" " << (
bool)fPhysTriggerEnabled << endl;
386 PrintThresholds(sdata);
390 if (fThresholds.empty())
401 return GetCurrentState();
408 if (fThresholds.empty())
409 return GetCurrentState();
413 return GetCurrentState();
416 return GetCurrentState();
421 return ProcessCamera(sdata);
424 ProcessPatches(sdata);
426 return GetCurrentState();
432 if (!CheckEventSize(evt, (2*416+8)*4))
433 return GetCurrentState();
438 return GetCurrentState();
442 const float med = evt.
Get<
float>(416*4+4+4);
443 const float dev = evt.
Get<
float>(416*4+4+4+4);
444 const float *cur = evt.
Ptr<
float>();
447 fCurrentsMed.emplace_back(time, med);
448 fCurrentsDev.emplace_back(time, dev);
449 fCurrentsVec.emplace_back(time, vector<float>(cur, cur+320));
450 while (!fCurrentsMed.empty())
452 if (time-fCurrentsMed.front().first<boost::posix_time::seconds(fAverageTime))
455 fCurrentsMed.pop_front();
456 fCurrentsDev.pop_front();
457 fCurrentsVec.pop_front();
461 if (!fCalibrateByCurrent)
462 return GetCurrentState();
466 return GetCurrentState();
469 if (!fThresholds.empty())
470 return GetCurrentState();
473 if (fCurrentsMed.size()<fRequiredEvents)
474 return GetCurrentState();
479 for (
auto it=fCurrentsMed.begin(); it!=fCurrentsMed.end(); it++)
482 rms += it->second*it->second;
484 avg /= fCurrentsMed.size();
485 rms /= fCurrentsMed.size();
487 rms = rms<0 ? 0 : sqrt(rms);
490 for (
auto it=fCurrentsDev.begin(); it!=fCurrentsDev.end(); it++)
491 avg_dev += it->second;
492 avg_dev /= fCurrentsMed.size();
497 vector<double> vec(160);
498 for (
auto it=fCurrentsVec.begin(); it!=fCurrentsVec.end(); it++)
499 for (
int i=0;
i<320;
i++)
503 vec[hv.
hw()/9] += it->second[
i]*hv.
count();
511 fThresholdMin = max(uint16_t(156.3*pow(avg, 0.3925)+1), fThresholdReference);
513 fThresholds.assign(160, fThresholdMin);
518 for (
int i=0;
i<160;
i++)
520 vec[
i] /= fCurrentsVec.size()*9;
524 if (vec[
i]>avg+3.5*avg_dev)
526 fThresholds[
i] = max(uint16_t(40.5*pow(vec[
i], 0.642)+164), fThresholdMin);
539 fDimThreshold.
Update(data);
544 out << setprecision(3);
545 out <<
"Measured average current " << avg <<
"uA +- " << rms <<
"uA [N=" << fCurrentsMed.size() <<
"]... minimum threshold set to " << fThresholdMin;
547 Info(
"Set "+to_string(counter)+
" individual thresholds.");
550 fPhysTriggerEnabled =
false;
557 const int32_t val[2] = { -1, fThresholdReference };
560 fThresholds.assign(160, fThresholdReference);
562 fThresholdMin = fThresholdReference;
565 fBlock.assign(160,
false);
567 fCalibrateByCurrent =
false;
568 fCalibrationTimeStart =
Time();
571 out <<
"Rate calibration started at a threshold of " << fThresholdReference <<
" with a target rate of " << fTargetRate <<
" Hz";
580 fCalibrateByCurrent =
true;
581 fCalibrationTimeStart =
Time();
582 fBlock.assign(160,
false);
587 out <<
"Rate calibration by current with min. threshold of " << fThresholdReference <<
".";
595 const string name = evt.
GetText();
597 auto it = fRunTypes.find(name);
598 if (it==fRunTypes.end())
600 Info(
"CalibrateRun - Run-type '"+name+
"' not found... trying 'default'.");
602 it = fRunTypes.find(
"default");
603 if (it==fRunTypes.end())
605 Error(
"CalibrateRun - Run-type 'default' not found.");
606 return GetCurrentState();
610 const config &conf = it->second;
615 if (!fPhysTriggerEnabled)
617 Info(
"Calibration requested, but physics trigger not enabled... CALIBRATE command ignored.");
620 fPhysTriggerEnabled =
false;
626 Info(
"Calibration requested, but lid closed... setting all thresholds to "+to_string(conf.
fMinThreshold)+
".");
633 const double mjd =
Time().
Mjd();
637 fDimThreshold.
Update(data);
639 fCalibrateByCurrent =
true;
641 fPhysTriggerEnabled =
false;
646 Warn(
"Calibration requested, but drive not even moving...");
652 Info(
"No calibration requested.");
654 fPhysTriggerEnabled =
false;
667 return CalibrateByCurrent();
671 return GetCurrentState();
676 Info(
"Stop received.");
682 if (!CheckEventSize(evt, 4))
683 return kSM_FatalError;
689 return GetCurrentState();
694 if (!CheckEventSize(evt, 4))
695 return kSM_FatalError;
699 return GetCurrentState();
704 Out() << fDim << endl;
705 Out() << fDimFTM << endl;
706 Out() << fDimRS << endl;
707 Out() << fDimLid << endl;
708 Out() << fDimDrive << endl;
710 return GetCurrentState();
715 if (!CheckEventSize(evt, 1))
716 return kSM_FatalError;
720 return GetCurrentState();
736 switch (GetCurrentState())
744 if (fTriggerOn && fPhysTriggerEnabled)
752 if (!fTriggerOn || !fPhysTriggerEnabled)
763 fPhysTriggerEnabled(false), fTriggerOn(false), fBlock(40),
764 fDimFTM(
"FTM_CONTROL"),
766 fDimLid(
"LID_CONTROL"),
767 fDimDrive(
"DRIVE_CONTROL"),
768 fDimThreshold(
"RATE_CONTROL/THRESHOLD",
"S:1;D:1;D:1",
769 "Resulting threshold after calibration" 770 "|threshold[dac]:Resulting threshold from calibration" 771 "|begin[mjd]:Start time of calibration" 772 "|end[mjd]:End time of calibration")
787 Subscribe(
"FTM_CONTROL/TRIGGER_RATES")
789 Subscribe(
"FTM_CONTROL/STATIC_DATA")
791 Subscribe(
"FEEDBACK/CALIBRATED_CURRENTS")
796 "The Dim DNS is not reachable.");
799 "The Dim DNS is reachable, but the required subsystems are not available.");
802 "All needed subsystems are connected to their hardware, no action is performed.");
805 "A global minimum threshold is currently determined.");
808 "A global threshold has ben set, waiting for the trigger to be switched on.");
811 "Rate control in progress.");
813 AddEvent(
"CALIBRATE")
815 (
"Start a search for a reasonable minimum global threshold");
817 AddEvent(
"CALIBRATE_BY_CURRENT")
819 (
"Set the global threshold from the median current");
821 AddEvent(
"CALIBRATE_RUN",
"C")
823 (
"Start a threshold calibration as defined in the setup for this run-type, state change to InProgress is delayed until trigger enabled");
827 (
"Stop a calibration or ratescan in progress");
829 AddEvent(
"SET_MIN_THRESHOLD",
"I:1")
831 (
"Set a minimum threshold at which th rate control starts calibrating");
833 AddEvent(
"SET_TARGET_RATE",
"F:1")
835 (
"Set a target trigger rate for the calibration");
839 (
"Print current status");
841 AddEvent(
"SET_VERBOSE",
"B")
843 (
"set verbosity state" 844 "|verbosity[bool]:disable or enable verbosity for received data (yes/no), except dynamic data");
850 if (conf.
HasDef(name, sub))
852 rc = conf.
GetDef<uint16_t>(name, sub);
856 Error(
"Neither "+name+
"default nor "+name+sub+
" found.");
862 fVerbose = !conf.
Get<
bool>(
"quiet");
864 if (!fMap.
Read(conf.
Get<
string>(
"pixel-map-file")))
866 Error(
"Reading mapping table from "+conf.
Get<
string>(
"pixel-map-file")+
" failed.");
870 fThresholdReference = 300;
878 const vector<string> types = conf.
Vec<
string>(
"run-type");
880 Warn(
"No run-types defined.");
882 Message(
"Defining run-types");
884 for (
auto it=types.begin(); it!=types.end(); it++)
886 Message(
" -> "+ *it);
888 if (fRunTypes.count(*it)>0)
890 Error(
"Run-type "+*it+
" defined twice.");
894 config &c = fRunTypes[*it];
896 !GetConfig(conf,
"target-rate.", *it, c.
fTargetRate) ||
898 !GetConfig(conf,
"average-time.", *it, c.
fAverageTime) ||
914 return Main::execute<T, StateMachineRateControl>(conf);
919 po::options_description control(
"Rate control options");
920 control.add_options()
921 (
"quiet,q",
po_bool(),
"Disable printing more informations during rate control.")
922 (
"pixel-map-file", var<string>()->required(),
"Pixel mapping file. Used here to get the default reference voltage.")
929 po::options_description runtype(
"Run type configuration");
930 runtype.add_options()
931 (
"run-type", vars<string>(),
"Name of run-types (replace the * in the following configuration by the case-sensitive names defined here)")
932 (
"calibration-type.*", var<uint16_t>(),
"Calibration type (0: none, 1: by rate, 2: by current)")
933 (
"target-rate.*", var<uint16_t>(),
"Target rate for calibration by rate")
934 (
"min-threshold.*", var<uint16_t>(),
"Minimum threshold which can be applied in a calibration")
935 (
"average-time.*", var<uint16_t>(),
"Time in seconds to average the currents for a calibration by current.")
936 (
"required-events.*", var<uint16_t>(),
"Number of required current events to start a calibration by current.");
954 "The ratecontrol program is a keep the rate reasonable low.\n" 956 "Usage: ratecontrol [-c type] [OPTIONS]\n" 957 " or: ratecontrol [OPTIONS]\n";
963 Main::PrintHelp<StateMachineRateControl>();
983 int main(
int argc,
const char* argv[])
993 if (!conf.
Has(
"console"))
994 return RunShell<LocalStream>(conf);
996 if (conf.
Get<
int>(
"console")==0)
997 return RunShell<LocalShell>(conf);
999 return RunShell<LocalConsole>(conf);
int CalibrateRun(const EventImp &evt)
void ProcessPatches(const FTM::DimTriggerRates &sdata)
int SetMinThreshold(const EventImp &evt)
list< pair< Time, float > > fCurrentsDev
virtual void Subscribe(StateMachineImp &imp)
A general base-class describing events issues in a state machine.
const char * GetText() const
int HandleStaticData(const EventImp &evt)
void SetupConfiguration(Configuration &conf)
void PrintThresholds(const FTM::DimStaticData &sdata)
void setQuality(int quality)
list< pair< Time, float > > fCurrentsMed
Adds some functionality to boost::posix_time::ptime for our needs.
void SetPrintUsage(const std::function< void(void)> &func)
T Get(const std::string &var)
int HandleTriggerRates(const EventImp &evt)
int Execute()
Is called continously to execute actions in the current state.
int HandleCalibratedCurrents(const EventImp &evt)
const int32_t & state() const
uint16_t fThresholdReference
std::vector< T > Vec(const std::string &var)
StateMachineRateControl(ostream &out=cout)
int ProcessCamera(const FTM::DimTriggerRates &sdata)
int SetVerbosity(const EventImp &evt)
uint16_t GetUShort() const
bool Has(const std::string &var)
T GetDef(const std::string &var, const S &val)
int SetTargetRate(const EventImp &evt)
Time fCalibrationTimeStart
void AddOptions(const po::options_description &opt, bool visible=true)
uint16_t fCalibrationType
map< string, config > fRunTypes
virtual Time GetTime() const
DimDescribedState fDimDrive
virtual int GetQoS() const
list< pair< Time, vector< float > > > fCurrentsVec
void SendCommandNB(const std::string &command)
Warning because the service this data corrsponds to might have been last updated longer ago than Local time
void SetupConfiguration(Configuration &conf)
Commandline parsing, resource file parsing and database access.
DimDescribedService fDimThreshold
DimDescribedState fDimFTM
virtual void Subscribe(StateMachineImp &imp)
Class for a state machine implementation within a DIM network.
virtual std::string GetName() const
DimDescribedState fDimLid
Return to feeserver c CVS log Up to[MAIN] dcscvs FeeServer feeserver src Wed FeeServer_v0 v0 dev
int main(int argc, const char *argv[])
po::typed_value< bool > * po_bool(bool def=false)
bool GetConfig(Configuration &conf, const string &name, const string &sub, uint16_t &rc)
T Get(size_t offset=0) const
bool HasDef(const std::string &var, const T &val)
bool Read(const std::string &fname)
virtual const void * GetData() const
bool DoParse(int argc, const char **argv, const std::function< void()> &func=std::function< void()>())
Trigger output enabled, configuration ignored.
const T * Ptr(size_t offset=0) const
bool Step(int idx, float step)
vector< uint32_t > fThresholds
int RunShell(Configuration &conf)
bool CheckEventSize(const EventImp &evt, size_t size)
const PixelMapEntry & hv(int board, int channel) const
virtual size_t GetSize() const
int EvalOptions(Configuration &conf)