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

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