REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestRawUSTCToSignalProcess.cxx
1/*************************************************************************
2 * This file is part of the REST software framework. *
3 * *
4 * Copyright (C) 2016 GIFNA/TREX (University of Zaragoza) *
5 * For more information see http://gifna.unizar.es/trex *
6 * *
7 * REST is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 3 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * REST is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have a copy of the GNU General Public License along with *
18 * REST in $REST_PATH/LICENSE. *
19 * If not, see http://www.gnu.org/licenses/. *
20 * For the list of contributors see $REST_PATH/CREDITS. *
21 *************************************************************************/
22
59
60// int counter = 0;
61
62#include "TRestRawUSTCToSignalProcess.h"
63
64using namespace std;
65
66#include <bitset>
67
68#include "TTimeStamp.h"
69
71
72TRestRawUSTCToSignalProcess::TRestRawUSTCToSignalProcess() { Initialize(); }
73
74TRestRawUSTCToSignalProcess::TRestRawUSTCToSignalProcess(const char* configFilename) { Initialize(); }
75
76TRestRawUSTCToSignalProcess::~TRestRawUSTCToSignalProcess() {
77 // TRestRawUSTCToSignalProcess destructor
78}
79
82
83 SetSectionName(this->ClassName());
84 SetLibraryVersion(LIBRARY_VERSION);
85}
86
88 fEventBuffer.clear();
89 errorevents.clear();
90 unknownerrors = 0;
91 fLastBufferedId = 0;
92
93#ifndef Incoherent_Event_Generation
94 nBufferedEvent = StringToInteger(GetParameter("BufferNumber", "2"));
95 if (nBufferedEvent < 1) nBufferedEvent = 1;
96#else
97 nBufferedEvent = 2;
98#endif // !Incoherent_Readout
99
100 for (int n = 0; n < nBufferedEvent + 1; n++) {
101 fEventBuffer.push_back(vector<USTCDataFrame>());
102 }
103
104 fRunOrigin = fRunInfo->GetRunNumber();
105 fCurrentFile = 0;
106 fCurrentBuffer = 0;
107 totalbytesRead = 0;
108
109 USTCDataFrame frame;
110 if ((!GetNextFrame(frame)) || (!ReadFrameData(frame))) {
111 FixToNextFrame(fInputFiles[fCurrentFile]);
112 if ((!GetNextFrame(frame)) || (!ReadFrameData(frame))) {
113 RESTError << "TRestRawUSTCToSignalProcess: Failed to read the first data "
114 "frame in file, may be wrong "
115 "input?"
116 << RESTendl;
117 exit(1);
118 }
119 }
120
121 fCurrentEvent = frame.evId;
122 AddBuffer(frame);
123
124 if (fCurrentEvent != 0) {
125 RESTWarning << "TRestRawUSTCToSignalProcess : first event is not with id 0 !" << RESTendl;
126 RESTWarning << "The first Id is " << fCurrentEvent << ". May be input file not the first file?"
127 << RESTendl;
128 }
129}
130
132 while (1) {
133 if (EndReading()) {
134 return nullptr;
135 }
136 if (!FillBuffer()) {
137 fSignalEvent->SetOK(false);
138 }
139 if (fEventBuffer[fCurrentBuffer].size() == 0) {
140 RESTDebug << "Blank event " << fCurrentEvent << " !" << RESTendl;
141 fCurrentEvent++;
142 ClearBuffer();
143 } else {
144 break;
145 }
146 }
147
148 fSignalEvent->Initialize();
149 fSignalEvent->SetID(fCurrentEvent);
150
151 RESTDebug << "------------------------------------" << RESTendl;
152 RESTDebug << "Generating event with ID: " << fCurrentEvent << RESTendl;
153
154 // some event level operation
155 USTCDataFrame* frame0 = &fEventBuffer[fCurrentBuffer][0];
156 TTimeStamp tSt = 0;
157 Long64_t evtTime = frame0->eventTime;
158 tSt.SetNanoSec((fTimeOffset + evtTime) % ((Long64_t)1e9));
159 tSt.SetSec((fTimeOffset + evtTime) / ((Long64_t)1e9));
160
161 // some signal level operation
162 for (unsigned int i = 0; i < fEventBuffer[fCurrentBuffer].size(); i++) {
163 USTCDataFrame* frame = &fEventBuffer[fCurrentBuffer][i];
164 if (frame->evId == fCurrentEvent && frame->eventTime == evtTime) {
165 sgnl.Initialize();
166 sgnl.SetSignalID(frame->signalId);
167 for (int j = 0; j < 512; j++) {
168 sgnl.AddPoint((Short_t)frame->dataPoint[j]);
169 }
170 fSignalEvent->AddSignal(sgnl);
171
172 RESTDebug << "AsAdId, AgetId, chnId, max value: " << frame->boardId << ", " << frame->chipId
173 << ", " << frame->channelId << ", " << sgnl.GetMaxValue() << RESTendl;
174
175 } else {
176 RESTWarning << "TRestRawUSTCToSignalProcess : unmatched signal frame!" << RESTendl;
177 RESTWarning << "ID (supposed, received): " << fCurrentEvent << ", " << frame->evId << RESTendl;
178 RESTWarning << "Time (supposed, received) : " << evtTime << ", " << frame->eventTime << RESTendl;
179 RESTWarning << RESTendl;
180 fSignalEvent->SetOK(false);
181 fCurrentEvent++;
182 ClearBuffer();
183 return fSignalEvent;
184 }
185 }
186
187 ClearBuffer();
188
190 cout << "------------------------------------" << endl;
191 GetChar();
192 }
193 fSignalEvent->SetTimeStamp(tSt);
194 fSignalEvent->SetRunOrigin(fRunOrigin);
195 fSignalEvent->SetSubRunOrigin(fSubRunOrigin);
196
197 // cout << fSignalEvent->GetNumberOfSignals() << endl;
198 // if( fSignalEvent->GetNumberOfSignals( ) == 0 ) return nullptr;
199 fCurrentEvent++;
200
201 return fSignalEvent;
202}
203
205 for (unsigned int i = 0; i < errorevents.size(); i++) {
206 RESTWarning << "Event " << errorevents[i] << " contains error !" << RESTendl;
207 }
208 if (errorevents.size() > 0 && unknownerrors > 0) {
209 RESTWarning << "There are also " << unknownerrors << " errors from unknown events! " << RESTendl;
210 } else if (unknownerrors > 0) {
211 RESTWarning << "There are " << unknownerrors << " errors from unknown events! " << RESTendl;
212 }
213
214 errorevents.clear();
215}
216
217bool TRestRawUSTCToSignalProcess::FillBuffer() {
218#ifdef Incoherent_Event_Generation
219 bool unknowncurrentevent = false;
220 if (fEventBuffer[fCurrentBuffer].size() > 0) {
221 fCurrentEvent = fEventBuffer[fCurrentBuffer][0].evId;
222 } else {
223 unknowncurrentevent = true;
224 }
225
226 while (1)
227#else
228 while (fLastBufferedId < fCurrentEvent + ((int)fEventBuffer.size() - 1) / 2)
229#endif
230 {
231 bool errortag = false;
232 bool breaktag = false;
233 USTCDataFrame frame;
234 if (!GetNextFrame(frame)) {
235 break;
236 }
237 if (!ReadFrameData(frame)) {
238 RESTWarning << "error reading frame data in file " << fCurrentFile << RESTendl;
239 FixToNextFrame(fInputFiles[fCurrentFile]);
240 GetNextFrame(frame);
241 ReadFrameData(frame);
242 errortag = true;
243 }
244#ifdef Incoherent_Event_Generation
245 if (unknowncurrentevent) {
246 cout << frame.evId << endl;
247 fCurrentEvent = frame.evId;
248 unknowncurrentevent = false;
249 }
250
251 if (frame.evId != fCurrentEvent) {
252 breaktag = true;
253 }
254#else
255 if (frame.evId >= fCurrentEvent + ((int)fEventBuffer.size() - 1) / 2) {
256 breaktag = true;
257 }
258#endif // Incoherent_Event_Generation
259
260 if (!AddBuffer(frame)) {
261 errortag = true;
262 }
263
264 if (errortag) {
265 if (frame.evId != -1) {
266 if (errorevents.size() == 0) {
267 errorevents.push_back(frame.evId);
268 } else {
269 for (unsigned int i = 0; i < errorevents.size(); i++) {
270 if (errorevents[i] == frame.evId) {
271 break;
272 } else if (i == errorevents.size() - 1) {
273 errorevents.push_back(frame.evId);
274 break;
275 }
276 }
277 }
278
279 } else {
280 unknownerrors++;
281 }
282 }
283
284 if (breaktag) {
285 fLastBufferedId = frame.evId;
286 break;
287 }
288 }
289 for (unsigned int i = 0; i < errorevents.size(); i++) {
290 if (errorevents[i] == fCurrentEvent) return false;
291 }
292 return true;
293}
294
295bool TRestRawUSTCToSignalProcess::OpenNextFile(USTCDataFrame& frame) {
296 if (fCurrentFile < (int)fInputFiles.size() - 1) // try to get frame form next file
297 {
298 fCurrentFile++;
299 return GetNextFrame(frame);
300 } else {
301 return false;
302 }
303}
304
305bool TRestRawUSTCToSignalProcess::GetNextFrame(USTCDataFrame& frame) {
306 if (fInputFiles[fCurrentFile] == nullptr) {
307 return OpenNextFile(frame);
308 }
309#ifdef V4_Readout_Format
310 while (1) {
311 UChar_t Protocol[PROTOCOL_SIZE];
312 if (fread(Protocol, PROTOCOL_SIZE, 1, fInputFiles[fCurrentFile]) != 1 ||
313 feof(fInputFiles[fCurrentFile])) {
314 fclose(fInputFiles[fCurrentFile]);
315 fInputFiles[fCurrentFile] = nullptr;
316 return OpenNextFile(frame);
317 }
318 totalbytesRead += PROTOCOL_SIZE;
319
320 if (!(Protocol[0] ^ 0xac) && !(Protocol[1] ^ 0x0f)) {
321 // the first 2 bytes must be 0xac0f, otherwise it is wrong
322
323 int flag = Protocol[2] >> 5;
324 if (flag & 0x1) {
325 // this is the evt_ending frame
326 memcpy(fEnding, Protocol, PROTOCOL_SIZE);
327 if (fread(fEnding + PROTOCOL_SIZE, ENDING_SIZE - PROTOCOL_SIZE, 1,
328 fInputFiles[fCurrentFile]) != 1 ||
329 feof(fInputFiles[fCurrentFile])) {
330 fclose(fInputFiles[fCurrentFile]);
331 fInputFiles[fCurrentFile] = nullptr;
332 return OpenNextFile(frame);
333 }
334 totalbytesRead += ENDING_SIZE;
335 } else if (flag & 0x2) {
336 // this is the evt_header frame
337 memcpy(fHeader, Protocol, PROTOCOL_SIZE);
338 if (fread(fHeader + PROTOCOL_SIZE, HEADER_SIZE - PROTOCOL_SIZE, 1,
339 fInputFiles[fCurrentFile]) != 1 ||
340 feof(fInputFiles[fCurrentFile])) {
341 fclose(fInputFiles[fCurrentFile]);
342 fInputFiles[fCurrentFile] = nullptr;
343 return OpenNextFile(frame);
344 }
345 totalbytesRead += HEADER_SIZE;
346 } else {
347 // this is the evt_data frame
348 memcpy(frame.data, Protocol, PROTOCOL_SIZE);
349 if (fread(frame.data + PROTOCOL_SIZE, DATA_SIZE - PROTOCOL_SIZE, 1,
350 fInputFiles[fCurrentFile]) != 1 ||
351 feof(fInputFiles[fCurrentFile])) {
352 fclose(fInputFiles[fCurrentFile]);
353 fInputFiles[fCurrentFile] = nullptr;
354 return OpenNextFile(frame);
355 }
356 totalbytesRead += DATA_SIZE;
357 return true;
358 }
359 } else {
360 return false;
361 }
362 }
363#else
364 if (fread(frame.data, DATA_SIZE, 1, fInputFiles[fCurrentFile]) != 1 || feof(fInputFiles[fCurrentFile])) {
365 fclose(fInputFiles[fCurrentFile]);
366 fInputFiles[fCurrentFile] = nullptr;
367 return OpenNextFile(frame);
368 }
369 totalbytesRead += DATA_SIZE;
370
371 if (frame.data[0] * 0x100 + frame.data[1] != 0xEEEE) {
372 RESTarning << "wrong header!" << RESTendl;
373 return false;
374 }
375#endif // V4_Readout_Format
376
377 return true;
378}
379
380// it find the next flag of frame, e.g. 0xffff or 0xac0f
381void TRestRawUSTCToSignalProcess::FixToNextFrame(FILE* f) {
382 if (f == nullptr) return;
383 UChar_t buffer[PROTOCOL_SIZE];
384 int n = 0;
385 while (1) {
386 if (fread(buffer, PROTOCOL_SIZE, 1, f) != 1 || feof(f)) {
387 return;
388 }
389 n += PROTOCOL_SIZE;
390#ifdef V4_Readout_Format
391 if (!(buffer[0] ^ 0xac) && !(buffer[1] ^ 0x0f)) {
392 int flag = buffer[2] >> 5;
393 if (flag & 0x2) {
394 // we have meet the next event header
395 memcpy(fHeader, buffer, PROTOCOL_SIZE);
396 if (fread(fHeader + PROTOCOL_SIZE, HEADER_SIZE - PROTOCOL_SIZE, 1,
397 fInputFiles[fCurrentFile]) != 1 ||
398 feof(fInputFiles[fCurrentFile])) {
399 fclose(f);
400 f = nullptr;
401 break;
402 }
403 n += HEADER_SIZE;
404 RESTWarning << "successfully switched to next frame ( + " << n << " byte)" << RESTendl;
405 RESTWarning << RESTendl;
406 break;
407 }
408 }
409#else
410 if (!(buffer[0] ^ 0xff) && !(buffer[1] ^ 0xff) && !(buffer[2] ^ 0xff) && !(buffer[3] ^ 0xff)) {
411 RESTWarning << "successfully switched to next frame ( + " << n << " byte)" << RESTendl;
412 RESTWarning << RESTendl;
413 break;
414 }
415#endif
416 }
417 totalbytesRead += n;
418}
419
420bool TRestRawUSTCToSignalProcess::ReadFrameData(USTCDataFrame& frame) {
421#ifdef V3_Readout_Format_Long
422
423 // EEEE | E0A0 | 246C 0686 4550 504E | 0001 | 2233 4455 6677 | (A098)(A09C)...
424 // | FFFF FFFF
425 // 0~1header | 2~3board number | 4~11event time | 12~13channel id(0~63)
426 // | 14~19event id | [chip id + data(0~4095)]*512 | ending
427 frame.boardId = frame.data[2] & 0x0F;
428 frame.chipId = (frame.data[3] & 0xF0) / 16 - 10;
429 frame.readoutType = frame.data[3] & 0x0F;
430 Long64_t tmp = (Long64_t)frame.data[5] * 0x10000 + (Long64_t)frame.data[6] * 0x100 +
431 (Long64_t)frame.data[7]; // we omit the first byte in case the number is too large
432 frame.eventTime = tmp * 0x100000000 + (Long64_t)frame.data[8] * 0x1000000 +
433 (Long64_t)frame.data[9] * 0x10000 + (Long64_t)frame.data[10] * 0x100 +
434 (Long64_t)frame.data[11];
435 frame.channelId = frame.data[12] * 0x100 + frame.data[13];
436 frame.evId = (frame.data[16] & 0x7F) * 0x1000000 + frame.data[17] * 0x10000 + frame.data[18] * 0x100 +
437 frame.data[19]; // we omit the first 17 bits in case the number
438 // is too large
439
440 frame.signalId = frame.boardId * 4 * 64 + frame.chipId * 64 + frame.channelId;
441#endif
442
443#ifdef V3_Readout_Format_Short
444 // EEEE | E0A0 | 246C 0686 | 0001 | 2233 | (A098)(A09C)... | FFFF
445 // 0~1header | 2~3board number | 4~7event time | 8~9channel id(0~63) |
446 // 10~11event id | [chip id + data(0~4095)]*512 | ending
447 frame.boardId = frame.data[2] & 0x0F;
448 frame.chipId = (frame.data[3] & 0xF0) / 16 - 10;
449 frame.readoutType = frame.data[3] & 0x0F;
450 Long64_t tmp = (Long64_t)frame.data[4] * 0x1000000 + (Long64_t)frame.data[5] * 0x10000 +
451 (Long64_t)frame.data[6] * 0x100 + (Long64_t)frame.data[7];
452 frame.eventTime = tmp;
453 frame.channelId = frame.data[8] * 0x100 + frame.data[9];
454 frame.evId = frame.data[10] * 256 + frame.data[11];
455
456 frame.signalId = frame.boardId * 4 * 64 + frame.chipId * 64 + frame.channelId;
457
458#endif // Long_Readout_Format
459
460#ifdef V4_Readout_Format
461
462 // the evt header frame
463 // AC0F | 401C | 0300 |
464 // 010A 3140 0000 |
465 // 0500 0000 | .... | .... | 8E95 B452 0~1Protocol | 2~3
466 // 010+size | 4~5:
467 // 00000011+ETYPE(2)+ST(1)+SOURCEID(5) | 6~11 time stamp(inverted) | 12~15
468 // event id(inverted) | not used
469 // | ending
470 frame.readoutType = fHeader[5] & 0xc0;
471
472 int t_high = fHeader[10] * 0x100 + fHeader[11];
473 int t_mid = fHeader[8] * 0x100 + fHeader[9];
474 int t_low = fHeader[6] * 0x100 + fHeader[7];
475 Long64_t tmp = (Long64_t)t_high * 0x100000000 + (Long64_t)t_mid * 0x10000 + (Long64_t)t_low;
476 frame.eventTime = tmp;
477
478 int id_high = fHeader[14] * 0x100 + fHeader[15];
479 int id_low = fHeader[12] * 0x100 + fHeader[13];
480 frame.evId = id_high * 0x10000 + id_low;
481
482 // the signal frame
483 // AC0F | 0404 | C000 | (3163)(316C)... | 0000 BCEB 5742
484 // 0~1Protocol | 2~3 not used | 4~5: 11+card(5)+chip(2)+channel(7) |
485 // [0011+data(0~4095)]*512 | ending
486 // event info(time, id, etc.) is in event header
487 frame.boardId = (frame.data[4] & 0x3e) >> 1;
488 frame.chipId = (frame.data[4] & 0x01) * 2 + (frame.data[5] >> 7);
489 frame.channelId = frame.data[5] & 0x7f;
490
491 frame.signalId = frame.boardId * 4 * 68 + frame.chipId * 68 + frame.channelId;
492
493 fChannelOffset.insert(frame.boardId * 4 * 68 + frame.chipId * 68);
494#endif
495
496 // sampling point data
497 for (int i = 0; i < 512; i++) {
498 int pos = i * 2 + DATA_OFFSET;
499 frame.dataPoint[i] = (int)((frame.data[pos] & 0x0F) * 0x100 + frame.data[pos + 1]);
500 }
501
502 // if (frame.data[DATA_SIZE - 4] * 0x1000000 + frame.data[DATA_SIZE - 3] *
503 // 0x10000 +
504 // frame.data[DATA_SIZE - 2] * 0x100 + frame.data[DATA_SIZE - 1] !=
505 // 0xFFFFFFFF) {
506 // warning << "wrong ending of frame! Event Id : " << frame.evId << "
507 // Channel Id : " << frame.channelId
508 // << endl;
509 // return false;
510 //}
511
514 return true;
515}
516
517bool TRestRawUSTCToSignalProcess::AddBuffer(USTCDataFrame& frame) {
518#ifdef Incoherent_Event_Generation
519 if (frame.evId == fCurrentEvent) {
520 fEventBuffer[fCurrentBuffer].push_back(frame);
521 } else {
522 int pos = 1 + fCurrentBuffer;
523 if (pos >= fEventBuffer.size()) pos -= fEventBuffer.size();
524 fEventBuffer[pos].push_back(frame);
525 }
526#else
527 if (frame.evId >= fCurrentEvent + (int)fEventBuffer.size()) {
528 RESTWarning << "too large event id for buffering!" << RESTendl;
529 RESTWarning << "this may due to the inconherence of event id. Increase the "
530 "buffer number!"
531 << RESTendl;
532 RESTWarning << "Current Event, Burrfering event : " << fCurrentEvent << ", " << frame.evId
533 << RESTendl;
534 return false;
535 }
536 if (frame.evId < fCurrentEvent) {
537 RESTWarning << "skipping a signal from old event!" << RESTendl;
538 RESTWarning << "the cause may be that too much events are mixing. Increase the "
539 "buffer number!"
540 << RESTendl;
541 RESTWarning << "Current Event, Burrfering event : " << fCurrentEvent << ", " << frame.evId
542 << RESTendl;
543 return false;
544 }
545 size_t pos = frame.evId - fCurrentEvent + fCurrentBuffer;
546 if (pos >= fEventBuffer.size()) pos -= fEventBuffer.size();
547 fEventBuffer[pos].push_back(frame);
548#endif
549
550 return true;
551}
552
553void TRestRawUSTCToSignalProcess::ClearBuffer() {
554 fEventBuffer[fCurrentBuffer].clear();
555 fCurrentBuffer += 1;
556 if (fCurrentBuffer >= (int)fEventBuffer.size()) {
557 fCurrentBuffer -= fEventBuffer.size();
558 }
559}
560
561Bool_t TRestRawUSTCToSignalProcess::EndReading() {
562 for (const auto& file : fInputFiles) {
563 if (file != nullptr) {
564 return false;
565 }
566 }
567
568 for (const auto& eventBuffer : fEventBuffer) {
569 if (!eventBuffer.empty()) {
570 return false;
571 }
572 }
573
574 return kTRUE;
575}
TRestRun * fRunInfo
< Pointer to TRestRun object where to find metadata.
A base class for any REST event.
Definition: TRestEvent.h:38
endl_t RESTendl
Termination flag object for TRestStringOutput.
void SetLibraryVersion(TString version)
Set the library version of this metadata class.
TRestStringOutput::REST_Verbose_Level GetVerboseLevel()
returns the verboselevel in type of REST_Verbose_Level enumerator
void SetSectionName(std::string sName)
set the section name, clear the section content
std::string GetParameter(std::string parName, TiXmlElement *e, TString defaultValue=PARAMETER_NOT_FOUND_STR)
Returns the value for the parameter named parName in the given section.
Double_t GetMaxValue()
Returns the maximum value found in the data points. It includes baseline correction.
void Initialize()
Initialization of TRestRawSignal members.
void SetSignalID(Int_t sID)
It sets the id number of the signal.
void AddPoint(Short_t)
Adds a new point to the end of the signal data array.
void Initialize() override
Making default settings.
A process to read USTC electronic binary format files generated.
TRestEvent * ProcessEvent(TRestEvent *inputEvent) override
Process one event.
void EndProcess() override
To be executed at the end of the run (outside event loop)
void InitProcess() override
To be executed at the beginning of the run (outside event loop)
void Initialize() override
Making default settings.
@ REST_Debug
+show the defined debug messages
Int_t GetChar(std::string hint="Press a KEY to continue ...")
Helps to pause the program, printing a message before pausing.
Int_t StringToInteger(std::string in)
Gets an integer from a string.