source: trunk/FACT++/src/EventBuilderWrapper.h@ 14468

Last change on this file since 14468 was 14366, checked in by tbretz, 12 years ago
Shortened a few descriptions complained by the datalogger
File size: 46.2 KB
Line 
1#ifndef FACT_EventBuilderWrapper
2#define FACT_EventBuilderWrapper
3
4#include <sstream>
5
6#if BOOST_VERSION < 104400
7#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4))
8#undef BOOST_HAS_RVALUE_REFS
9#endif
10#endif
11#include <boost/thread.hpp>
12#include <boost/filesystem.hpp>
13#include <boost/date_time/posix_time/posix_time_types.hpp>
14
15#include "DimWriteStatistics.h"
16
17#include "DataCalib.h"
18#include "DataWriteRaw.h"
19
20#ifdef HAVE_FITS
21#include "DataWriteFits.h"
22#else
23#define DataWriteFits DataWriteFits2
24#endif
25
26#include "DataWriteFits2.h"
27
28namespace ba = boost::asio;
29namespace bs = boost::system;
30namespace fs = boost::filesystem;
31
32using ba::ip::tcp;
33
34using namespace std;
35
36// ========================================================================
37
38#include "EventBuilder.h"
39
40extern "C" {
41 extern void StartEvtBuild();
42 extern int CloseRunFile(uint32_t runId, uint32_t closeTime, uint32_t maxEvt);
43}
44
45// ========================================================================
46
47class EventBuilderWrapper
48{
49public:
50 // FIXME
51 static EventBuilderWrapper *This;
52
53 MessageImp &fMsg;
54
55private:
56 boost::thread fThread;
57
58 enum CommandStates_t // g_runStat
59 {
60 kAbort = -2, // quit as soon as possible ('abort')
61 kExit = -1, // stop reading, quit when buffered events done ('exit')
62 kInitialize = 0, // 'initialize' (e.g. dim not yet started)
63 kHybernate = 1, // do nothing for long time ('hybernate') [wakeup within ~1sec]
64 kSleep = 2, // do nothing ('sleep') [wakeup within ~10msec]
65 kModeFlush = 10, // read data from camera, but skip them ('flush')
66 kModeTest = 20, // read data and process them, but do not write to disk ('test')
67 kModeFlag = 30, // read data, process and write all to disk ('flag')
68 kModeRun = 40, // read data, process and write selected to disk ('run')
69 };
70
71 enum
72 {
73 kCurrent = 0,
74 kTotal = 1,
75 kEventId = 2,
76 kTriggerId = 3,
77 };
78
79 FAD::FileFormat_t fFileFormat;
80
81 uint32_t fMaxRun;
82 uint32_t fLastOpened;
83 uint32_t fLastClosed;
84 uint32_t fNumEvts[4];
85
86 DimWriteStatistics fDimWriteStats;
87 DimDescribedService fDimRuns;
88 DimDescribedService fDimEvents;
89 DimDescribedService fDimRawData;
90 DimDescribedService fDimEventData;
91 DimDescribedService fDimFeedbackData;
92 DimDescribedService fDimFwVersion;
93 DimDescribedService fDimRunNumber;
94 DimDescribedService fDimStatus;
95 DimDescribedService fDimDNA;
96 DimDescribedService fDimTemperature;
97 DimDescribedService fDimPrescaler;
98 DimDescribedService fDimRefClock;
99 DimDescribedService fDimRoi;
100 DimDescribedService fDimDac;
101 DimDescribedService fDimDrsRuns;
102 DimDescribedService fDimDrsCalibration;
103 DimDescribedService fDimStatistics1;
104 DimDescribedService fDimStatistics2;
105 DimDescribedService fDimFileFormat;
106
107 bool fDebugStream;
108 bool fDebugRead;
109 bool fDebugLog;
110
111 string fPath;
112 uint32_t fRunNumber;
113
114protected:
115 int64_t InitRunNumber()
116 {
117 fRunNumber = 1000;
118
119 // Ensure that the night doesn't change during our check
120 const int check = Time().NightAsInt();
121
122 while (--fRunNumber>0)
123 {
124 const string name = DataProcessorImp::FormFileName(fPath, fRunNumber, "");
125
126 if (access((name+"bin").c_str(), F_OK) == 0)
127 break;
128 if (access((name+"fits").c_str(), F_OK) == 0)
129 break;
130 if (access((name+"drs.fits").c_str(), F_OK) == 0)
131 break;
132
133 }
134
135 if (check != Time().NightAsInt())
136 return InitRunNumber();
137
138 fRunNumber++;
139
140 if (fRunNumber==1000)
141 {
142 fMsg.Error("You have a file with run-number 1000 in "+fPath);
143 return -1;
144 }
145
146 ostringstream str;
147 str << "Set next run-number to " << fRunNumber << " determined from '" << (fPath.empty()?".":fPath) << "'";
148 fMsg.Message(str);
149
150 //fMsg.Info(" ==> TODO: Crosscheck with database!");
151
152 return check;
153 }
154
155 int64_t InitRunNumber(const string &path)
156 {
157 if (!DimWriteStatistics::DoesPathExist(path, fMsg))
158 {
159 fMsg.Error("Data path "+path+" does not exist!");
160 return -1;
161 }
162
163 //const fs::path fullPath = fs::system_complete(fs::path(path));
164
165 fPath = path;
166
167 fDimWriteStats.SetCurrentFolder(fPath);
168
169 return InitRunNumber();
170 }
171
172public:
173 EventBuilderWrapper(MessageImp &imp) : fMsg(imp),
174 fFileFormat(FAD::kNone), fMaxRun(0), fLastOpened(0), fLastClosed(0),
175 fDimWriteStats ("FAD_CONTROL", imp),
176 fDimRuns ("FAD_CONTROL/RUNS", "I:5;C",
177 "Run files statistics"
178 "|stats[int]:num of open files, min/max run no, last opened or closed run"
179 "|file[string]:filename of last opened file"),
180 fDimEvents ("FAD_CONTROL/EVENTS", "I:4",
181 "Event counts"
182 "|evtsCount[int]:Num evts cur. run, total (all run), evt ID, trig. Num"),
183 fDimRawData ("FAD_CONTROL/RAW_DATA", "S:1;I:1;S:1;I:1;I:2;I:40;S:1440;S:160;F", ""),
184 fDimEventData ("FAD_CONTROL/EVENT_DATA", "F:1440;F:1440;F:1440;F:1440", ""),
185 fDimFeedbackData("FAD_CONTROL/FEEDBACK_DATA", "F:1440", ""),
186 fDimFwVersion ("FAD_CONTROL/FIRMWARE_VERSION", "F:42",
187 "Firmware version number of fad boards"
188 "|firmware[float]:Version number of firmware, for each board. 40=min, 41=max"),
189 fDimRunNumber ("FAD_CONTROL/RUN_NUMBER", "I:42",
190 "Run numbers coming from FAD boards"
191 "|runNumbers[int]:current run number of each FAD board. 40=min, 41=max"),
192 fDimStatus ("FAD_CONTROL/STATUS", "S:42",
193 "Status of FAD boards"
194 "|status[bitpattern]:Status of each FAD board. Maybe buggy"),
195 fDimDNA ("FAD_CONTROL/DNA", "X:40",
196 "DNA of FAD boards"
197 "|DNA[hex]:Hex identifier of each FAD board"),
198 fDimTemperature ("FAD_CONTROL/TEMPERATURE", "F:82",
199 "FADs temperatures"
200 "|temp[deg. C]:0 global min, 1-40 min, 41 global max, 42-81 max"),
201 fDimPrescaler ("FAD_CONTROL/PRESCALER", "S:42",
202 "Trigger generator prescaler of fad boards"
203 "|prescaler[int]:Trigger generator prescaler value, for each board"),
204 fDimRefClock ("FAD_CONTROL/REFERENCE_CLOCK", "I:42",
205 "Reference clock of FAD boards"
206 "|refClocks[t]:ref clocks of FAD boards. 40=min, 41=max"),
207 fDimRoi ("FAD_CONTROL/REGION_OF_INTEREST", "S:2", ""),
208 fDimDac ("FAD_CONTROL/DAC", "S:336",
209 "DAC settings of each FAD board"
210 "|DAC[int]:DAC counts, sequentially DAC 0 board 0, 0/1, 0/2... (plus min max)"),
211 fDimDrsRuns ("FAD_CONTROL/DRS_RUNS", "I:1;I:3", ""),
212 fDimDrsCalibration("FAD_CONTROL/DRS_CALIBRATION", "I:1;I:3;F:1474560;F:1474560;F:1474560;F:1474560;F:1474560;F:1474560;F:163840;F:163840", ""),
213 fDimStatistics1 ("FAD_CONTROL/STATISTICS1", "I:3;I:5;X:4;I:3;I:3;I:40;I:1;I:2;C:40;I:40;I:40;X:40",
214 "Event Builder status for GUI display"
215 "|threadInfo[int]:Number of read, proc and writes"
216 "|bufferInfo[int]:Events in buffer, incomp., comp., tot., max past cycle, total"
217 "|memInfo[int]:total buf. mem, used mem, max used, max past cycle"
218 "|EvtCnt[int]:Number of events skipped, written, with errors"
219 "|badRoi[int]:Num boards with wrong ROI in event, run or board"
220 "|badRoiBoard[int]:Num boards with wrong ROI"
221 "|deltaT[ms]:Time in ms for rates"
222 "|rateNew[int]:Number of new start events received"
223 "|numConn[int]:Number of connections per board"
224 "|errConn[int]:IO errors per board"
225 "|rateBytes[int]:Bytes read this cycle"
226 "|totBytes[int]:Bytes read (counter)"),
227 fDimStatistics2 ("FAD_CONTROL/STATISTICS2", "I:1;I:280;X:40;I:40;I:4;I:4;I:2;I:2;I:3;C:40",
228 "Event Builder status, events oriented"
229 "|reset[int]:If increased, reset all counters"
230 "|numRead[int]:How often sucessful read from N sockets per loop"
231 "|gotByte[int]:number of bytes read per board"
232 "|gotErr[int]:number of com. errors per board"
233 "|evtStat[int]:number of evts read, completed, with errors, incomplete"
234 "|procStat[int]:num. of evts proc., w probs, acc. or rej. by SW trigger"
235 "|feedStat[int]:number of evts used or rejected by feedback system"
236 "|wrtStat[int]:number of evts written to disk, with errors"
237 "|runStat[int]:number of run opened, closed, with open or close errors"
238 "|numConn[int]:number of sockets successfully opened per board"),
239 fDimFileFormat ("FAD_CONTROL/FILE_FORMAT", "S:1", ""),
240 fDebugStream(false), fDebugRead(false), fDebugLog(false)
241 {
242 if (This)
243 throw logic_error("EventBuilderWrapper cannot be instantiated twice.");
244
245 This = this;
246
247 memset(fNumEvts, 0, sizeof(fNumEvts));
248 fDimEvents.Update(fNumEvts);
249
250 for (size_t i=0; i<40; i++)
251 ConnectSlot(i, tcp::endpoint());
252 }
253 virtual ~EventBuilderWrapper()
254 {
255 Abort();
256
257 // FIXME: Used timed_join and abort afterwards
258 // What's the maximum time the eb need to abort?
259 fThread.join();
260 //ffMsg.Info("EventBuilder stopped.");
261
262 for (vector<DataProcessorImp*>::iterator it=fFiles.begin(); it!=fFiles.end(); it++)
263 delete *it;
264 }
265
266 set<uint32_t> fIsRunStarted;
267 map<uint32_t, FAD::RunDescription> fExpectedRuns;
268
269 uint32_t StartNewRun(int64_t maxtime, int64_t maxevt, const pair<string, FAD::Configuration> &ref)
270 {
271 if (maxtime<=0 || maxtime>24*60*60)
272 maxtime = 24*60*60;
273 if (maxevt<=0 || maxevt>INT32_MAX)
274 maxevt = INT32_MAX;
275
276 const FAD::RunDescription descr =
277 {
278 uint32_t(maxtime),
279 uint32_t(maxevt),
280 ref.first,
281 ref.second,
282 };
283
284 // FIMXE: Maybe reset an event counter so that the mcp can count events?
285
286 //fMsg.Info(" ==> TODO: Set a limit on the size of fExpectedRuns!");
287
288 fExpectedRuns[fRunNumber] = descr;
289 fIsRunStarted.insert(fRunNumber);
290 return fRunNumber++;
291 }
292
293 bool IsThreadRunning()
294 {
295 return !fThread.timed_join(boost::posix_time::microseconds(0));
296 }
297
298 void SetMaxMemory(unsigned int mb) const
299 {
300 /*
301 if (mb*1000000<GetUsedMemory())
302 {
303 // ffMsg.Warn("...");
304 return;
305 }*/
306
307 g_maxMem = size_t(mb)*1000000;
308 }
309
310 void StartThread(const vector<tcp::endpoint> &addr)
311 {
312 if (IsThreadRunning())
313 {
314 fMsg.Warn("Start - EventBuilder still running");
315 return;
316 }
317
318 fLastMessage.clear();
319
320 for (size_t i=0; i<40; i++)
321 ConnectSlot(i, addr[i]);
322
323 g_runStat = kModeRun;
324 g_maxProc = 3;
325
326 fMsg.Message("Starting EventBuilder thread");
327
328 fThread = boost::thread(StartEvtBuild);
329 }
330 void ConnectSlot(unsigned int i, const tcp::endpoint &addr)
331 {
332 if (i>39)
333 return;
334
335 if (addr==tcp::endpoint())
336 {
337 DisconnectSlot(i);
338 return;
339 }
340
341 g_port[i].sockAddr.sin_family = AF_INET;
342 g_port[i].sockAddr.sin_addr.s_addr = htonl(addr.address().to_v4().to_ulong());
343 g_port[i].sockAddr.sin_port = htons(addr.port());
344 // In this order
345 g_port[i].sockDef = 1;
346 }
347 void DisconnectSlot(unsigned int i)
348 {
349 if (i>39)
350 return;
351
352 g_port[i].sockDef = 0;
353 // In this order
354 g_port[i].sockAddr.sin_family = AF_INET;
355 g_port[i].sockAddr.sin_addr.s_addr = 0;
356 g_port[i].sockAddr.sin_port = 0;
357 }
358 void IgnoreSlot(unsigned int i)
359 {
360 if (i>39)
361 return;
362 if (g_port[i].sockAddr.sin_port==0)
363 return;
364
365 g_port[i].sockDef = -1;
366 }
367
368
369 void Abort()
370 {
371 fMsg.Message("Signal abort to EventBuilder thread...");
372 g_runStat = kAbort;
373 }
374
375 void ResetThread(bool soft)
376 {
377 /*
378 if (g_reset > 0)
379
380 * suspend reading
381 * reset = g_reset;
382 * g_reset=0
383
384 * reset% 10
385 == 0 leave event Buffers as they are
386 == 1 let all buffers drain (write (incomplete) events)
387 > 1 flush all buffers (do not write buffered events)
388
389 * (reset/10)%10
390 > 0 close all sockets and destroy them (also free the
391 allocated read-buffers)
392 recreate before resuming operation
393 [ this is more than just close/open that can be
394 triggered by e.g. close/open the base-socket ]
395
396 * (reset/100)%10
397 > 0 close all open run-files
398
399 * (reset/1000)
400 sleep so many seconds before resuming operation
401 (does not (yet) take into account time left when waiting
402 for buffers getting empty ...)
403
404 * resume_reading
405
406 */
407 fMsg.Message("Signal reset to EventBuilder thread...");
408 g_reset = soft ? 101 : 102;
409 }
410
411 void Exit()
412 {
413 fMsg.Message("Signal exit to EventBuilder thread...");
414 g_runStat = kExit;
415 }
416
417 /*
418 void Wait()
419 {
420 fThread.join();
421 ffMsg.Message("EventBuilder stopped.");
422 }*/
423
424 void Hybernate() const { g_runStat = kHybernate; }
425 void Sleep() const { g_runStat = kSleep; }
426 void FlushMode() const { g_runStat = kModeFlush; }
427 void TestMode() const { g_runStat = kModeTest; }
428 void FlagMode() const { g_runStat = kModeFlag; }
429 void RunMode() const { g_runStat = kModeRun; }
430
431 // FIXME: To be removed
432 //void SetMode(int mode) const { g_runStat = mode; }
433
434 bool IsConnected(int i) const { return gi_NumConnect[i]==7; }
435 bool IsConnecting(int i) const { return !IsConnected(i) && !IsDisconnected(i); }
436 bool IsDisconnected(int i) const { return gi_NumConnect[i]<=0 && g_port[i].sockDef==0; }
437 int GetNumConnected(int i) const { return gi_NumConnect[i]; }
438 int GetNumFilesOpen() const { return fFiles.size(); }
439
440 /*
441 bool IsConnected(int i) const { return gi_NumConnect[i]>0; }
442 bool IsConnecting(int i) const { return !IsConnected(i) && !IsDisconnected(i); }
443 bool IsDisconnected(int i) const { return gi_NumConnect[i]<=0 && g_port[i].sockDef==0; }
444 int GetNumConnected(int i) const { return gi_NumConnect[i]; }
445 */
446
447 void SetIgnore(int i, bool b) const { if (g_port[i].sockDef!=0) g_port[i].sockDef=b?-1:1; }
448 bool IsIgnored(int i) const { return g_port[i].sockDef==-1; }
449
450 void SetOutputFormat(FAD::FileFormat_t f)
451 {
452 fFileFormat = f;
453 fDimFileFormat.Update(uint16_t(f));
454 if (fFileFormat==FAD::kCalib)
455 {
456 DataCalib::Restart();
457 DataCalib::Update(fDimDrsCalibration, fDimDrsRuns);
458 fMsg.Message("Resetted DRS calibration.");
459 }
460 }
461
462 virtual int ResetSecondaryDrsBaseline()
463 {
464 if (DataCalib::ResetTrgOff(fDimDrsCalibration, fDimDrsRuns))
465 {
466 fFileFormat = FAD::kCalib;
467 fDimFileFormat.Update(uint16_t(fFileFormat));
468 fMsg.Message("Resetted DRS calibration for secondary baseline.");
469 }
470 else
471 fMsg.Warn("Could not reset DRS calibration of secondary baseline.");
472
473 return 0;
474 }
475
476 void SetDebugLog(bool b) { fDebugLog = b; }
477
478 void SetDebugStream(bool b)
479 {
480 fDebugStream = b;
481 if (b)
482 return;
483
484 for (int i=0; i<40; i++)
485 {
486 if (!fDumpStream[i].is_open())
487 continue;
488
489 fDumpStream[i].close();
490
491 ostringstream name;
492 name << "socket_dump-" << setfill('0') << setw(2) << i << ".bin";
493 fMsg.Message("Closed file '"+name.str()+"'");
494 }
495 }
496
497 void SetDebugRead(bool b)
498 {
499 fDebugRead = b;
500 if (b || !fDumpRead.is_open())
501 return;
502
503 fDumpRead.close();
504 fMsg.Message("Closed file 'socket_events.txt'");
505 }
506
507// size_t GetUsedMemory() const { return gi_usedMem; }
508
509 void LoadDrsCalibration(const char *fname)
510 {
511 if (!DataCalib::ReadFits(fname, fMsg))
512 return;
513 fMsg.Info("Successfully loaded DRS calibration from "+string(fname));
514 DataCalib::Update(fDimDrsCalibration, fDimDrsRuns);
515 }
516
517 virtual int CloseOpenFiles() { CloseRunFile(0, 0, 0); return 0; }
518
519
520 /*
521 struct OpenFileToDim
522 {
523 int code;
524 char fileName[FILENAME_MAX];
525 };
526
527 SignalRunOpened(runid, filename);
528 // Send num open files
529 // Send runid, (more info about the run?), filename via dim
530
531 SignalEvtWritten(runid);
532 // Send num events written of newest file
533
534 SignalRunClose(runid);
535 // Send new num open files
536 // Send empty file-name if no file is open
537
538 */
539
540 // -------------- Mapped event builder callbacks ------------------
541
542 void UpdateRuns(const string &fname="")
543 {
544 uint32_t values[5] =
545 {
546 static_cast<uint32_t>(fFiles.size()),
547 0xffffffff,
548 0,
549 fLastOpened,
550 fLastClosed
551 };
552
553 for (vector<DataProcessorImp*>::const_iterator it=fFiles.begin();
554 it!=fFiles.end(); it++)
555 {
556 const DataProcessorImp *file = *it;
557
558 if (file->GetRunId()<values[1])
559 values[1] = file->GetRunId();
560
561 if (file->GetRunId()>values[2])
562 values[2] = file->GetRunId();
563 }
564
565 fMaxRun = values[2];
566
567 vector<char> data(sizeof(values)+fname.size()+1);
568 memcpy(data.data(), values, sizeof(values));
569 strcpy(data.data()+sizeof(values), fname.c_str());
570
571 fDimRuns.Update(data);
572 }
573
574 vector<DataProcessorImp*> fFiles;
575
576 FileHandle_t runOpen(uint32_t runid, RUN_HEAD *h, size_t)
577 {
578 //fMsg.Info(" ==> TODO: Update run configuration in database!");
579
580 map<uint32_t,FAD::RunDescription>::iterator it = fExpectedRuns.begin();
581 while (it!=fExpectedRuns.end())
582 {
583 if (it->first<runid)
584 {
585 ostringstream str;
586 str << "runOpen - Missed run " << it->first << ".";
587 fMsg.Info(str);
588
589 fExpectedRuns.erase(it++);
590 continue;
591 }
592 if (it->first==runid)
593 break;
594 it++;
595 }
596
597 FAD::RunDescription desc;
598
599 if (it==fExpectedRuns.end())
600 {
601 ostringstream str;
602 str << "runOpen - Run " << runid << " wasn't expected (maybe manual triggers)";
603 fMsg.Warn(str);
604 }
605 else
606 {
607 desc = it->second;
608 fExpectedRuns.erase(it);
609 }
610
611 // Check if file already exists...
612 DataProcessorImp *file = 0;
613 switch (fFileFormat)
614 {
615 case FAD::kNone: file = new DataDump(fPath, runid, fMsg); break;
616 case FAD::kDebug: file = new DataDebug(fPath, runid, fMsg); break;
617 case FAD::kCfitsio: file = new DataWriteFits(fPath, runid, fMsg); break;
618 case FAD::kFits: file = new DataWriteFits2(fPath, runid, fMsg); break;
619 case FAD::kRaw: file = new DataWriteRaw(fPath, runid, fMsg); break;
620 case FAD::kCalib: file = new DataCalib(fPath, runid, fDimDrsCalibration, fDimDrsRuns, fMsg); break;
621 }
622
623 try
624 {
625 if (!file->Open(h, desc))
626 return 0;
627 }
628 catch (const exception &e)
629 {
630 fMsg.Error("Exception trying to open file: "+string(e.what()));
631 return 0;
632 }
633
634 fFiles.push_back(file);
635
636 ostringstream str;
637 str << "Opened: " << file->GetFileName() << " (" << file->GetRunId() << ")";
638 fMsg.Info(str);
639
640 fDimWriteStats.FileOpened(file->GetFileName());
641
642 fLastOpened = runid;
643 UpdateRuns(file->GetFileName());
644
645 fNumEvts[kEventId] = 0;
646 fNumEvts[kTriggerId] = 0;
647
648 fNumEvts[kCurrent] = 0;
649 fDimEvents.Update(fNumEvts);
650 // fDimCurrentEvent.Update(uint32_t(0));
651
652 return reinterpret_cast<FileHandle_t>(file);
653 }
654
655 int runWrite(FileHandle_t handler, EVENT *e, size_t /*sz*/)
656 {
657 DataProcessorImp *file = reinterpret_cast<DataProcessorImp*>(handler);
658
659 if (!file->WriteEvt(e))
660 return -1;
661
662 if (file->GetRunId()==fMaxRun)
663 {
664 fNumEvts[kCurrent]++;
665 fNumEvts[kEventId] = e->EventNum;
666 fNumEvts[kTriggerId] = e->TriggerNum;
667 }
668
669 fNumEvts[kTotal]++;
670
671 static Time oldt(boost::date_time::neg_infin);
672 Time newt;
673 if (newt>oldt+boost::posix_time::seconds(1))
674 {
675 fDimEvents.Update(fNumEvts);
676 oldt = newt;
677 }
678
679
680 // ===> SignalEvtWritten(runid);
681 // Send num events written of newest file
682
683 /* close run runId (all all runs if runId=0) */
684 /* return: 0=close scheduled / >0 already closed / <0 does not exist */
685 //CloseRunFile(file->GetRunId(), time(NULL)+2) ;
686
687 return 0;
688 }
689
690 virtual void CloseRun(uint32_t /*runid*/) { }
691
692 int runClose(FileHandle_t handler, RUN_TAIL *tail, size_t)
693 {
694 //fMsg.Info(" ==> TODO: Update run configuration in database!");
695
696 DataProcessorImp *file = reinterpret_cast<DataProcessorImp*>(handler);
697
698 const vector<DataProcessorImp*>::iterator it = find(fFiles.begin(), fFiles.end(), file);
699 if (it==fFiles.end())
700 {
701 ostringstream str;
702 str << "File handler (" << handler << ") requested to close by event builder doesn't exist.";
703 fMsg.Fatal(str);
704 return -1;
705 }
706
707 fFiles.erase(it);
708
709 fLastClosed = file->GetRunId();
710 CloseRun(fLastClosed);
711 UpdateRuns();
712
713 fDimEvents.Update(fNumEvts);
714
715 const bool rc = file->Close(tail);
716 if (!rc)
717 {
718 // Error message
719 }
720
721 ostringstream str;
722 str << "Closed: " << file->GetFileName() << " (" << file->GetRunId() << ")";
723 fMsg.Info(str);
724
725 delete file;
726
727 // ==> SignalRunClose(runid);
728 // Send new num open files
729 // Send empty file-name if no file is open
730
731 return rc ? 0 : -1;
732 }
733
734 ofstream fDumpStream[40];
735
736 void debugStream(int isock, void *buf, int len)
737 {
738 if (!fDebugStream)
739 return;
740
741 const int slot = isock/7;
742 if (slot<0 || slot>39)
743 return;
744
745 if (!fDumpStream[slot].is_open())
746 {
747 ostringstream name;
748 name << "socket_dump-" << setfill('0') << setw(2) << slot << ".bin";
749
750 fDumpStream[slot].open(name.str().c_str(), ios::app);
751 if (!fDumpStream[slot])
752 {
753 ostringstream str;
754 str << "Open file '" << name << "': " << strerror(errno) << " (errno=" << errno << ")";
755 fMsg.Error(str);
756
757 return;
758 }
759
760 fMsg.Message("Opened file '"+name.str()+"' for writing.");
761 }
762
763 fDumpStream[slot].write(reinterpret_cast<const char*>(buf), len);
764 }
765
766 ofstream fDumpRead; // Stream to possibly dump docket events
767
768 void debugRead(int isock, int ibyte, uint32_t event, uint32_t ftmevt, uint32_t runno, int state, uint32_t tsec, uint32_t tusec)
769 {
770 // isock = socketID (0-279)
771 // ibyte = #bytes gelesen
772 // event = eventId (oder 0 wenn noch nicht bekannt)
773 // state : 1=finished reading data
774 // 0=reading data
775 // -1=start reading data (header)
776 // -2=start reading data,
777 // eventId not known yet (too little data)
778 // tsec, tusec = time when reading seconds, microseconds
779 //
780 if (!fDebugRead || ibyte==0)
781 return;
782
783 if (!fDumpRead.is_open())
784 {
785 fDumpRead.open("socket_events.txt", ios::app);
786 if (!fDumpRead)
787 {
788 ostringstream str;
789 str << "Open file 'socket_events.txt': " << strerror(errno) << " (errno=" << errno << ")";
790 fMsg.Error(str);
791
792 return;
793 }
794
795 fMsg.Message("Opened file 'socket_events.txt' for writing.");
796
797 fDumpRead << "# START: " << Time().GetAsStr() << endl;
798 fDumpRead << "# state time_sec time_usec socket slot runno event_id trigger_id bytes_received" << endl;
799 }
800
801 fDumpRead
802 << setw(2) << state << " "
803 << setw(8) << tsec << " "
804 << setw(9) << tusec << " "
805 << setw(3) << isock << " "
806 << setw(2) << isock/7 << " "
807 << runno << " "
808 << event << " "
809 << ftmevt << " "
810 << ibyte << endl;
811 }
812
813 array<uint16_t,2> fVecRoi;
814
815 int eventCheck(uint32_t runNr, PEVNT_HEADER *fadhd, EVENT *event, int /*iboard*/)
816 {
817 /*
818 fadhd[i] ist ein array mit den 40 fad-headers
819 (falls ein board nicht gelesen wurde, ist start_package_flag =0 )
820
821 event ist die Struktur, die auch die write routine erhaelt;
822 darin sind im header die 'soll-werte' fuer z.B. eventID
823 als auch die ADC-Werte (falls Du die brauchst)
824
825 Wenn die routine einen negativen Wert liefert, wird das event
826 geloescht (nicht an die write-routine weitergeleitet [mind. im Prinzip]
827 */
828
829 const array<uint16_t,2> roi = {{ event->Roi, event->RoiTM }};
830
831 if (roi!=fVecRoi)
832 {
833 Update(fDimRoi, roi);
834 fVecRoi = roi;
835 }
836
837 const FAD::EventHeader *beg = reinterpret_cast<FAD::EventHeader*>(fadhd);
838 const FAD::EventHeader *end = reinterpret_cast<FAD::EventHeader*>(fadhd)+40;
839
840 // FIMXE: Compare with target configuration
841
842 for (const FAD::EventHeader *ptr=beg; ptr!=end; ptr++)
843 {
844 // FIXME: Compare with expectations!!!
845 if (ptr->fStartDelimiter==0)
846 {
847 if (ptr==beg)
848 beg++;
849 continue;
850 }
851
852 if (beg->fStatus != ptr->fStatus)
853 {
854 fMsg.Error("Inconsistency in FAD status detected.... closing run.");
855 CloseRunFile(runNr, 0, 0);
856 return -1;
857 }
858
859 if (beg->fRunNumber != ptr->fRunNumber)
860 {
861 fMsg.Error("Inconsistent run number detected.... closing run.");
862 CloseRunFile(runNr, 0, 0);
863 return -1;
864 }
865
866 /*
867 if (beg->fVersion != ptr->fVersion)
868 {
869 Error("Inconsist firmware version detected.... closing run.");
870 CloseRunFile(runNr, 0, 0);
871 break;
872 }
873 */
874 if (beg->fEventCounter != ptr->fEventCounter)
875 {
876 fMsg.Error("Inconsistent FAD event number detected.... closing run.");
877 CloseRunFile(runNr, 0, 0);
878 return -1;
879 }
880
881 if (beg->fTriggerCounter != ptr->fTriggerCounter)
882 {
883 fMsg.Error("Inconsistent FTM trigger number detected.... closing run.");
884 CloseRunFile(runNr, 0, 0);
885 return -1;
886 }
887
888 if (beg->fAdcClockPhaseShift != ptr->fAdcClockPhaseShift)
889 {
890 fMsg.Error("Inconsistent phase shift detected.... closing run.");
891 CloseRunFile(runNr, 0, 0);
892 return -1;
893 }
894
895 if (memcmp(beg->fDac, ptr->fDac, sizeof(beg->fDac)))
896 {
897 fMsg.Error("Inconsistent DAC values detected.... closing run.");
898 CloseRunFile(runNr, 0, 0);
899 return -1;
900 }
901
902 if (beg->fTriggerType != ptr->fTriggerType)
903 {
904 fMsg.Error("Inconsistent trigger type detected.... closing run.");
905 CloseRunFile(runNr, 0, 0);
906 return -1;
907 }
908 }
909
910 // check REFCLK_frequency
911 // check consistency with command configuration
912 // how to log errors?
913 // need gotNewRun/closedRun to know it is finished
914
915 return 0;
916 }
917
918 void SendRawData(PEVNT_HEADER *fadhd, EVENT *event)
919 {
920 // Currently we send any event no matter what its trigger id is...
921 // To be changed.
922 static Time oldt(boost::date_time::neg_infin);
923 Time newt;
924
925 static int skip = 0;
926
927 // FIXME: Only send events if the have newer run-numbers
928 if (newt<oldt+boost::posix_time::milliseconds(skip>0 ? 100 : 1000))
929 return;
930 oldt = newt;
931
932 // Workaround to find a valid header.....
933 const FAD::EventHeader *beg = reinterpret_cast<FAD::EventHeader*>(fadhd);
934 const FAD::EventHeader *end = reinterpret_cast<FAD::EventHeader*>(fadhd)+40;
935
936 // FIMXE: Compare with target configuration
937 const FAD::EventHeader *ptr=beg;
938 for (; ptr!=end; ptr++)
939 {
940 if (ptr->fStartDelimiter!=0)
941 break;
942 }
943 if (ptr==end)
944 return;
945
946
947 vector<char> data(sizeof(EVENT)+event->Roi*sizeof(float)*(1440+160));
948 memcpy(data.data(), event, sizeof(EVENT));
949
950 float *vec = reinterpret_cast<float*>(data.data()+sizeof(EVENT));
951
952 DataCalib::Apply(vec, event->Adc_Data, event->StartPix, event->Roi);
953 DrsCalibrate::RemoveSpikes(vec, event->Roi);
954
955 vector<float> data2(1440*4); // Mean, RMS, Max, Pos
956 const double max = DrsCalibrate::GetPixelStats(data2.data(), vec, event->Roi);
957
958 // Maximum above roughly 5pe
959 if (ptr->IsTriggerPhys() && max<100 && skip<10)
960 {
961 skip++;
962 return;
963 }
964
965 skip = 0;
966
967 fDimRawData.setQuality(ptr->fTriggerType);
968 fDimRawData.Update(data);
969
970 fDimEventData.setQuality(ptr->fTriggerType);
971 fDimEventData.Update(data2);
972 }
973
974 void SendFeedbackData(PEVNT_HEADER *fadhd, EVENT *event)
975 {
976 if (!DataCalib::IsValid())
977 return;
978
979 // Workaround to find a valid header.....
980 const FAD::EventHeader *beg = reinterpret_cast<FAD::EventHeader*>(fadhd);
981 const FAD::EventHeader *end = reinterpret_cast<FAD::EventHeader*>(fadhd)+40;
982
983 // FIMXE: Compare with target configuration
984
985 const FAD::EventHeader *ptr=beg;
986 for (; ptr<end; ptr++)
987 {
988 if (ptr->fStartDelimiter!=0)
989 break;
990 }
991
992 if (ptr==end)
993 return;
994
995 if (!ptr->HasTriggerLPext() && !ptr->HasTriggerLPint())
996 return;
997
998 vector<float> data(event->Roi*1440);
999 DataCalib::Apply(data.data(), event->Adc_Data, event->StartPix, event->Roi);
1000
1001 DrsCalibrate::RemoveSpikes(data.data(), event->Roi);
1002
1003 vector<float> data2(1440); // Mean, RMS, Max, Pos, first, last
1004 DrsCalibrate::GetPixelMax(data2.data(), data.data(), event->Roi, 0, event->Roi-1);
1005
1006 fDimFeedbackData.Update(data2);
1007 }
1008
1009 int subProcEvt(int threadID, PEVNT_HEADER *fadhd, EVENT *event, int16_t /*iboard*/, void */*buffer*/)
1010 {
1011 switch (threadID)
1012 {
1013 case 0:
1014 SendRawData(fadhd, event);
1015 return 1;
1016 case 1:
1017 SendFeedbackData(fadhd, event);
1018 return 2;
1019 }
1020 return 100;
1021 }
1022
1023
1024 bool IsRunStarted() const
1025 {
1026 const set<uint32_t>::const_iterator it = fIsRunStarted.find(fRunNumber-1);
1027 return it==fIsRunStarted.end();// ? true : it->second.started;
1028 }
1029
1030 uint32_t GetRunNumber() const
1031 {
1032 return fRunNumber;
1033 }
1034
1035 void IncreaseRunNumber(uint32_t run)
1036 {
1037 if (run>fRunNumber)
1038 fRunNumber = run;
1039 }
1040
1041 void gotNewRun(uint32_t runnr, PEVNT_HEADER */*headers*/)
1042 {
1043 // This function is called even when writing is switched off
1044 set<uint32_t>::iterator it = fIsRunStarted.begin();
1045 while (it!=fIsRunStarted.end())
1046 {
1047 if (*it<runnr)
1048 {
1049 ostringstream str;
1050 str << "gotNewRun - Missed run " << *it << ".";
1051 fMsg.Info(str);
1052
1053 fIsRunStarted.erase(it++);
1054 continue;
1055 }
1056 if (*it==runnr)
1057 break;
1058 it++;
1059 }
1060 if (it==fIsRunStarted.end())
1061 {
1062 ostringstream str;
1063 str << "gotNewRun - Not waiting for run " << runnr << ".";
1064 fMsg.Warn(str);
1065 return;
1066 }
1067
1068 map<uint32_t,FAD::RunDescription>::iterator i2 = fExpectedRuns.find(runnr);
1069 if (i2==fExpectedRuns.end())
1070 {
1071 ostringstream str;
1072 str << "gotNewRun - Run " << runnr << " wasn't expected.";
1073 fMsg.Warn(str);
1074 return;
1075 }
1076
1077 CloseRunFile(runnr, time(NULL)+i2->second.maxtime, i2->second.maxevt);
1078 // return: 0=close scheduled / >0 already closed / <0 does not exist
1079
1080 // FIXME: Move configuration from expected runs to runs which will soon
1081 // be opened/closed
1082
1083 fIsRunStarted.erase(it);
1084 }
1085
1086 map<boost::thread::id, string> fLastMessage;
1087
1088 void factOut(int severity, int err, const char *message)
1089 {
1090 if (!fDebugLog && severity==99)
1091 return;
1092
1093 ostringstream str;
1094 //str << boost::this_thread::get_id() << " ";
1095 str << "EventBuilder(";
1096 if (err<0)
1097 str << "---";
1098 else
1099 str << err;
1100 str << "): " << message;
1101
1102 string &old = fLastMessage[boost::this_thread::get_id()];
1103
1104 if (str.str()==old)
1105 return;
1106 old = str.str();
1107
1108 fMsg.Update(str, severity);
1109 }
1110/*
1111 void factStat(int64_t *stat, int len)
1112 {
1113 if (len!=7)
1114 {
1115 fMsg.Warn("factStat received unknown number of values.");
1116 return;
1117 }
1118
1119 vector<int64_t> data(1, g_maxMem);
1120 data.insert(data.end(), stat, stat+len);
1121
1122 static vector<int64_t> last(8);
1123 if (data==last)
1124 return;
1125 last = data;
1126
1127 fDimStatistics.Update(data);
1128
1129 // len ist die Laenge des arrays.
1130 // array[4] enthaelt wieviele bytes im Buffer aktuell belegt sind; daran
1131 // kannst Du pruefen, ob die 100MB voll sind ....
1132
1133 ostringstream str;
1134 str
1135 << "Wait=" << stat[0] << " "
1136 << "Skip=" << stat[1] << " "
1137 << "Del=" << stat[2] << " "
1138 << "Tot=" << stat[3] << " "
1139 << "Mem=" << stat[4] << "/" << g_maxMem << " "
1140 << "Read=" << stat[5] << " "
1141 << "Conn=" << stat[6];
1142
1143 fMsg.Info(str);
1144 }
1145 */
1146
1147 void factStat(const EVT_STAT &stat)
1148 {
1149 fDimStatistics2.Update(stat);
1150 }
1151
1152 void factStat(const GUI_STAT &stat)
1153 {
1154 fDimStatistics1.Update(stat);
1155 }
1156
1157
1158 array<FAD::EventHeader, 40> fVecHeader;
1159
1160 template<typename T, class S>
1161 array<T, 42> Compare(const S *vec, const T *t)
1162 {
1163 const int offset = reinterpret_cast<const char *>(t) - reinterpret_cast<const char *>(vec);
1164
1165 const T *min = NULL;
1166 const T *val = NULL;
1167 const T *max = NULL;
1168
1169 array<T, 42> arr;
1170
1171 // bool rc = true;
1172 for (int i=0; i<40; i++)
1173 {
1174 const char *base = reinterpret_cast<const char*>(vec+i);
1175 const T *ref = reinterpret_cast<const T*>(base+offset);
1176
1177 arr[i] = *ref;
1178
1179 if (gi_NumConnect[i]!=7)
1180 {
1181 arr[i] = 0;
1182 continue;
1183 }
1184
1185 if (!val)
1186 {
1187 min = ref;
1188 val = ref;
1189 max = ref;
1190 }
1191
1192 if (*ref<*min)
1193 min = ref;
1194
1195 if (*ref>*max)
1196 max = ref;
1197
1198 // if (*val!=*ref)
1199 // rc = false;
1200 }
1201
1202 arr[40] = val ? *min : 1;
1203 arr[41] = val ? *max : 0;
1204
1205 return arr;
1206 }
1207
1208 template<typename T>
1209 array<T, 42> CompareBits(const FAD::EventHeader *h, const T *t)
1210 {
1211 const int offset = reinterpret_cast<const char *>(t) - reinterpret_cast<const char *>(h);
1212
1213 T val = 0;
1214 T rc = 0;
1215
1216 array<T, 42> vec;
1217
1218 bool first = true;
1219
1220 for (int i=0; i<40; i++)
1221 {
1222 const char *base = reinterpret_cast<const char*>(&fVecHeader[i]);
1223 const T *ref = reinterpret_cast<const T*>(base+offset);
1224
1225 vec[i+2] = *ref;
1226
1227 if (gi_NumConnect[i]!=7)
1228 {
1229 vec[i+2] = 0;
1230 continue;
1231 }
1232
1233 if (first)
1234 {
1235 first = false;
1236 val = *ref;
1237 rc = 0;
1238 }
1239
1240 rc |= val^*ref;
1241 }
1242
1243 vec[0] = rc;
1244 vec[1] = val;
1245
1246 return vec;
1247 }
1248
1249 template<typename T, size_t N>
1250 void Update(DimDescribedService &svc, const array<T, N> &data, int n=N)
1251 {
1252// svc.setQuality(vec[40]<=vec[41]);
1253 svc.setData(const_cast<T*>(data.data()), sizeof(T)*n);
1254 svc.Update();
1255 }
1256
1257 template<typename T>
1258 void Print(const char *name, const pair<bool,array<T, 43>> &data)
1259 {
1260 cout << name << "|" << data.first << "|" << data.second[1] << "|" << data.second[0] << "<x<" << data.second[1] << ":";
1261 for (int i=0; i<40;i++)
1262 cout << " " << data.second[i+3];
1263 cout << endl;
1264 }
1265
1266 vector<uint> fNumConnected;
1267
1268 void debugHead(int /*socket*/, const FAD::EventHeader &h)
1269 {
1270 const uint16_t id = h.Id();
1271 if (id>39)
1272 return;
1273
1274 if (fNumConnected.size()!=40)
1275 fNumConnected.resize(40);
1276
1277 const vector<uint> con(gi_NumConnect, gi_NumConnect+40);
1278
1279 const bool changed = con!=fNumConnected || !IsThreadRunning();
1280
1281 fNumConnected = con;
1282
1283 const FAD::EventHeader old = fVecHeader[id];
1284 fVecHeader[id] = h;
1285
1286 if (old.fVersion != h.fVersion || changed)
1287 {
1288 const array<uint16_t,42> ver = Compare(&fVecHeader[0], &fVecHeader[0].fVersion);
1289
1290 array<float,42> data;
1291 for (int i=0; i<42; i++)
1292 {
1293 ostringstream str;
1294 str << (ver[i]>>8) << '.' << (ver[i]&0xff);
1295 data[i] = stof(str.str());
1296 }
1297 Update(fDimFwVersion, data);
1298 }
1299
1300 if (old.fRunNumber != h.fRunNumber || changed)
1301 {
1302 const array<uint32_t,42> run = Compare(&fVecHeader[0], &fVecHeader[0].fRunNumber);
1303 fDimRunNumber.Update(run);
1304 }
1305
1306 if (old.fTriggerGeneratorPrescaler != h.fTriggerGeneratorPrescaler || changed)
1307 {
1308 const array<uint16_t,42> pre = Compare(&fVecHeader[0], &fVecHeader[0].fTriggerGeneratorPrescaler);
1309 fDimPrescaler.Update(pre);
1310 }
1311
1312 if (old.fDNA != h.fDNA || changed)
1313 {
1314 const array<uint64_t,42> dna = Compare(&fVecHeader[0], &fVecHeader[0].fDNA);
1315 Update(fDimDNA, dna, 40);
1316 }
1317
1318 if (old.fStatus != h.fStatus || changed)
1319 {
1320 const array<uint16_t,42> sts = CompareBits(&fVecHeader[0], &fVecHeader[0].fStatus);
1321 Update(fDimStatus, sts);
1322 }
1323
1324 if (memcmp(old.fDac, h.fDac, sizeof(h.fDac)) || changed)
1325 {
1326 array<uint16_t, FAD::kNumDac*42> dacs;
1327
1328 for (int i=0; i<FAD::kNumDac; i++)
1329 {
1330 const array<uint16_t, 42> dac = Compare(&fVecHeader[0], &fVecHeader[0].fDac[i]);
1331 memcpy(&dacs[i*42], &dac[0], sizeof(uint16_t)*42);
1332 }
1333
1334 Update(fDimDac, dacs);
1335 }
1336
1337 // -----------
1338
1339 static Time oldt(boost::date_time::neg_infin);
1340 Time newt;
1341
1342 if (newt>oldt+boost::posix_time::seconds(1))
1343 {
1344 oldt = newt;
1345
1346 // --- RefClock
1347
1348 const array<uint32_t,42> clk = Compare(&fVecHeader[0], &fVecHeader[0].fFreqRefClock);
1349 Update(fDimRefClock, clk);
1350
1351 // --- Temperatures
1352
1353 const array<int16_t,42> tmp[4] =
1354 {
1355 Compare(&fVecHeader[0], &fVecHeader[0].fTempDrs[0]), // 0-39:val, 40:min, 41:max
1356 Compare(&fVecHeader[0], &fVecHeader[0].fTempDrs[1]), // 0-39:val, 40:min, 41:max
1357 Compare(&fVecHeader[0], &fVecHeader[0].fTempDrs[2]), // 0-39:val, 40:min, 41:max
1358 Compare(&fVecHeader[0], &fVecHeader[0].fTempDrs[3]) // 0-39:val, 40:min, 41:max
1359 };
1360
1361 vector<int16_t> data;
1362 data.reserve(82);
1363 data.push_back(tmp[0][40]); // min: 0
1364 data.insert(data.end(), tmp[0].data(), tmp[0].data()+40); // val: 1-40
1365 data.push_back(tmp[0][41]); // max: 41
1366 data.insert(data.end(), tmp[0].data(), tmp[0].data()+40); // val: 42-81
1367
1368 for (int j=1; j<=3; j++)
1369 {
1370 const array<int16_t,42> &ref = tmp[j];
1371
1372 // Gloabl min
1373 if (ref[40]<data[0]) // 40=min
1374 data[0] = ref[40];
1375
1376 // Global max
1377 if (ref[41]>data[41]) // 41=max
1378 data[41] = ref[41];
1379
1380 for (int i=0; i<40; i++)
1381 {
1382 // min per board
1383 if (ref[i]<data[i+1]) // data: 1-40
1384 data[i+1] = ref[i]; // ref: 0-39
1385
1386 // max per board
1387 if (ref[i]>data[i+42]) // data: 42-81
1388 data[i+42] = ref[i]; // ref: 0-39
1389 }
1390
1391
1392 }
1393
1394 vector<float> deg(82); // 0: global min, 1-40: min
1395 for (int i=0; i<82; i++) // 41: global max, 42-81: max
1396 deg[i] = data[i]/16.;
1397 fDimTemperature.Update(deg);
1398 }
1399 }
1400};
1401
1402EventBuilderWrapper *EventBuilderWrapper::This = 0;
1403
1404// ----------- Event builder callbacks implementation ---------------
1405extern "C"
1406{
1407 FileHandle_t runOpen(uint32_t irun, RUN_HEAD *runhd, size_t len)
1408 {
1409 return EventBuilderWrapper::This->runOpen(irun, runhd, len);
1410 }
1411
1412 int runWrite(FileHandle_t fileId, EVENT *event, size_t len)
1413 {
1414 return EventBuilderWrapper::This->runWrite(fileId, event, len);
1415 }
1416
1417 int runClose(FileHandle_t fileId, RUN_TAIL *runth, size_t len)
1418 {
1419 return EventBuilderWrapper::This->runClose(fileId, runth, len);
1420 }
1421
1422 // -----
1423
1424 //void *runStart(uint32_t /*irun*/, RUN_HEAD */*runhd*/, size_t /*len*/)
1425 //{
1426 // return NULL;
1427 //}
1428
1429 int subProcEvt(int threadID, PEVNT_HEADER *fadhd, EVENT *event, int16_t mboard, void *runPtr)
1430 {
1431 return EventBuilderWrapper::This->subProcEvt(threadID, fadhd, event, mboard, runPtr);
1432 }
1433
1434 int runEnd(uint32_t, void */*runPtr*/)
1435 {
1436 return 0;
1437 }
1438
1439 // -----
1440
1441 int eventCheck(uint32_t runNr, PEVNT_HEADER *fadhd, EVENT *event, int mboard)
1442 {
1443 return EventBuilderWrapper::This->eventCheck(runNr, fadhd, event, mboard);
1444 }
1445
1446 void gotNewRun(uint32_t runnr, PEVNT_HEADER *headers)
1447 {
1448 return EventBuilderWrapper::This->gotNewRun(runnr, headers);
1449 }
1450
1451 // -----
1452
1453 void factOut(int severity, int err, const char *message)
1454 {
1455 EventBuilderWrapper::This->factOut(severity, err, message);
1456 }
1457
1458 void factStat(GUI_STAT stat)
1459 {
1460 EventBuilderWrapper::This->factStat(stat);
1461 }
1462
1463 void factStatNew(EVT_STAT stat)
1464 {
1465 EventBuilderWrapper::This->factStat(stat);
1466 }
1467
1468 // ------
1469
1470 void debugHead(int socket, int/*board*/, void *buf)
1471 {
1472 const FAD::EventHeader &h = *reinterpret_cast<FAD::EventHeader*>(buf);
1473 EventBuilderWrapper::This->debugHead(socket, h);
1474 }
1475
1476 void debugStream(int isock, void *buf, int len)
1477 {
1478 return EventBuilderWrapper::This->debugStream(isock, buf, len);
1479 }
1480
1481 void debugRead(int isock, int ibyte, int32_t event, int32_t ftmevt, int32_t runno, int state, uint32_t tsec, uint32_t tusec)
1482 {
1483 EventBuilderWrapper::This->debugRead(isock, ibyte, event, ftmevt, runno, state, tsec, tusec);
1484 }
1485}
1486
1487#endif
Note: See TracBrowser for help on using the repository browser.