GRSISort "v4.0.0.5"
An extension of the ROOT analysis Framework
Loading...
Searching...
No Matches
TGRSIDataParser.cxx
Go to the documentation of this file.
1#include "TGRSIDataParser.h"
3
4#include "TChannel.h"
5#include "Globals.h"
6
7#include "TScalerQueue.h"
8
9#include "TEpicsFrag.h"
10#include "TParsingDiagnostics.h"
11
12#include "Rtypes.h"
13
14#include "TMidasEvent.h"
15#include "TXMLOdb.h"
16#include "TRunInfo.h"
17#include "TFragment.h"
18#include "TBadFragment.h"
19
21 : fState(EDataParserState::kGood), fIgnoreMissingChannel(TGRSIOptions::Get()->IgnoreMissingChannel())
22{
23}
24
25int TGRSIDataParser::Process(std::shared_ptr<TRawEvent> rawEvent)
26{
27 std::shared_ptr<TMidasEvent> event = std::static_pointer_cast<TMidasEvent>(rawEvent);
28 int banksize = 0;
29 void* ptr = nullptr;
30 int frags = 0;
31 try {
32 switch(event->GetEventId()) {
33 case 1:
34 event->SetBankList();
35 if((banksize = event->LocateBank(nullptr, "WFDN", &ptr)) > 0) {
36 frags = TigressDataToFragment(reinterpret_cast<uint32_t*>(ptr), banksize, event);
37 } else if((banksize = event->LocateBank(nullptr, "GRF1", &ptr)) > 0) {
38 frags = ProcessGriffin(reinterpret_cast<uint32_t*>(ptr), banksize, TGRSIDataParser::EBank::kGRF1, event);
39 } else if((banksize = event->LocateBank(nullptr, "GRF2", &ptr)) > 0) {
40 frags = ProcessGriffin(reinterpret_cast<uint32_t*>(ptr), banksize, TGRSIDataParser::EBank::kGRF2, event);
41 } else if((banksize = event->LocateBank(nullptr, "GRF3", &ptr)) > 0) {
42 frags = ProcessGriffin(reinterpret_cast<uint32_t*>(ptr), banksize, TGRSIDataParser::EBank::kGRF3, event);
43 } else if((banksize = event->LocateBank(nullptr, "GRF4", &ptr)) > 0) {
44 frags = ProcessGriffin(reinterpret_cast<uint32_t*>(ptr), banksize, TGRSIDataParser::EBank::kGRF4, event);
45 } else if((banksize = event->LocateBank(nullptr, "CAEN", &ptr)) > 0) {
46 frags = CaenPsdToFragment(reinterpret_cast<uint32_t*>(ptr), banksize, event);
47 } else if((banksize = event->LocateBank(nullptr, "CPHA", &ptr)) > 0) {
48 frags = CaenPhaToFragment(reinterpret_cast<uint32_t*>(ptr), banksize, event);
49 } else if((banksize = event->LocateBank(nullptr, "MADC", &ptr)) > 0) {
50 frags = EmmaMadcDataToFragment(reinterpret_cast<uint32_t*>(ptr), banksize, event);
51 if((banksize = event->LocateBank(nullptr, "EMMT", &ptr)) > 0) {
52 //TODO: make this smarter so that an error in processing EMMT bank doesn't reduce frags
53 frags += EmmaTdcDataToFragment(reinterpret_cast<uint32_t*>(ptr), banksize, event);
54 }
55 } else if((banksize = event->LocateBank(nullptr, "EMMT", &ptr)) > 0) {
56 frags = EmmaTdcDataToFragment(reinterpret_cast<uint32_t*>(ptr), banksize, event);
57 } else {
58 std::cout << DRED << std::endl
59 << "Unknown bank in midas event #" << event->GetSerialNumber() << ", event ID 1, bank list " << event->GetBankList() << RESET_COLOR << std::endl;
60 }
61 break;
62 case 2:
63 event->SetBankList();
64 if((banksize = event->LocateBank(nullptr, "SRAW", &ptr)) > 0) {
65 if(!TGRSIOptions::Get()->SuppressErrors()) {
66 std::cout << "Found bank \"SRAW\" of size " << banksize << std::endl;
67 }
68 frags = EmmaRawDataToFragment(reinterpret_cast<uint32_t*>(ptr), banksize, event);
69 }
70 if((banksize = event->LocateBank(nullptr, "SSUM", &ptr)) > 0) {
71 if(!TGRSIOptions::Get()->SuppressErrors()) {
72 std::cout << "Found bank \"SSUM\" of size " << banksize << std::endl;
73 }
74 frags = EmmaSumDataToFragment(reinterpret_cast<uint32_t*>(ptr), banksize, event);
75 }
76 if((banksize = event->LocateBank(nullptr, "SCLR", &ptr)) > 0) {
77 if(!TGRSIOptions::Get()->SuppressErrors()) {
78 std::cout << "Found bank \"SCLR\" of size " << banksize << std::endl;
79 }
80 }
81 break;
82 case 3:
83 if((banksize = event->LocateBank(nullptr, "CAEN", &ptr)) > 0) {
84 frags = CaenPsdToFragment(reinterpret_cast<uint32_t*>(ptr), banksize, event);
85 } else if((banksize = event->LocateBank(nullptr, "CPHA", &ptr)) > 0) {
86 frags = CaenPhaToFragment(reinterpret_cast<uint32_t*>(ptr), banksize, event);
87 } else {
88 std::cout << DRED << std::endl
89 << "Unknown bank in midas event #" << event->GetSerialNumber() << ", event ID 3, bank list \"" << event->GetBankList() << "\"" << RESET_COLOR << std::endl;
90 }
91 break;
92 case 4:
93 case 5:
94 event->SetBankList();
95 if((banksize = event->LocateBank(nullptr, "MSRD", &ptr)) > 0) {
96 EPIXToScalar(reinterpret_cast<float*>(ptr), banksize, event->GetSerialNumber(), event->GetTimeStamp());
97 // EPIXToScalar will only ever read a single fragment
98 event->IncrementGoodFrags();
99 }
100 break;
101 case 0x8001:
102 // end of file ODB
103#ifdef HAS_XML
104 auto* odb = new TXMLOdb(event->GetData(), event->GetDataSize());
105 TXMLNode* node = odb->FindPath("/Runinfo/Stop time binary");
106 if(node != nullptr) {
107 std::stringstream str(node->GetText());
108 unsigned int odbTime = 0;
109 str >> odbTime;
110 odbTime *= 10; // convert from 10 ns to 1 ns units
111 if(atoi(node->GetText()) != 0 && odbTime != event->GetTimeStamp() && !TGRSIOptions::Get()->SuppressErrors()) {
112 std::cout << "Warning, ODB stop time of last subrun (" << odbTime << ") does not match midas time of last event in this subrun (" << event->GetTimeStamp() << ")!" << std::endl;
113 }
114 TRunInfo::SetRunStop(event->GetTimeStamp());
115 }
117 delete odb;
118#endif
119 break;
120 };
121 } catch(const std::bad_alloc&) {
122 }
123
124 // if we failed to get any fragments and this is not a start-of-run or end-of-run event
125 // we print an error message (unless these are suppressed)
126 if(frags <= 0 && event->GetEventId() < 0x8000 && !TGRSIOptions::Get()->SuppressErrors()) {
127 event->SetBankList();
128 event->Print(Form("a%i", (-1 * frags) - 1));
129 }
130
131 if(frags < 0) {
132 frags = 0;
133 }
134
135 return frags;
136}
137
138int TGRSIDataParser::TigressDataToFragment(uint32_t* data, int size, std::shared_ptr<TMidasEvent>& event)
139{
140 /// Converts A MIDAS File from the Tigress DAQ into a TFragment.
141 int NumFragsFound = 0;
142 std::shared_ptr<TFragment> eventFrag = std::make_shared<TFragment>();
143 eventFrag->SetDaqTimeStamp(event->GetTimeStamp());
144 eventFrag->SetDaqId(event->GetSerialNumber());
145
146 int x = 0;
147 uint32_t dword = *(data + x);
148
149 uint32_t type = 0;
150 uint32_t value = 0;
151
152 if(!SetTIGTriggerID(dword, eventFrag)) {
153 std::cout << RED << "Setting TriggerId (" << hex(dword, 8) << ") failed on midas event: " << DYELLOW << event->GetSerialNumber() << RESET_COLOR << std::endl;
154 return -x;
155 }
156 x += 1;
157
158 // There can be a tigger bit pattern between the header and the time ! pcb.
159
160 if(!SetTIGTimeStamp((data + x), eventFrag)) {
161 std::cout << RED << x << " Setting TimeStamp failed on midas event: " << DYELLOW << event->GetSerialNumber() << RESET_COLOR << std::endl;
162 return -x;
163 }
164 // int temp_charge = 0;
165 int temp_led = 0;
166 for(; x < size; x++) {
167 dword = *(data + x);
168 type = (dword & 0xf0000000) >> 28;
169 value = (dword & 0x0fffffff);
170 switch(type) {
171 case 0x0: // raw wave forms.
172 {
173 TChannel* chan = TChannel::GetChannel(eventFrag->GetAddress(), false);
174 if(!NoWaveforms()) {
175 SetTIGWave(value, eventFrag);
176 }
177 if((chan != nullptr) && strncmp("Tr", chan->GetName(), 2) == 0) {
178 SetTIGWave(value, eventFrag);
179 } else if((chan != nullptr) && strncmp("RF", chan->GetName(), 2) == 0) {
180 SetTIGWave(value, eventFrag);
181 }
182 } break;
183 case 0x1: // trapizodal wave forms.
184 break;
185 case 0x4: // cfd values. This also ends the the fragment!
186 SetTIGCfd(value, eventFrag);
187 SetTIGLed(temp_led, eventFrag);
188 /// check whether the fragment is 'good'
189
190 if(((*(data + x + 1)) & 0xf0000000) != 0xe0000000) {
191 std::shared_ptr<TFragment> transferfrag = std::make_shared<TFragment>(*eventFrag);
192 eventFrag = std::make_shared<TFragment>();
193 eventFrag->SetDaqTimeStamp(transferfrag->GetDaqTimeStamp());
194 eventFrag->SetDaqId(transferfrag->GetDaqId());
195 eventFrag->SetTriggerId(transferfrag->GetTriggerId());
196 eventFrag->SetTimeStamp(transferfrag->GetTimeStamp());
197
198 Push(GoodOutputQueues(), transferfrag);
199 NumFragsFound++;
200 event->IncrementGoodFrags();
201 } else {
202 std::shared_ptr<TFragment> transferfrag = std::make_shared<TFragment>(*eventFrag);
203 Push(GoodOutputQueues(), transferfrag);
204 NumFragsFound++;
205 event->IncrementGoodFrags();
206 eventFrag = nullptr;
207 return NumFragsFound;
208 }
209
210 break;
211 case 0x5: // raw charge evaluation.
212 SetTIGCharge(value, eventFrag);
213 break;
214 case 0x6: temp_led = value; break;
215 case 0xb:
216 // SetTIGBitPattern
217 break;
218 case 0xc: SetTIGAddress(value, eventFrag); break;
219 case 0xe: // this ends the bank!
220 if(eventFrag) {
221 return -x;
222 }
223 break;
224 case 0xf: break;
225 default: break;
226 }
227 }
228 return NumFragsFound;
229}
230
231void TGRSIDataParser::SetTIGAddress(uint32_t value, const std::shared_ptr<TFragment>& currentFrag)
232{
233 /// Sets the digitizer address of the 'currentFrag' TFragment
234 currentFrag->SetAddress(static_cast<int32_t>(0x00ffffff & value));
235}
236
237void TGRSIDataParser::SetTIGWave(uint32_t value, const std::shared_ptr<TFragment>& currentFrag)
238{
239 /// Sets the waveform for a Tigress event.
240
241 if(currentFrag->GetWaveform()->size() > (100000)) {
242 std::cout << "number of wave samples found is to great" << std::endl;
243 return;
244 }
245
246 if((value & 0x00002000) != 0u) {
247 int temp = value & 0x00003fff;
248 temp = ~temp;
249 temp = (temp & 0x00001fff) + 1;
250 currentFrag->AddWaveformSample(static_cast<Short_t>(-temp));
251 } else {
252 currentFrag->AddWaveformSample(static_cast<Short_t>(value & 0x00001fff));
253 }
254 if(((value >> 14) & 0x00002000) != 0u) {
255 int temp = (value >> 14) & 0x00003fff;
256 temp = ~temp;
257 temp = (temp & 0x00001fff) + 1;
258 currentFrag->AddWaveformSample(static_cast<Short_t>(-temp));
259 } else {
260 currentFrag->AddWaveformSample(static_cast<Short_t>((value >> 14) & 0x00001fff));
261 }
262}
263
264void TGRSIDataParser::SetTIGCfd(uint32_t value, const std::shared_ptr<TFragment>& currentFrag)
265{
266 /// Sets the CFD of a Tigress Event.
267
268 currentFrag->SetCfd(static_cast<int32_t>(value & 0x07ffffff));
269}
270
271void TGRSIDataParser::SetTIGLed(uint32_t, const std::shared_ptr<TFragment>&)
272{
273 /// Sets the LED of a Tigress event.
274 // No longer used anywhere
275 // currentFrag->SetLed( int32_t(value & 0x07ffffff) );
276}
277
278void TGRSIDataParser::SetTIGCharge(uint32_t value, const std::shared_ptr<TFragment>& currentFragment)
279{
280 /// Sets the integrated charge of a Tigress event.
281 TChannel* chan = currentFragment->GetChannel();
282 if(chan == nullptr) {
283 chan = Channel();
284 }
285 std::string dig_type = chan->GetDigitizerTypeString();
286
287 int charge = 0;
288 if((dig_type.compare(0, 5, "Tig10") == 0) || (dig_type.compare(0, 5, "TIG10") == 0)) {
289 if((value & 0x02000000) != 0u) {
290 charge = (-((~(static_cast<int32_t>(value) & 0x01ffffff)) & 0x01ffffff) + 1);
291 } else {
292 charge = (value & 0x03ffffff);
293 }
294 } else if((dig_type.compare(0, 5, "Tig64") == 0) || (dig_type.compare(0, 5, "TIG64") == 0)) {
295 if((value & 0x00200000) != 0u) {
296 charge = (-((~(static_cast<int32_t>(value) & 0x001fffff)) & 0x001fffff) + 1);
297 } else {
298 charge = ((value & 0x003fffff));
299 }
300 } else {
301 if((value & 0x02000000) != 0u) {
302 charge = (-((~(static_cast<int32_t>(value) & 0x01ffffff)) & 0x01ffffff) + 1);
303 } else {
304 charge = ((static_cast<int32_t>(value) & 0x03ffffff));
305 }
306 }
307 currentFragment->SetCharge(charge);
308}
309
310bool TGRSIDataParser::SetTIGTriggerID(uint32_t value, const std::shared_ptr<TFragment>& currentFrag)
311{
312 /// Sets the Trigger ID of a Tigress event.
313 if((value & 0xf0000000) != 0x80000000) {
314 return false;
315 }
316 value = value & 0x0fffffff;
317 unsigned int LastTriggerIdHiBits = LastTriggerId() & 0xFF000000; // highest 8 bits, remainder will be
318 unsigned int LastTriggerIdLoBits = LastTriggerId() & 0x00FFFFFF; // determined by the reported value
319 if(value < MaxTriggerId() / 10) { // the trigger id has wrapped around
320 if(LastTriggerIdLoBits > MaxTriggerId() * 9 / 10) {
321 currentFrag->SetTriggerId(static_cast<uint64_t>(LastTriggerIdHiBits + value + MaxTriggerId()));
322 std::cout << DBLUE << "We are looping new trigger id = " << currentFrag->GetTriggerId() << ", last trigger hi bits = " << LastTriggerIdHiBits << ", last trigger lo bits = " << LastTriggerIdLoBits << ", value = " << value << RESET_COLOR << std::endl;
323 } else {
324 currentFrag->SetTriggerId(static_cast<uint64_t>(LastTriggerIdHiBits + value));
325 }
326 } else if(value < MaxTriggerId() * 9 / 10) {
327 currentFrag->SetTriggerId(static_cast<uint64_t>(LastTriggerIdHiBits + value));
328 } else {
329 if(LastTriggerIdLoBits < MaxTriggerId() / 10) {
330 currentFrag->SetTriggerId(static_cast<uint64_t>(LastTriggerIdHiBits + value - MaxTriggerId()));
331 std::cout << DRED << "We are backwards looping new trigger id = " << currentFrag->GetTriggerId() << ", last trigger hi bits = " << LastTriggerIdHiBits << ", last trigger lo bits = " << LastTriggerIdLoBits << ", value = " << value << RESET_COLOR << std::endl;
332 } else {
333 currentFrag->SetTriggerId(static_cast<uint64_t>(LastTriggerIdHiBits + value));
334 }
335 }
336 // fragment_id_map[value]++;
337 // currentFrag->FragmentId = fragment_id_map[value];
338 LastTriggerId(static_cast<uint64_t>(currentFrag->GetTriggerId()));
339 return true;
340}
341
342bool TGRSIDataParser::SetTIGTimeStamp(uint32_t* data, const std::shared_ptr<TFragment>& currentFrag)
343{
344 /// Sets the Timestamp of a Tigress Event
345 for(int x = 0; x < 10; x++) { // finds the timestamp.
346 ++data;
347 if(((*data) >> 28) == 0xa) {
348 break;
349 }
350 }
351 int64_t timestamplow = -1;
352 int64_t timestamphigh = -1;
353
354 if(!((*data & 0xf0000000) == 0xa0000000)) {
355 std::cout << "here 0?\t" << hex(*data, 8) << std::endl;
356 return false;
357 }
358
359 std::array<unsigned int, 5> time = {0}; // tigress can report up to 5 valid timestamp words
360 int x = 0;
361
362 while((*(data + x) & 0xf0000000) == 0xa0000000) {
363 time[x] = *(data + x);
364 x += 1;
365 if(x == 5) {
366 break;
367 }
368 }
369
370 switch(x) {
371 case 1: // bad.
372 break;
373 case 2: // minimum number of good a's
374 if(time[0] != time[1]) { // tig64's only have two, both second hex's are 0s. also some times tig10s.
375 timestamplow = time[0] & 0x00ffffff;
376 timestamphigh = time[1] & 0x00ffffff;
377 // return true;
378 }
379 break;
380 case 3:
381 if(time[0] == time[1] && time[0] != time[2]) {
382 if(((time[0] & 0x0f000000) != 0x00000000) && ((time[2] & 0x0f000000) != 0x01000000)) {
383 break;
384 }
385 timestamplow = time[0] & 0x00ffffff;
386 timestamphigh = time[2] & 0x00ffffff;
387 } else if(time[0] != time[1] && time[1] == time[2]) {
388 if(((time[0] & 0x0f000000) != 0x00000000) && ((time[1] & 0x0f000000) != 0x01000000)) {
389 break;
390 }
391 timestamplow = time[0] & 0x00ffffff;
392 timestamphigh = time[1] & 0x00ffffff;
393 } else { // assume the third if the counter.
394 // if( ((time[0]&0x0f000000)!=0x00000000) && ((time[1]&0x0f000000)!=0x01000000) )
395 // break;
396 timestamplow = time[0] & 0x00ffffff;
397 timestamphigh = time[1] & 0x00ffffff;
398 }
399 break;
400 // return true;
401 case 4:
402 case 5:
403 if(time[0] == time[1] && time[2] == time[3]) {
404 if(((time[0] & 0x0f000000) != 0x00000000) && ((time[2] & 0x0f000000) != 0x01000000)) {
405 break;
406 }
407 timestamplow = time[0] & 0x00ffffff;
408 timestamphigh = time[1] & 0x00ffffff;
409 } else {
410 if(((time[0] & 0x0f000000) != 0x00000000) && ((time[1] & 0x0f000000) != 0x01000000)) {
411 break;
412 }
413 timestamplow = time[0] & 0x00ffffff;
414 timestamphigh = time[1] & 0x00ffffff;
415 }
416 break;
417 // return true;
418 };
419 if(timestamplow > -1 && timestamphigh > -1) {
420 // combine low and high time stamp bits
421 currentFrag->SetTimeStamp((timestamphigh << 24) + timestamplow);
422 return true;
423 }
424
425 return false;
426}
427
428/////////////***************************************************************/////////////
429/////////////***************************************************************/////////////
430/////////////***************************************************************/////////////
431/////////////***************************************************************/////////////
432/////////////***************************************************************/////////////
433/////////////***************************************************************/////////////
434
435int TGRSIDataParser::ProcessGriffin(uint32_t* data, const int& size, const EBank& bank, std::shared_ptr<TMidasEvent>& event)
436{
437 // loop over words in event to find fragment header
438 int totalFrags = 0;
439 for(int index = 0; index < size;) {
440 if(((data[index]) & 0xf0000000) == 0x80000000) {
441 // if we found a fragment header we use GriffinDataToFragment which returns the number of words read
442 int words = 0;
443 try {
444 words = GriffinDataToFragment(&data[index], size - index, bank, event->GetSerialNumber(), event->GetTimeStamp());
445 } catch(TGRSIDataParserException& e) {
446 words = -e.GetFailedWord();
447 if(!TGRSIOptions::Get()->SuppressErrors()) {
448 if(!TGRSIOptions::Get()->LogErrors()) {
449 std::cout << std::endl
450 << e.what();
451 }
452 }
453 }
454 if(words > 0) {
455 // we successfully read one event with <words> words, so we advance the index by words
456 event->IncrementGoodFrags();
457 ++totalFrags;
458 index += words;
459 } else {
460 // we failed to read the fragment on word <-words>, so advance the index by -words and we create an error
461 // message
462 ++totalFrags; // if the midas bank fails, we assume it only had one frag in it... this is just used for a
463 // print statement.
464 index -= words;
465
466 if(!TGRSIOptions::Get()->SuppressErrors()) {
467 if(!TGRSIOptions::Get()->LogErrors()) {
468 std::cout << DRED << "//**********************************************//" << RESET_COLOR << std::endl;
469 std::cout << DRED << "Bad things are happening. Failed on datum " << index << RESET_COLOR << std::endl;
470 event->Print(Form("a%i", index));
471 std::cout << DRED << "//**********************************************//" << RESET_COLOR << std::endl;
472 } else {
473 std::string errfilename = "error.log";
474 // if(mFile) {
475 // if(mFile->GetSubRunNumber() != -1) {
476 // errfilename.append(Form("error%05i_%03i.log",mFile->GetRunNumber(),mFile->GetSubRunNumber()));
477 // } else {
478 // errfilename.append(Form("error%05i.log",mFile->GetRunNumber()));
479 // }
480 // } else {
481 // errfilename.append("error_log.log");
482 // }
483 FILE* originalstdout = stdout;
484 FILE* errfileptr = freopen(errfilename.c_str(), "a", stdout);
485 std::cout << "//**********************************************//" << std::endl;
486 event->Print("a");
487 std::cout << "//**********************************************//" << std::endl;
488 fclose(errfileptr);
489 stdout = originalstdout;
490 }
491 }
492 }
493 } else {
494 // this is not a fragment header, so we advance the index
495 ++index;
496 }
497 }
498
499 return totalFrags;
500}
501
502int TGRSIDataParser::GriffinDataToFragment(uint32_t* data, int size, EBank bank, unsigned int midasSerialNumber,
503 time_t midasTime)
504{
505 /// Converts a Griffin flavoured MIDAS file into a TFragment and returns the number of words processed (or the
506 /// negative index of the word it failed on)
507 std::shared_ptr<TFragment> eventFrag = std::make_shared<TFragment>();
508 // no need to delete eventFrag, it's a shared_ptr and gets deleted when it goes out of scope
509 FragmentHasWaveform(false);
511 int failedWord = -1; // Variable stores which word we failed on (if we fail). This is somewhat duplicate information
512 // to fState, but makes things easier to track.
513 bool multipleErrors = false; // Variable to store if multiple errors occured parsing one fragment
514
515 if(Options() == nullptr) {
517 }
518
519 int x = 0;
520 if(!SetGRIFHeader(data[x++], eventFrag, bank)) {
521 std::cout << DYELLOW << "data[0] = " << hex(data, 8) << RESET_COLOR << std::endl;
522 // we failed to get a good header, so we don't know which detector type this fragment would've belonged to
524 // this is the first word, so no need to check is the state/failed word has been set before
526 failedWord = 0;
527 }
528
529 eventFrag->SetDaqTimeStamp(midasTime);
530 eventFrag->SetDaqId(midasSerialNumber);
531
532 // Changed on 11 Aug 2015 by RD to include PPG events. If the event has ModuleType 4 and address 0xffff, it is a PPG
533 // event.
534 if((eventFrag->GetModuleType() == 1 || eventFrag->GetModuleType() == 4) && eventFrag->GetAddress() == 0xffff) {
535 return GriffinDataToPPGEvent(data, size, midasSerialNumber, midasTime);
536 }
537 // If the event has detector type 15 (0xf) it's a scaler event.
538 if(eventFrag->GetDetectorType() == 0xf) {
539 // a scaler event (trigger or deadtime) has 8 words (including header and trailer), make sure we have at least
540 // that much left
541 TChannel* chan = TChannel::GetChannel(eventFrag->GetAddress(), false);
542 if((chan != nullptr) && strncmp("RF", chan->GetName(), 2) == 0) {
543 //JW: RF event, stored as a scaler containing fit paramters
544 //in recent (2019 and later) GRIF-16 firmware revisions.
545 //These should be still be treated as RF event fragments, but
546 //need to be parsed differently.
547 //std::cout << "RF scaler event" << std::endl;
548 return RFScalerToFragment(data, size, eventFrag);
549 }
550 if(size < 8) {
553 failedWord = x;
554 } else {
555 multipleErrors = true;
556 }
557 throw TGRSIDataParserException(fState, failedWord, multipleErrors);
558 }
559 return GriffinDataToScalerEvent(data, eventFrag->GetAddress());
560 }
561
562 // If the flag is set, skip any fragment without a channel
563 if(fIgnoreMissingChannel && eventFrag->GetChannel() != nullptr) {
564 // find end of this event
565 for(; x < size; x++) {
566 if((data[x] >> 28) == 0xe) { return x; }
567 }
568 }
569
570 // The Network packet number is for debugging and is not always written to the midas file.
571 if(SetGRIFNetworkPacket(data[x], eventFrag)) {
572 ++x;
573 }
574
575 // The Primary Filter Pattern is in an unstable state right now and is not
576 // always written to the midas file
577 if(SetGRIFPrimaryFilterPattern(data[x], eventFrag, bank)) {
578 ++x;
579 }
580
581 // We can get multiple filter ids (one fragment can pass multiple filter conditions)
582 // so we have to loop until we don't find one
583 while(SetGRIFPrimaryFilterId(data[x], eventFrag)) {
584 ++x;
585 }
586
587 // The channel trigger ID is in an unstable state right now and is not
588 // always written to the midas file
589 if(!SetGRIFChannelTriggerId(data[x++], eventFrag)) {
590 TParsingDiagnostics::Get()->BadFragment(eventFrag->GetDetectorType());
593 failedWord = x - 1; // -1 compensates the incrementation in the if-statement
594 } else {
595 multipleErrors = true;
596 }
597 }
598
599 // The Network packet number is for debugging and is not always written to
600 // the midas file.
601 if(SetGRIFNetworkPacket(data[x], eventFrag)) {
602 x++;
603 }
604
605 if(!SetGRIFTimeStampLow(data[x++], eventFrag)) {
606 TParsingDiagnostics::Get()->BadFragment(eventFrag->GetDetectorType());
609 failedWord = x - 1; // -1 compensates the incrementation in the if-statement
610 } else {
611 multipleErrors = true;
612 }
613 }
614
615 if(!SetGRIFDeadTime(data[x++], eventFrag)) {
616 TParsingDiagnostics::Get()->BadFragment(eventFrag->GetDetectorType());
619 failedWord = x - 1; // -1 compensates the incrementation in the if-statement
620 } else {
621 multipleErrors = true;
622 }
623 }
624
625 std::vector<Int_t> tmpCharge;
626 std::vector<Short_t> tmpIntLength;
627 std::vector<Int_t> tmpCfd;
628
629 for(; x < size; x++) {
630 uint32_t dword = data[x];
631 uint32_t packet = dword >> 28;
632 uint32_t value = dword & 0x0fffffff;
633
634 switch(packet) {
635 case 0x8: // The 8 packet type is for event headers
636 // if this happens, we have "accidentally" found another event.
637 // currently the GRIF-C only sets the primary/secondary port of the address for the first header (of the corrupt
638 // event)
639 // so we want to ignore this corrupt event and the next event which has a wrong address
640 TParsingDiagnostics::Get()->BadFragment(eventFrag->GetDetectorType());
643 failedWord = x + 1; //+1 to ensure we don't read this header as start of a good event
644 } else {
645 multipleErrors = true;
646 }
647 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*eventFrag, data, size, failedWord, multipleErrors));
648 throw TGRSIDataParserException(fState, failedWord, multipleErrors);
649 break;
650 case 0xc: // The c packet type is for waveforms
651 if(!NoWaveforms()) {
652 SetGRIFWaveForm(value, eventFrag);
653 }
654 break;
655 case 0xd:
656 SetGRIFNetworkPacket(dword, eventFrag); // The network packet placement is not yet stable.
657 break;
658 case 0xe:
659 // changed on 21 Apr 2015 by JKS, when signal processing code from Chris changed the trailer.
660 // change should be backward-compatible
661 if((value & 0x3fff) == (eventFrag->GetChannelId() & 0x3fff)) {
662 if(!Options()->SuppressErrors() && (eventFrag->GetModuleType() == 2) && (bank < EBank::kGRF3)) {
663 // check whether the nios finished and if so whether it finished with an error
664 if(((value >> 14) & 0x1) == 0x1) {
665 if(((value >> 16) & 0xff) != 0) {
666 std::cout << BLUE << hex(eventFrag->GetAddress(), 4) << ": NIOS code finished with error " << hex((value >> 16) & 0xff, 2) << RESET_COLOR << std::endl;
667 }
668 }
669 }
670
671 if((eventFrag->GetModuleType() == 1) || (bank > EBank::kGRF2)) { // 4Gs have this only for banks newer than GRF2
672 eventFrag->SetAcceptedChannelId((value >> 14) & 0x3fff);
673 } else {
674 eventFrag->SetAcceptedChannelId(0);
675 }
676
677 // check the number of words the header said we should have with the number of words we've read
678 // the number of words is only set for bank >= GRF3
679 // if the fragment has a waveform, we can't compare the number of words
680 // the headers number of words includes the header (word 0) itself, so we need to compare to x plus one
681 if(Options()->WordOffset() >= 0 && eventFrag->GetNumberOfWords() > 0 && !eventFrag->HasWave() && eventFrag->GetNumberOfWords() != x + Options()->WordOffset()) {
684 failedWord = x;
685 } else {
686 multipleErrors = true;
687 }
688 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*eventFrag, data, size, failedWord, multipleErrors));
689 throw TGRSIDataParserException(fState, failedWord, multipleErrors);
690 }
691
692 // the way we insert the fragment(s) depends on the module type and bank:
693 // 1 - for module type 1 & bank GRF4, we can't insert the fragments yet, we need to put them in a separate queue
694 // 2 - for module type 2 (4G, all banks) and module type 1 & bank GRF3 we set the single charge, cfd, and
695 // IntLength, and insert the fragment
696 // 3 - for module type 1 & banks GRF1/GRF2 we loop over the charge, cfd, and IntLengths, and insert the
697 // (multiple) fragment(s)
698 // the last two cases can be treated the same since the second case will just have a single length charge,
699 // cfd, and IntLengths
700
701 // so we only need to check for the first case
702 if(eventFrag->GetModuleType() == 1 && bank == EBank::kGRF4) {
703 if(tmpCfd.size() != 1) {
704 if(RecordDiag()) {
705 TParsingDiagnostics::Get()->BadFragment(eventFrag->GetDetectorType());
706 }
709 failedWord = x;
710 } else {
711 multipleErrors = true;
712 }
713 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*eventFrag, data, size, failedWord, multipleErrors));
714 throw TGRSIDataParserException(fState, failedWord, multipleErrors);
715 }
716 eventFrag->SetCfd(tmpCfd[0]);
717 if(RecordDiag()) {
718 TParsingDiagnostics::Get()->GoodFragment(eventFrag->GetDetectorType());
719 }
720 FragmentMap().Add(eventFrag, tmpCharge, tmpIntLength);
721 return x;
722 }
723 if(tmpCharge.size() != tmpIntLength.size() || tmpCharge.size() != tmpCfd.size()) {
724 if(RecordDiag()) {
725 TParsingDiagnostics::Get()->BadFragment(eventFrag->GetDetectorType());
726 }
729 failedWord = x;
730 } else {
731 multipleErrors = true;
732 }
733 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*eventFrag, data, size, failedWord, multipleErrors));
734 throw TGRSIDataParserException(fState, failedWord, multipleErrors);
735 }
736 for(size_t h = 0; h < tmpCharge.size(); ++h) {
737 eventFrag->SetCharge(tmpCharge[h]);
738 eventFrag->SetKValue(tmpIntLength[h]);
739 eventFrag->SetCfd(tmpCfd[h]);
740 if(RecordDiag()) {
741 TParsingDiagnostics::Get()->GoodFragment(eventFrag->GetDetectorType());
742 }
744 if(Options()->ReconstructTimeStamp()) {
745 LastTimeStampMap()[eventFrag->GetAddress()] = eventFrag->GetTimeStamp();
746 }
747 Push(GoodOutputQueues(), std::make_shared<TFragment>(*eventFrag));
748 } else {
749 if(Options()->ReconstructTimeStamp() && fState == EDataParserState::kBadHighTS && !multipleErrors) {
750 // std::cout<<"reconstructing timestamp from 0x"<<std::hex<<eventFrag->GetTimeStamp()<<" using
751 // 0x"<<LastTimeStampMap()[eventFrag->GetAddress()];
752 // reconstruct the high bits of the timestamp from the high bits of the last time stamp of the
753 // same address after converting the saved timestamp back to 10 ns units
754 if((eventFrag->GetTimeStamp() & 0x0fffffff) <
755 (LastTimeStampMap()[eventFrag->GetAddress()] & 0x0fffffff)) {
756 // we had a wrap-around of the low time stamp, so we need to set the high bits to the old
757 // high bits plus one
758 eventFrag->AppendTimeStamp(((LastTimeStampMap()[eventFrag->GetAddress()] >> 28) + 1) << 28);
759 } else {
760 eventFrag->AppendTimeStamp(LastTimeStampMap()[eventFrag->GetAddress()] & 0x3fff0000000);
761 }
762 // std::cout<<" => 0x"<<eventFrag->GetTimeStamp()<<std::dec<<std::endl;
763 Push(GoodOutputQueues(), std::make_shared<TFragment>(*eventFrag));
764 } else {
765 // std::cout<<"Can't reconstruct time stamp, "<<Options()->ReconstructTimeStamp()<<",
766 // state "<<fState<<" = "<<EDataParserState::kBadHighTS<<", "<<multipleErrors<<std::endl;
767 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*eventFrag, data, size, failedWord, multipleErrors));
768 }
769 }
770 }
771 return x;
772 } else {
773 if(RecordDiag()) {
774 TParsingDiagnostics::Get()->BadFragment(eventFrag->GetDetectorType());
775 }
778 failedWord = x;
779 } else {
780 multipleErrors = true;
781 }
782 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*eventFrag, data, size, failedWord, multipleErrors));
783 throw TGRSIDataParserException(fState, failedWord, multipleErrors);
784 }
785 break;
786 case 0xf:
787 switch(bank) {
788 case EBank::kGRF1: // format from before May 2015 experiments
789 TParsingDiagnostics::Get()->BadFragment(eventFrag->GetDetectorType());
792 failedWord = x;
793 } else {
794 multipleErrors = true;
795 }
796 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*eventFrag, data, size, failedWord, multipleErrors));
797 throw TGRSIDataParserException(fState, failedWord, multipleErrors);
798 break;
799 case EBank::kGRF2: // from May 2015 to the end of 2015 0xf denoted a psd-word from a 4G
800 if(x + 1 < size) {
801 SetGRIFCc(value, eventFrag);
802 ++x;
803 dword = data[x];
804 SetGRIFPsd(dword, eventFrag);
805 } else {
806 TParsingDiagnostics::Get()->BadFragment(eventFrag->GetDetectorType());
809 failedWord = x;
810 } else {
811 multipleErrors = true;
812 }
813 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*eventFrag, data, size, failedWord, multipleErrors));
814 throw TGRSIDataParserException(fState, failedWord, multipleErrors);
815 }
816 break;
817 case EBank::kGRF3: // from 2016 on we're back to reserving 0xf for faults
818 case EBank::kGRF4:
819 TParsingDiagnostics::Get()->BadFragment(eventFrag->GetDetectorType());
822 failedWord = x;
823 } else {
824 multipleErrors = true;
825 }
826 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*eventFrag, data, size, failedWord, multipleErrors));
827 throw TGRSIDataParserException(fState, failedWord, multipleErrors);
828 break;
829 default:
830 std::cout << "This bank not yet defined." << std::endl;
831 break;
832 }
833 break;
834
835 default:
836 // these are charge/cfd words which are different depending on module type, and bank number/detector type
837 switch(eventFrag->GetModuleType()) {
838 case 1:
839 switch(bank) { // the GRIF-16 data format depends on the bank number
840 case EBank::kGRF1: // bank's 1&2 have n*2 words with (5 high bits IntLength, 26 Charge)(5 low bits IntLength, 26
841 // Cfd)
842 case EBank::kGRF2:
843 // read this pair of charge/cfd words, check if the next word is also a charge/cfd word
844 if(((data[x] & 0x80000000) == 0x0) && x + 1 < size && (data[x + 1] & 0x80000000) == 0x0) {
845 Short_t tmp = (data[x] & 0x7c000000) >> 21; // 21 = 26 minus space for 5 low bits
846 tmpCharge.push_back((data[x] & 0x03ffffff) | (((data[x] & 0x02000000) == 0x02000000)
847 ? 0xfc000000
848 : 0x0)); // extend the sign bit of 26bit charge word
849 ++x;
850 tmpIntLength.push_back(tmp | ((data[x] & 0x7c000000) >> 26));
851 tmpCfd.push_back(data[x] & 0x03ffffff);
852 } else {
853 TParsingDiagnostics::Get()->BadFragment(eventFrag->GetDetectorType());
856 failedWord = x;
857 } else {
858 multipleErrors = true;
859 }
860 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*eventFrag, data, size, failedWord, multipleErrors));
861 throw TGRSIDataParserException(fState, failedWord, multipleErrors);
862 }
863 break;
864 case EBank::kGRF3: // bank 3 has 2 words with (5 high bits IntLength, 26 Charge)(9 low bits IntLength, 22 Cfd)
865 if(x + 1 < size &&
866 (data[x + 1] & 0x80000000) == 0x0) { // check if the next word is also a charge/cfd word
867 Short_t tmp = (data[x] & 0x7c000000) >> 17; // 17 = 26 minus space for 9 low bits
868 tmpCharge.push_back((data[x] & 0x03ffffff) | (((data[x] & 0x02000000) == 0x02000000)
869 ? 0xfc000000
870 : 0x0)); // extend the sign bit of 26bit charge word
871 ++x;
872 tmpIntLength.push_back(tmp | ((data[x] & 0x7fc00000) >> 22));
873 tmpCfd.push_back(data[x] & 0x003fffff);
874 break;
875 } else {
876 TParsingDiagnostics::Get()->BadFragment(eventFrag->GetDetectorType());
879 failedWord = x;
880 } else {
881 multipleErrors = true;
882 }
883 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*eventFrag, data, size, failedWord, multipleErrors));
884 throw TGRSIDataParserException(fState, failedWord, multipleErrors);
885 }
886 break;
887 case EBank::kGRF4: // bank 4 can have more than one integration (up to four), but these have to be combined with
888 // other fragments/hits!
889 // we always have 2 words with (5 high bits IntLength, 26 Charge)(9 low bits IntLength, 22 Cfd)
890 if((data[x] & 0x80000000) == 0x0 && x + 1 < size &&
891 (data[x + 1] & 0x80000000) == 0x0) { // check if the next word is also a charge/cfd word
892 Short_t tmp = ((data[x] & 0x7c000000) >> 17) |
893 (((data[x] & 0x40000000) == 0x40000000) ? 0xc000 : 0x0); // 17 = 26 minus space for 9
894 // low bits; signed, so we
895 // extend the sign bit from 14
896 // (31) to 16 bits
897 tmpCharge.push_back((data[x] & 0x01ffffff) |
898 (((data[x] & 0x01000000) == 0x01000000)
899 ? 0xfe000000
900 : 0x0)); // extend the sign bit of 25bit charge word
901 ++x;
902 tmpIntLength.push_back(tmp | ((data[x] & 0x7fc00000) >> 22));
903 tmpCfd.push_back(data[x] & 0x003fffff);
904 // check if we have two more words (X & XI) with (8 num hits, 2 reserved, 14 IntLength2)(31 Charge2);
905 // x has already been incremented once!
906 if(x + 2 < size && (data[x + 1] & 0x80000000) == 0x0 && (data[x + 2] & 0x80000000) == 0x0) {
907 ++x;
908 tmpIntLength.push_back((data[x] & 0x3fff) | (((data[x] & 0x2000) == 0x2000) ? 0xc000 : 0x0));
909 // eventFrag->SetNumberOfPileups((data[x] >> 16) & 0xff);
910 ++x;
911 if((data[x] & 0x02000000) == 0x02000000) { // overflow bit was set
912 tmpCharge.push_back(std::numeric_limits<int>::max());
913 } else {
914 tmpCharge.push_back((data[x] & 0x01ffffff) |
915 (((data[x] & 0x01000000) == 0x01000000)
916 ? 0xfe000000
917 : 0x0)); // extend the sign bit of 25bit charge word
918 }
919 // check if we have two more words (XI & XIII) with (14 IntLength4, 2 reserved, 14 IntLength3)(31
920 // Charge3); x has already been incremented thrice!
921 if(x + 2 < size && (data[x + 1] & 0x80000000) == 0x0 && (data[x + 2] & 0x80000000) == 0x0) {
922 ++x;
923 tmpIntLength.push_back((data[x] & 0x3fff) | (((data[x] & 0x2000) == 0x2000) ? 0xc000 : 0x0));
924 tmpIntLength.push_back((data[x] >> 16) |
925 (((data[x] & 0x20000000) == 0x20000000) ? 0xc000 : 0x0));
926 ++x;
927 if((data[x] & 0x02000000) == 0x02000000) { // overflow bit was set
928 tmpCharge.push_back(std::numeric_limits<int>::max());
929 } else {
930 tmpCharge.push_back((data[x] & 0x01ffffff) |
931 (((data[x] & 0x01000000) == 0x01000000)
932 ? 0xfe000000
933 : 0x0)); // extend the sign bit of 25bit charge word
934 }
935 // check if we have one final word with (31 Charge4), otherwise remove the last integration
936 // length (IntLength4)
937 if(x + 1 < size && (data[x + 1] & 0x80000000) == 0x0) {
938 ++x;
939 if((data[x] & 0x02000000) == 0x02000000) { // overflow bit was set
940 tmpCharge.push_back(std::numeric_limits<int>::max());
941 } else {
942 tmpCharge.push_back((data[x] & 0x01ffffff) |
943 (((data[x] & 0x01000000) == 0x01000000)
944 ? 0xfe000000
945 : 0x0)); // extend the sign bit of 25bit charge word
946 }
947 } else {
948 tmpIntLength.pop_back();
949 }
950 } else if((data[x + 1] & 0x80000000) == 0x0) { // 5 words
951 ++x;
952 }
953 } else if((data[x + 1] & 0x80000000) == 0x0) { // 3 words
954 ++x;
955 }
956 } else {
957 // these types of corrupt events quite often end without a trailer which leads to the header of the
958 // next event missing the primary/secondary part of the address
959 // so we look for the next trailer and stop there
960 while(x < size && (data[x] & 0xf0000000) != 0xe0000000) {
961 ++x;
962 }
963 TParsingDiagnostics::Get()->BadFragment(eventFrag->GetDetectorType());
966 failedWord = x;
967 } else {
968 multipleErrors = true;
969 }
970 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*eventFrag, data, size, failedWord, multipleErrors));
971 throw TGRSIDataParserException(fState, failedWord, multipleErrors);
972 }
973 break;
974 default:
975 if(!Options()->SuppressErrors()) {
976 std::cout << DRED << "Error, bank type " << static_cast<std::underlying_type<EBank>::type>(bank) << " not implemented yet" << RESET_COLOR << std::endl;
977 }
978 TParsingDiagnostics::Get()->BadFragment(eventFrag->GetDetectorType());
981 failedWord = x;
982 } else {
983 multipleErrors = true;
984 }
985 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*eventFrag, data, size, failedWord, multipleErrors));
986 throw TGRSIDataParserException(fState, failedWord, multipleErrors);
987 break;
988 }
989 break;
990 case 2:
991 // the 4G data format depends on the detector type, but the first two words are always the same
992 if(x + 1 < size && (data[x + 1] & 0x80000000) == 0x0) { // check if the next word is also a charge/cfd word
993 Short_t tmp = (data[x] & 0x7c000000) >> 21; // 21 = 26 minus space for 5 low bits
994 tmpCharge.push_back((data[x] & 0x03ffffff) | (((data[x] & 0x02000000) == 0x02000000)
995 ? 0xfc000000
996 : 0x0)); // extend the sign bit of 26bit charge word
997 ++x;
998 tmpIntLength.push_back(tmp | ((data[x] & 0x7c000000) >> 26));
999 tmpCfd.push_back(data[x] & 0x03ffffff);
1000 } else {
1001 TParsingDiagnostics::Get()->BadFragment(eventFrag->GetDetectorType());
1004 failedWord = x;
1005 } else {
1006 multipleErrors = true;
1007 }
1008 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*eventFrag, data, size, failedWord, multipleErrors));
1009 throw TGRSIDataParserException(fState, failedWord, multipleErrors);
1010 }
1011 // for descant types (6,10,11) there are two more words for banks > GRF2 (bank GRF2 used 0xf packet and bank
1012 // GRF1 never had descant)
1013 if(bank > EBank::kGRF2 && (eventFrag->GetDetectorType() == 6 || eventFrag->GetDetectorType() == 10 ||
1014 eventFrag->GetDetectorType() == 11)) {
1015 ++x;
1016 if(x + 1 < size && (data[x + 1] & 0x80000000) == 0x0) {
1017 SetGRIFCc(value, eventFrag);
1018 ++x;
1019 dword = data[x];
1020 SetGRIFPsd(dword, eventFrag);
1021 } else {
1022 TParsingDiagnostics::Get()->BadFragment(eventFrag->GetDetectorType());
1025 failedWord = x;
1026 } else {
1027 multipleErrors = true;
1028 }
1029 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*eventFrag, data, size, failedWord, multipleErrors));
1030 throw TGRSIDataParserException(fState, failedWord, multipleErrors);
1031 }
1032 }
1033 break;
1034 default:
1035 if(!Options()->SuppressErrors()) {
1036 std::cout << DRED << "Error, module type " << eventFrag->GetModuleType() << " not implemented yet" << RESET_COLOR << std::endl;
1037 }
1038 TParsingDiagnostics::Get()->BadFragment(eventFrag->GetDetectorType());
1041 failedWord = x;
1042 } else {
1043 multipleErrors = true;
1044 }
1045 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*eventFrag, data, size, failedWord, multipleErrors));
1046 throw TGRSIDataParserException(fState, failedWord, multipleErrors);
1047 } // switch(eventFrag->GetModuleType())
1048 break;
1049 } // switch(packet)
1050 } // for(;x<size;x++)
1051
1052 TParsingDiagnostics::Get()->BadFragment(eventFrag->GetDetectorType());
1055 failedWord = x;
1056 } else {
1057 multipleErrors = true;
1058 }
1059 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*eventFrag, data, size, failedWord, multipleErrors));
1060 throw TGRSIDataParserException(fState, failedWord, multipleErrors);
1061 return -x;
1062}
1063
1064bool TGRSIDataParser::SetGRIFHeader(uint32_t value, const std::shared_ptr<TFragment>& frag, EBank bank)
1065{
1066 if((value & 0xf0000000) != 0x80000000) {
1067 return false;
1068 }
1069 switch(bank) {
1070 case EBank::kGRF1: // header format from before May 2015 experiments
1071 // Sets:
1072 // The number of filters
1073 // The Data Type
1074 // Number of Pileups
1075 // Channel Address
1076 // Detector Type
1077 // frag->SetNumberOfFilters((value &0x0f000000)>> 24);
1078 frag->SetModuleType((value & 0x00e00000) >> 21);
1079 frag->SetNumberOfPileups((value & 0x001c0000) >> 18);
1080 frag->SetAddress((value & 0x0003fff0) >> 4);
1081 frag->SetDetectorType((value & 0x0000000f));
1082
1083 // if(frag-DetectorType==2)
1084 // frag->ChannelAddress += 0x8000;
1085 break;
1086 case EBank::kGRF2:
1087 // Sets:
1088 // The number of filters
1089 // The Data Type
1090 // Number of Pileups
1091 // Channel Address
1092 // Detector Type
1093 frag->SetNumberOfPileups((value & 0x0c000000) >> 26);
1094 frag->SetModuleType((value & 0x03800000) >> 23);
1095 // frag->SetNumberOfFilters((value &0x00700000)>> 20);
1096 frag->SetAddress((value & 0x000ffff0) >> 4);
1097 frag->SetDetectorType((value & 0x0000000f));
1098
1099 break;
1100 case EBank::kGRF3:
1101 case EBank::kGRF4:
1102 frag->SetModuleType((value & 0x0e000000) >> 25);
1103 frag->SetNumberOfWords((value & 0x01f00000) >> 20);
1104 frag->SetAddress((value & 0x000ffff0) >> 4);
1105 frag->SetDetectorType((value & 0x0000000f));
1106
1107 break;
1108 default:
1109 std::cout << "This bank is not yet defined." << std::endl;
1110 return false;
1111 }
1112
1113 return true;
1114}
1115
1116bool TGRSIDataParser::SetGRIFPrimaryFilterPattern(uint32_t value, const std::shared_ptr<TFragment>& frag, EBank bank)
1117{
1118 /// Sets the Griffin Primary Filter Pattern
1119 if((value & 0xc0000000) != 0x00000000) {
1120 return false;
1121 }
1122 switch(bank) {
1123 case EBank::kGRF1:
1124 case EBank::kGRF2:
1125 frag->SetTriggerBitPattern(value >> 16);
1126 // frag->SetPPGWord(value & 0x0000ffff);//This is due to new GRIFFIN data format
1127 break;
1128 case EBank::kGRF3:
1129 case EBank::kGRF4:
1130 frag->SetTriggerBitPattern(value >> 16);
1131 frag->SetNumberOfPileups(value & 0x1f);
1132 FragmentHasWaveform((value & 0x8000) == 0x8000);
1133 break;
1134 default: return false;
1135 }
1136 return true;
1137}
1138
1139bool TGRSIDataParser::SetGRIFPrimaryFilterId(uint32_t value, const std::shared_ptr<TFragment>& frag)
1140{
1141 /// Sets the Griffin Primary filter ID and PPG
1142 if((value & 0x80000000) != 0x00000000) {
1143 return false;
1144 }
1145
1146 frag->SetTriggerId(value & 0x7FFFFFFF); // REAL
1147 return true;
1148}
1149
1150bool TGRSIDataParser::SetGRIFChannelTriggerId(uint32_t value, const std::shared_ptr<TFragment>& frag)
1151{
1152 /// Sets the Griffin Channel Trigger ID
1153 if((value & 0xf0000000) != 0x90000000) {
1154 return false;
1155 }
1156 frag->SetChannelId(value & 0x0fffffff);
1157 return true;
1158}
1159
1160bool TGRSIDataParser::SetGRIFNetworkPacket(uint32_t value, const std::shared_ptr<TFragment>& frag)
1161{
1162 /// Ignores the network packet number (for now)
1163 if((value & 0xf0000000) != 0xd0000000) {
1164 return false;
1165 }
1166 if((value & 0x0f000000) == 0x0f000000 && frag->GetNetworkPacketNumber() > 0) {
1167 if(frag->GetZc() != 0) {
1168 return false;
1169 }
1170 // descant zero crossing time.
1171 frag->SetZc(value & 0x00ffffff);
1172 } else {
1173 frag->SetNetworkPacketNumber(value & 0x0fffffff);
1174 }
1175 return true;
1176}
1177
1178bool TGRSIDataParser::SetGRIFTimeStampLow(uint32_t value, const std::shared_ptr<TFragment>& frag)
1179{
1180 /// Sets the lower 28 bits of the griffin time stamp
1181 if((value & 0xf0000000) != 0xa0000000) {
1182 return false;
1183 }
1184 // we always get the lower 28 bits first
1185 frag->SetTimeStamp(value & 0x0fffffff);
1186 return true;
1187}
1188
1189bool TGRSIDataParser::SetGRIFWaveForm(uint32_t value, const std::shared_ptr<TFragment>& frag)
1190{
1191 /// Sets the Griffin waveform if record_waveform is set to true
1192 if(frag->GetWaveform()->size() > 100000) {
1193 std::cout << "number of wave samples found is too great" << std::endl;
1194 return false;
1195 }
1196
1197 // to go from a 14-bit signed number to a 16-bit signed number, we simply set the two highest bits if the sign bit is set
1198 frag->AddWaveformSample((value & 0x2000) != 0u ? static_cast<Short_t>((value & 0x3fff) | 0xc000)
1199 : static_cast<Short_t>(value & 0x3fff));
1200 value = value >> 14;
1201 frag->AddWaveformSample((value & 0x2000) != 0u ? static_cast<Short_t>((value & 0x3fff) | 0xc000)
1202 : static_cast<Short_t>(value & 0x3fff));
1203
1204 return true;
1205}
1206
1207bool TGRSIDataParser::SetGRIFDeadTime(uint32_t value, const std::shared_ptr<TFragment>& frag)
1208{
1209 /// Sets the Griffin deadtime and the upper 14 bits of the timestamp
1210 if((value & 0xf0000000) != 0xb0000000) {
1211 return false;
1212 }
1213 frag->SetDeadTime((value & 0x0fffc000) >> 14);
1214 // AppendTimeStamp simply adds the new value (not bitwise operation), so we just add the high bits
1215 frag->AppendTimeStamp(static_cast<Long64_t>(value & 0x00003fff) << 28);
1216 return true;
1217}
1218
1219bool TGRSIDataParser::SetGRIFCc(uint32_t value, const std::shared_ptr<TFragment>& frag)
1220{
1221 /// set the short integration and the lower 9 bits of the long integration
1222 if(frag->GetCcShort() != 0 || frag->GetCcLong() != 0) {
1223 return false;
1224 }
1225 frag->SetCcShort(value & 0x7ffff);
1226 frag->SetCcLong(value >> 19);
1227 return true;
1228}
1229
1230bool TGRSIDataParser::SetGRIFPsd(uint32_t value, const std::shared_ptr<TFragment>& frag)
1231{
1232 /// set the zero crossing and the higher 10 bits of the long integration
1233 if(frag->GetZc() != 0) { // low bits of ccLong have already been set
1234 return false;
1235 }
1236 frag->SetZc(value & 0x003fffff);
1237 frag->SetCcLong(frag->GetCcLong() | ((value & 0x7fe00000) >> 12)); // 21 bits from zero crossing minus 9 lower bits
1238 return true;
1239}
1240
1241int TGRSIDataParser::RFScalerToFragment(uint32_t* data, const int size, const std::shared_ptr<TFragment>& frag)
1242{
1243 // Parses special RF scaler events which contain only timestamps and fit paramteters
1244
1245 ULong64_t ts = 0;
1246 ULong64_t tshigh = 0;
1247 double rfFreq = -1.0;
1248 std::array<double, 4> rfPar;
1249 bool freqSet = false;
1250 bool tsSet = false;
1251 int failedWord = -1;
1252
1253 int x = 0;
1254 for(int i = 0; i < size; i++) {
1255
1256 if(x >= size) {
1257 //std::cout << "RF fragment missing frequency and/or timestamp info!" << std::endl;
1258 return -1;
1259 }
1260
1261 uint32_t dword = data[x];
1262 uint32_t packet = dword >> 28;
1263 uint32_t value = dword & 0x0fffffff;
1264
1265 switch(packet) {
1266 case 0x9:
1267 //RF frequency word
1268 rfFreq = static_cast<double>(value); //RF frequency (27-bit number) in cycles per 2^27 clock ticks or 1.34s
1269 freqSet = true;
1270 break;
1271 case 0xa:
1272 //timestamp words (low 0xa followed by high 0xb)
1273 ts = 0;
1274 ts |= value;
1275 x++;
1276 if((data[x] >> 28) == 0xb) {
1277 tshigh = data[x]; //need to convert the high timestamp data to a long int prior to shifting
1278 ts |= ((tshigh & 0x00003fff) << 28); //timestamp, in samples
1279 tsSet = true;
1280 } else {
1281 TParsingDiagnostics::Get()->BadFragment(frag->GetDetectorType());
1283 failedWord = x;
1284 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*frag, data, size, failedWord, false));
1285 //std::cout << "Invalid RF high time stamp!" << std::endl;
1286 return -1;
1287 }
1288 break;
1289 case 0xe:
1290 //std::cout << "Early end to RF fragment." << std::endl;
1291 TParsingDiagnostics::Get()->BadFragment(frag->GetDetectorType());
1293 failedWord = x;
1294 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*frag, data, size, failedWord, false));
1295 return -1;
1296 break;
1297 default:
1298 break;
1299 }
1300 x++;
1301 if(freqSet && tsSet) { break; }
1302 }
1303
1304 if(rfFreq < 0.0) {
1305 //std::cout << "Bad RF frequency." << std::endl;
1306 TParsingDiagnostics::Get()->BadFragment(frag->GetDetectorType());
1308 failedWord = x;
1309 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*frag, data, size, failedWord, false));
1310 return -1;
1311 }
1312
1313 frag->SetTimeStamp(ts);
1314
1315 if(!(x < size - 3)) {
1316 //std::cout << "RF fragment does not contain all parameters." << std::endl;
1317 TParsingDiagnostics::Get()->BadFragment(frag->GetDetectorType());
1319 failedWord = x;
1320 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*frag, data, size, failedWord, false));
1321 return -1;
1322 }
1323 if((data[x] == data[x + 1]) && (data[x] == data[x + 2]) && (data[x] == data[x + 3])) {
1324 //std::cout << "Failed RF fit: all parameters are the same value." << std::endl;
1325 TParsingDiagnostics::Get()->BadFragment(frag->GetDetectorType());
1327 failedWord = x;
1328 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*frag, data, size, failedWord, false));
1329 return -1;
1330 }
1331
1332 int pos = 0;
1333 for(int i = 0; i < 4; i++) {
1334
1335 uint32_t dword = data[x];
1336 uint32_t packet = dword >> 28;
1337
1338 if(x < size) {
1339 if((packet) == 0xe) {
1340 //std::cout << "RF fragment unexpectedly ended early!" << std::endl;
1341 TParsingDiagnostics::Get()->BadFragment(frag->GetDetectorType());
1343 failedWord = x;
1344 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*frag, data, size, failedWord, false));
1345 return -1;
1346 }
1347 if((i != 2) && (dword == 0)) {
1348 //std::cout << "Failed RF fit: non-offset parameter is zero." << std::endl;
1349 TParsingDiagnostics::Get()->BadFragment(frag->GetDetectorType());
1351 failedWord = x;
1352 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*frag, data, size, failedWord, false));
1353 return -1;
1354 }
1355
1356 if((dword & (1 << 29)) != 0x0) {
1357 //parameter value is negative
1358 //take two's complement
1359 for(int j = 0; j < 30; j++) {
1360 if((dword & (1 << j)) != 0x0) {
1361 pos = j;
1362 break;
1363 }
1364 }
1365 for(int j = pos + 1; j < 30; j++) {
1366 dword ^= 1 << j;
1367 }
1368 rfPar[i] = static_cast<double>(-1.0 * (dword & 0x03ffffff)); //RF fit parameters (30-bit numbers)
1369 } else {
1370 rfPar[i] = static_cast<double>(dword & 0x03ffffff); //RF fit parameters (30-bit numbers)
1371 }
1372
1373 x++;
1374 }
1375 }
1376
1377 //RF frequency and all 4 fit parameters were parsed without issue
1378 //convert these into the RF period and phase
1379
1380 rfPar[0] = rfPar[0] / rfPar[3];
1381 rfPar[1] = rfPar[1] / rfPar[3];
1382 rfPar[2] = rfPar[2] / rfPar[3];
1383 double T = 1.34217728E9 / rfFreq; // period in ns
1384 double A = sqrt(rfPar[1] * rfPar[1] + rfPar[0] * rfPar[0]);
1385 double s = -rfPar[0] / A;
1386 double c = rfPar[1] / A;
1387 double rfPhaseShift = 0.; //the phase shift, in ns
1388 if(s >= 0) {
1389 rfPhaseShift = acos(c) * T / (2 * TMath::Pi());
1390 } else {
1391 rfPhaseShift = (1 - acos(c) / (2 * TMath::Pi())) * T;
1392 }
1393
1394 //put the important info (phase shift, period) into the fragment
1395
1396 frag->SetCharge(static_cast<float>(T)); //period stored as charge (where else would I put it?)
1397 frag->SetCfd(static_cast<float>(rfPhaseShift) * 1.6f); //phase shift in cfd units (this one seems reasonable)
1398
1399 Push(GoodOutputQueues(), std::make_shared<TFragment>(*frag));
1400 return 1;
1401}
1402
1403int TGRSIDataParser::GriffinDataToPPGEvent(uint32_t* data, int size, unsigned int, time_t)
1404{
1405 auto* ppgEvent = new TPPGData;
1406 int x = 1; // We have already read the header so we can skip the 0th word.
1407
1408 // The Network packet number is for debugging and is not always written to
1409 // the midas file.
1410 if(SetPPGNetworkPacket(data[x], ppgEvent)) { // The network packet placement is not yet stable.
1411 ++x;
1412 }
1413 if(SetNewPPGPattern(data[x], ppgEvent)) {
1414 ++x;
1415 }
1416
1417 for(; x < size; x++) {
1418 uint32_t dword = data[x];
1419 uint32_t packet = dword & 0xf0000000;
1420 uint32_t value = dword & 0x0fffffff;
1421
1422 switch(packet) {
1423 case 0x80000000: // The 8 packet type is for event headers
1424 // if this happens, we have "accidentally" found another event.
1425 return -x;
1426 case 0x90000000: // The b packet type contains the dead-time word
1427 SetOldPPGPattern(value, ppgEvent);
1428 break;
1429 case 0xd0000000:
1430 SetPPGNetworkPacket(dword, ppgEvent); // The network packet placement is not yet stable.
1431 break;
1432 case 0xa0000000: SetPPGLowTimeStamp(value, ppgEvent); break;
1433 case 0xb0000000: SetPPGHighTimeStamp(value, ppgEvent); break;
1434 case 0xe0000000:
1435 // if((value & 0xFFFF) == (ppgEvent->GetNewPPG())){
1436 TPPG::Get()->AddData(ppgEvent);
1437 TParsingDiagnostics::Get()->GoodFragment(-2); // use detector type -2 for PPG
1438 return x;
1439 //} else {
1440 // TParsingDiagnostics::Get()->BadFragment(-2); //use detector type -2 for PPG
1441 // return -x;
1442 //}
1443 break;
1444 };
1445 }
1446 delete ppgEvent;
1447 // No trailer found
1448 TParsingDiagnostics::Get()->BadFragment(-2); // use detector type -2 for PPG
1449 return -x;
1450}
1451
1452bool TGRSIDataParser::SetNewPPGPattern(uint32_t value, TPPGData* ppgevent)
1453{
1454 if((value & 0xf0000000) != 0x00000000) {
1455 return false;
1456 }
1457 ppgevent->SetNewPPG(value & 0x0fffffff);
1458 return true;
1459}
1460
1461bool TGRSIDataParser::SetOldPPGPattern(uint32_t value, TPPGData* ppgevent)
1462{
1463 ppgevent->SetOldPPG(value & 0x0fffffff);
1464 return true;
1465}
1466
1467bool TGRSIDataParser::SetPPGNetworkPacket(uint32_t value, TPPGData* ppgevent)
1468{
1469 // Ignores the network packet number (for now)
1470 if((value & 0xf0000000) != 0xd0000000) {
1471 return false;
1472 }
1473 ppgevent->SetNetworkPacketId(value & 0x00ffffff);
1474
1475 return true;
1476}
1477
1478bool TGRSIDataParser::SetPPGLowTimeStamp(uint32_t value, TPPGData* ppgevent)
1479{
1480 // the PPG stores the raw values of low and high timestamp
1481 // SetTimeStamp caluculates the correct (multiplied by 10) timestamp from these
1482 // and is called by both SetLowTimeStamp and SetHighTimeStamp
1483 ppgevent->SetLowTimeStamp(value & 0x0fffffff);
1484 return true;
1485}
1486
1487bool TGRSIDataParser::SetPPGHighTimeStamp(uint32_t value, TPPGData* ppgevent)
1488{
1489 // the PPG stores the raw values of low and high timestamp
1490 // SetTimeStamp caluculates the correct (multiplied by 10) timestamp from these
1491 // and is called by both SetLowTimeStamp and SetHighTimeStamp
1492 ppgevent->SetHighTimeStamp(value & 0x0fffffff);
1493 return true;
1494}
1495
1496int TGRSIDataParser::GriffinDataToScalerEvent(uint32_t* data, int address)
1497{
1498 auto* scalerEvent = new TScalerData;
1499 scalerEvent->SetAddress(address);
1500 int x = 1; // We have already read the header so we can skip the 0th word.
1501 int failedWord = -1;
1502
1503 // we expect a word starting with 0xd containing the network packet id
1504 // this is a different format than the others because it will not always be in the scaler word
1505 if(SetScalerNetworkPacket(data[x], scalerEvent)) {
1506 x++;
1507 }
1508
1509 // we expect a word starting with 0xa containing the 28 lowest bits of the timestamp
1510 if(!SetScalerLowTimeStamp(data[x++], scalerEvent)) {
1511 TParsingDiagnostics::Get()->BadFragment(-3); // use detector type -3 for scaler data
1513 failedWord = x;
1514 delete scalerEvent;
1515 throw TGRSIDataParserException(fState, failedWord, false);
1516 }
1517 // followed by four scaler words (32 bits each)
1518 for(int i = 0; i < 4; ++i) {
1519 if(!SetScalerValue(i, data[x++], scalerEvent)) {
1520 TParsingDiagnostics::Get()->BadFragment(-3); // use detector type -3 for scaler data
1522 failedWord = x;
1523 delete scalerEvent;
1524 throw TGRSIDataParserException(fState, failedWord, false);
1525 }
1526 }
1527 // and finally the trailer word with the highest 24 bits of the timestamp
1528 int scalerType = 0;
1529 if(!SetScalerHighTimeStamp(data[x++], scalerEvent, scalerType)) {
1530 TParsingDiagnostics::Get()->BadFragment(-3); // use detector type -3 for scaler data
1532 failedWord = x;
1533 delete scalerEvent;
1534 throw TGRSIDataParserException(fState, failedWord, false);
1535 }
1536
1537 if(scalerType == 0) { // deadtime scaler
1538 TDeadtimeScalerQueue::Get()->Add(scalerEvent);
1539 } else if(scalerType == 1) { // rate scaler
1540 // the rate scaler has only one real value, the rate
1541 scalerEvent->ResizeScaler();
1542 TRateScalerQueue::Get()->Add(scalerEvent);
1543 } else { // unknown scaler type
1544 TParsingDiagnostics::Get()->BadFragment(-3); // use detector type -3 for scaler data
1546 failedWord = x;
1547 delete scalerEvent;
1548 throw TGRSIDataParserException(fState, failedWord, false);
1549 }
1550
1551 TParsingDiagnostics::Get()->GoodFragment(-3); // use detector type -3 for scaler data
1552
1553 return x;
1554}
1555
1557{
1558 if((value >> 28) != 0xd) {
1559 return false;
1560 }
1561 scalerEvent->SetNetworkPacketId(value & 0x0fffffff);
1562 return true;
1563}
1564
1565bool TGRSIDataParser::SetScalerLowTimeStamp(uint32_t value, TScalerData* scalerEvent)
1566{
1567 // the scaler stores the raw values of low and high timestamp
1568 // GetTimeStamp caluculates the correct (multiplied by 10) timestamp from these
1569 if((value >> 28) != 0xa) {
1570 return false;
1571 }
1572 scalerEvent->SetLowTimeStamp(value & 0x0fffffff);
1573 return true;
1574}
1575
1576bool TGRSIDataParser::SetScalerHighTimeStamp(uint32_t value, TScalerData* scalerEvent, int& type)
1577{
1578 // the scaler stores the raw values of low and high timestamp
1579 // GetTimeStamp caluculates the correct (multiplied by 10) timestamp from these
1580 if((value >> 28) != 0xe || (value & 0xff) != (scalerEvent->GetLowTimeStamp() >> 20)) {
1581 return false;
1582 }
1583 scalerEvent->SetHighTimeStamp((value >> 8) & 0x0000ffff);
1584 type = (value >> 24 & 0xf);
1585 return true;
1586}
1587
1588bool TGRSIDataParser::SetScalerValue(int index, uint32_t value, TScalerData* scalerEvent)
1589{
1590 scalerEvent->SetScaler(index, value);
1591 return true;
1592}
1593
1594int TGRSIDataParser::CaenPsdToFragment(uint32_t* data, int size, std::shared_ptr<TMidasEvent>& event)
1595{
1596 /// Converts a Caen flavoured MIDAS events into TFragments and returns the number of events processed
1597 std::shared_ptr<TFragment> eventFrag = std::make_shared<TFragment>();
1598 int w = 0;
1599 int nofFragments = 0;
1600
1601 if(Options() == nullptr) {
1603 }
1604
1605 for(int board = 0; w < size; ++board) {
1606 // read board aggregate header
1607 if(data[w] >> 28 != 0xa) {
1608 if(data[w] == 0x0) {
1609 while(w < size) {
1610 if(data[w++] != 0x0) {
1611 if(!Options()->SuppressErrors()) {
1612 std::cerr << board << ". board - failed on first word, found empty word, but not all following words were empty: " << w - 1 << " 0x" << std::hex << std::setw(8) << std::setfill('0') << data[w - 1] << std::dec << std::setfill(' ') << std::endl;
1613 }
1614 return -w;
1615 }
1616 }
1617 return nofFragments;
1618 }
1619 if(!Options()->SuppressErrors()) {
1620 std::cerr << board << ". board - failed on first word 0x" << std::hex << std::setw(8) << std::setfill('0') << data[w] << std::dec << std::setfill(' ') << ", highest nibble should have been 0xa!" << std::endl;
1621 }
1622 return -w;
1623 }
1624 int32_t numWordsBoard = data[w++] & 0xfffffff; // this is the number of 32-bit words from this board
1625 if(w - 1 + numWordsBoard > size) {
1626 if(!Options()->SuppressErrors()) {
1627 std::cerr << "0 - Missing words, at word " << w - 1 << ", expecting " << numWordsBoard << " more words for board " << board << " (bank size " << size << ")" << std::endl;
1628 }
1629 return -w;
1630 }
1631 uint8_t boardId = data[w] >> 27; // GEO address of board (can be set via register 0xef08 for VME)
1632 //uint16_t pattern = (data[w]>>8) & 0x7fff; // value read from LVDS I/O (VME only)
1633 uint8_t channelMask = data[w++] & 0xff; // which channels are in this board aggregate
1634 ++w; //uint32_t boardCounter = data[w++]&0x7fffff; // ??? "counts the board aggregate"
1635 uint32_t boardTime = data[w++]; // time of creation of aggregate (does not correspond to a physical quantity)
1636 //if(boardCounter < gBoardCounter) {
1637 // std::cerr<<"current board counter "<<boardCounter<<" is less than previous one "<<gBoardCounter<<", skipping this data"<<std::endl;
1638 // return nofFragments;
1639 //}
1640 //gBoardCounter = boardCounter;
1641
1642 for(uint8_t channel = 0; channel < 16; channel += 2) {
1643 if(((channelMask >> (channel / 2)) & 0x1) == 0x0) {
1644 continue;
1645 }
1646 // read channel aggregate header
1647 if(data[w] >> 31 != 0x1) {
1648 if(!Options()->SuppressErrors()) {
1649 std::cerr << "Failed on first word 0x" << std::hex << std::setw(8) << std::setfill('0') << data[w] << std::dec << std::setfill(' ') << ", highest bit should have been set!" << std::endl;
1650 }
1651 return -w;
1652 }
1653 int32_t numWords = data[w++] & 0x3fffff; //per channel
1654 if(w >= size) {
1655 if(!Options()->SuppressErrors()) {
1656 std::cerr << "1 - Missing words, got only " << w - 1 << " words for channel " << channel << " (bank size " << size << ")" << std::endl;
1657 }
1658 return -w;
1659 }
1660 if(((data[w] >> 29) & 0x3) != 0x3) {
1661 if(!Options()->SuppressErrors()) {
1662 std::cerr << "Failed on second word 0x" << std::hex << std::setw(8) << std::setfill('0') << data[w] << std::dec << std::setfill(' ') << ", bits 29 and 30 should have been set!" << std::endl;
1663 }
1664 return -w;
1665 }
1666 bool dualTrace = ((data[w] >> 31) == 0x1);
1667 bool extras = (((data[w] >> 28) & 0x1) == 0x1);
1668 bool waveform = (((data[w] >> 27) & 0x1) == 0x1);
1669 uint8_t extraFormat = ((data[w] >> 24) & 0x7);
1670 //for now we ignore the information which traces are stored:
1671 //bits 22,23: if(dualTrace) 00 = "Input and baseline", 01 = "CFD and Baseline", 10 = "Input and CFD"
1672 // else 00 = "Input", 01 = "CFD"
1673 //bits 19,20,21: 000 = "Long gate", 001 = "over thres.", 010 = "shaped TRG", 011 = "TRG Val. Accept. Win.", 100 = "Pile Up", 101 = "Coincidence", 110 = reserved, 111 = "Trigger"
1674 //bits 16,17,18: 000 = "Short gate", 001 = "over thres.", 010 = "TRG valid.", 011 = "TRG HoldOff", 100 = "Pile Up", 101 = "Coincidence", 110 = reserved, 111 = "Trigger"
1675 int numSampleWords = 4 * (data[w++] & 0xffff); // this is actually the number of samples divided by eight, 2 sample per word => 4*
1676 if(w >= size) {
1677 if(!Options()->SuppressErrors()) {
1678 std::cerr << "2 - Missing words, got only " << w - 1 << " words for channel " << channel << " (bank size " << size << ")" << std::endl;
1679 }
1680 return -w;
1681 }
1682 int eventSize = numSampleWords + 2; // +2 = trigger time words and charge word
1683 if(extras) { ++eventSize; }
1684 if(numWords % eventSize != 2 && !(eventSize == 2 && numWords % eventSize == 0)) { // 2 header words plus n*eventSize should make up one channel aggregate
1685 if(!Options()->SuppressErrors()) {
1686 std::cerr << numWords << " words in channel aggregate, event size is " << eventSize << " => " << static_cast<double>(numWords - 2.) / static_cast<double>(eventSize) << " events?" << std::endl;
1687 }
1688 return -w;
1689 }
1690
1691 // read channel data
1692 for(int ev = 0; ev < (numWords - 2) / eventSize; ++ev) { // -2 = 2 header words for channel aggregate
1693 eventFrag->SetDaqTimeStamp(boardTime);
1694 eventFrag->SetAddress(0x8000 + (boardId * 0x100) + channel + (data[w] >> 31)); // highest bit indicates odd channel
1695 if(eventFrag->GetAddress() == 0x8000) {
1696 eventFrag->SetDetectorType(9); //ZDS will always be in channel 0
1697 } else {
1698 eventFrag->SetDetectorType(6);
1699 }
1700 // these timestamps are in 2ns units
1701 eventFrag->SetTimeStamp(data[w] & 0x7fffffff);
1702 ++w;
1703 if(waveform) {
1704 if(w + numSampleWords >= size) { // need to read at least the sample words plus the charge/extra word
1705 if(!Options()->SuppressErrors()) {
1706 std::cerr << "3 - Missing " << numSampleWords << " waveform words, got only " << w - 1 << " words for channel " << channel << " (bank size " << size << ")" << std::endl;
1707 }
1708 return -w;
1709 }
1710 for(int s = 0; s < numSampleWords && w < size; ++s, ++w) {
1711 //eventFrag->AddDigitalWaveformSample(0, (data[w]>>14)&0x1);
1712 //eventFrag->AddDigitalWaveformSample(1, (data[w]>>15)&0x1);
1713 if(dualTrace) {
1714 // all even samples are from the first trace, all odd ones from the second trace
1715 //eventFrag->AddWaveformSample(data[w]&0x3fff);
1716 //eventFrag->AddWaveformSample((data[w]>>16)&0x3fff);
1717 eventFrag->AddWaveformSample(data[w] & 0xffff);
1718 eventFrag->AddWaveformSample((data[w] >> 16) & 0xffff);
1719 } else {
1720 // both samples are from the first trace
1721 //eventFrag->AddWaveformSample(data[w]&0x3fff);
1722 //eventFrag->AddWaveformSample((data[w]>>16)&0x3fff);
1723 eventFrag->AddWaveformSample(data[w] & 0xffff);
1724 eventFrag->AddWaveformSample((data[w] >> 16) & 0xffff);
1725 }
1726 //eventFrag->AddDigitalWaveformSample(0, (data[w]>>30)&0x1);
1727 //eventFrag->AddDigitalWaveformSample(1, (data[w]>>31)&0x1);
1728 }
1729 } else {
1730 if(w >= size) { // need to read at least the sample words plus the charge/extra word
1731 if(!Options()->SuppressErrors()) {
1732 std::cerr << "3 - Missing words, got only " << w - 1 << " words for channel " << channel << " (bank size " << size << ")" << std::endl;
1733 }
1734 return -w;
1735 }
1736 }
1737 if(extras) {
1738 //std::cout<<eventFrag->GetAddress()<<" - extra word format "<<static_cast<int>(extraFormat)<<": 0x"<<std::hex<<data[w]<<std::dec<<std::endl;
1739 switch(extraFormat) {
1740 case 0: // [31:16] extended time stamp, [15:0] baseline*4
1741 //eventFrag->Baseline(data[w]&0xffff);
1742 eventFrag->SetTimeStamp(eventFrag->GetTimeStamp() | static_cast<uint64_t>(data[w] & 0xffff0000) << 15);
1743 break;
1744 case 1: // [31:16] extended time stamp, 15 trigger lost, 14 over range, 13 1024 triggers, 12 n lost triggers
1745 eventFrag->SetNetworkPacketNumber((data[w] >> 12) & 0xf);
1746 //eventFrag->NLostCount(((data[w]>>12)&0x1) == 0x1);
1747 //eventFrag->KiloCount(((data[w]>>13)&0x1) == 0x1);
1748 //eventFrag->OverRange(((data[w]>>14)&0x1) == 0x1);
1749 //eventFrag->LostTrigger(((data[w]>>15)&0x1) == 0x1);
1750 eventFrag->SetTimeStamp(eventFrag->GetTimeStamp() | static_cast<uint64_t>(data[w] & 0xffff0000) << 15);
1751 break;
1752 case 2: // [31:16] extended time stamp, 15 trigger lost, 14 over range, 13 1024 triggers, 12 n lost triggers, [9:0] fine time stamp
1753 eventFrag->SetTimeStamp(eventFrag->GetTimeStamp() | static_cast<uint64_t>(data[w] & 0xffff0000) << 15);
1754 eventFrag->SetCfd(data[w] & 0x3ff);
1755 eventFrag->SetNetworkPacketNumber((data[w] >> 12) & 0xf);
1756 //eventFrag->NLostCount(((data[w]>>12)&0x1) == 0x1);
1757 //eventFrag->KiloCount(((data[w]>>13)&0x1) == 0x1);
1758 //eventFrag->OverRange(((data[w]>>14)&0x1) == 0x1);
1759 //eventFrag->LostTrigger(((data[w]>>15)&0x1) == 0x1);
1760 break;
1761 case 4: // [31:16] lost trigger counter, [15:0] total trigger counter
1762 eventFrag->SetAcceptedChannelId(data[w] & 0xffff); // this is actually the lost trigger counter!
1763 eventFrag->SetChannelId(data[w] >> 16);
1764 break;
1765 case 5: // [31:16] CFD sample after zero cross., [15:0] CFD sample before zero cross.
1766 //eventFrag->CfdAfterZC(data[w]&0xffff);
1767 //eventFrag->CfdBeforeZC(data[w]>>16);
1768 w++;
1769 break;
1770 case 7: // fixed value of 0x12345678
1771 if(data[w] != 0x12345678) {
1772 if(!Options()->SuppressErrors()) {
1773 std::cerr << "Failed to get debug data word 0x12345678, got " << std::hex << std::setw(8) << std::setfill('0') << data[w] << std::dec << std::setfill(' ') << std::endl;
1774 }
1775 break;
1776 }
1777 break;
1778 default:
1779 break;
1780 }
1781 ++w;
1782 }
1783 eventFrag->SetCcShort(data[w] & 0x7fff);
1784 eventFrag->SetCcLong((data[w] >> 15) & 0x1); //this is actually the over-range bit!
1785 eventFrag->SetCharge(static_cast<Int_t>(data[w++] >> 16));
1786 Push(GoodOutputQueues(), std::make_shared<TFragment>(*eventFrag));
1787 eventFrag->Clear();
1788 ++nofFragments;
1789 event->IncrementGoodFrags();
1790 } // while(w < size)
1791 } // for(uint8_t channel = 0; channel < 16; channel += 2)
1792 } // for(int board = 0; w < size; ++board)
1793
1794 return nofFragments;
1795}
1796
1797int TGRSIDataParser::CaenPhaToFragment(uint32_t* data, int size, std::shared_ptr<TMidasEvent>& event)
1798{
1799 /// Converts a Caen flavoured MIDAS events into TFragments and returns the number of events processed
1800 std::shared_ptr<TFragment> eventFrag = std::make_shared<TFragment>();
1801 int w = 0;
1802 int nofFragments = 0;
1803
1804 if(Options() == nullptr) {
1806 }
1807
1808 for(int board = 0; w < size; ++board) {
1809 // read board aggregate header
1810 if(data[w] >> 28 != 0xa) {
1811 if(data[w] == 0x0) {
1812 while(w < size) {
1813 if(data[w++] != 0x0) {
1814 if(!Options()->SuppressErrors()) {
1815 std::cerr << board << ". board - failed on first word, found empty word, but not all following words were empty: " << w - 1 << " 0x" << std::hex << std::setw(8) << std::setfill('0') << data[w - 1] << std::dec << std::setfill(' ') << std::endl;
1816 }
1817 return -w;
1818 }
1819 }
1820 return nofFragments;
1821 }
1822 if(!Options()->SuppressErrors()) {
1823 std::cerr << board << ". board - failed on first word 0x" << std::hex << std::setw(8) << std::setfill('0') << data[w] << std::dec << std::setfill(' ') << ", highest nibble should have been 0xa!" << std::endl;
1824 }
1825 return -w;
1826 }
1827 int32_t numWordsBoard = data[w++] & 0xfffffff; // this is the number of 32-bit words from this board
1828 if(w - 1 + numWordsBoard > size) {
1829 if(!Options()->SuppressErrors()) {
1830 std::cerr << "0 - Missing words, at word " << w - 1 << ", expecting " << numWordsBoard << " more words for board " << board << " (bank size " << size << ")" << std::endl;
1831 }
1832 return -w;
1833 }
1834 uint8_t boardId = data[w] >> 27; // GEO address of board (can be set via register 0xef08 for VME)
1835 //bool failFlag = (data[w]>>26) & 0x1; // board fail flag (PLL lock lost or overheating)
1836 //uint16_t pattern = (data[w]>>8) & 0x7fff; // value read from LVDS I/O (VME only)
1837 uint8_t channelMask = data[w++] & 0xff; // which channels are in this board aggregate
1838 ++w; //uint32_t boardCounter = data[w++]&0x7fffff; // ??? "counts the board aggregate"
1839 uint32_t boardTime = data[w++]; // time of creation of aggregate (does not correspond to a physical quantity)
1840 //if(boardCounter < gBoardCounter) {
1841 // std::cerr<<"current board counter "<<boardCounter<<" is less than previous one "<<gBoardCounter<<", skipping this data"<<std::endl;
1842 // return nofFragments;
1843 //}
1844 //gBoardCounter = boardCounter;
1845
1846 for(uint8_t channel = 0; channel < 8; ++channel) {
1847 // check if the bit for this channel is set in the channel mask
1848 if(((channelMask >> channel) & 0x1) == 0x0) {
1849 continue;
1850 }
1851 // read channel aggregate header
1852 if(data[w] >> 31 != 0x1) {
1853 if(!Options()->SuppressErrors()) {
1854 std::cerr << "Failed on first word 0x" << std::hex << std::setw(8) << std::setfill('0') << data[w] << std::dec << std::setfill(' ') << ", highest bit should have been set (to get format info)!" << std::endl;
1855 }
1856 return -w;
1857 }
1858 int32_t numWords = data[w++] & 0x7fffffff; //per channel
1859 if(w >= size) {
1860 if(!Options()->SuppressErrors()) {
1861 std::cerr << "1 - Missing words, got only " << w - 1 << " words for channel " << channel << " (bank size " << size << ")" << std::endl;
1862 }
1863 return -w;
1864 }
1865 //bool dualTrace = ((data[w]>>31) == 0x1);
1866 //bool energyEnabled = ((data[w]>>30) == 0x1);
1867 //bool timeEnabled = ((data[w]>>29) == 0x1);
1868 bool extras = (((data[w] >> 28) & 0x1) == 0x1);
1869 bool waveform = (((data[w] >> 27) & 0x1) == 0x1);
1870 uint8_t extraFormat = ((data[w] >> 24) & 0x7);
1871 //for now we ignore the information which traces are stored:
1872 //bits 22,23: 00 = "Input", 01 = "RC-CR - first step", 10 = "RC-CR2 - second step", 11 = "Trapezoid"
1873 //bits 20,21: 00 = "Input", 01 = "Threshold - of RC-CR2", 10 = "Trapezoid minus baseline", 11 = "baseline of trapezoid"
1874 //bits 16-19: 0000 = "Peaking" - aka when energy is evaluated,
1875 // 0001 = "Armed" - when RC-CR2 crosses threshold,
1876 // 0010 = "Peak Run" - starts with trigger until end of event,
1877 // 0011 = "Pile-Up" - time interval when energy calc. is disabled due to pile-up,
1878 // 0100 = "Peaking" - aka when energy is evaluated (again?),
1879 // 0101 = "Trg Validation Window" - trigger validation acceptance window TVAW,
1880 // 0110 = "BSL Freeze" - shows when baseline is frozen for energy evaluation,
1881 // 0111 = "Trg Holdoff" - shows trigger holdoff parameter,
1882 // 1000 = "Trg Validation" - shows trigger validation signal TRG_VAL,
1883 // 1001 = "Acq Busy" - 1 if board is busy or vetoed,
1884 // 1010 = "Trg Window" - not used,
1885 // 1011 = "Ext Trg" - shows external trigger when available,
1886 // 1100 = "Busy" - shows when memory board is full
1887 int numSampleWords = 4 * (data[w++] & 0xffff); // this is actually the number of samples divided by eight, 2 sample per word => 4*
1888 if(w >= size) {
1889 if(!Options()->SuppressErrors()) {
1890 std::cerr << "2 - Missing words, got only " << w - 1 << " words for channel " << channel << " (bank size " << size << ")" << std::endl;
1891 }
1892 return -w;
1893 }
1894 int eventSize = numSampleWords + 2; // +2 = trigger time words and charge word
1895 if(extras) { ++eventSize; }
1896 if(numWords % eventSize != 2 && !(eventSize == 2 && numWords % eventSize == 0)) { // 2 header words plus n*eventSize should make up one channel aggregate
1897 if(!Options()->SuppressErrors()) {
1898 std::cerr << numWords << " words in channel aggregate, event size is " << eventSize << " (" << numWords % eventSize << ") => " << static_cast<double>(numWords - 2.) / static_cast<double>(eventSize) << " events?" << std::endl;
1899 }
1900 return -w;
1901 }
1902
1903 // read channel data
1904 for(int ev = 0; ev < (numWords - 2) / eventSize; ++ev) { // -2 = 2 header words for channel aggregate
1905 eventFrag->SetDaqTimeStamp(boardTime);
1906 eventFrag->SetAddress(0x8000 + (boardId * 0x100) + channel + (data[w] >> 31)); // highest bit indicates odd channel
1907 eventFrag->SetDetectorType(0); // PHA firmware only used for HPGe?
1908 // these timestamps are in 2ns units
1909 eventFrag->SetTimeStamp(data[w++] & 0x7fffffff);
1910 if(waveform) {
1911 if(w + numSampleWords >= size) { // need to read at least the sample words plus the charge/extra word
1912 if(!Options()->SuppressErrors()) {
1913 std::cerr << "3 - Missing " << numSampleWords << " waveform words, got only " << w - 1 << " words for channel " << channel << " (bank size " << size << ")" << std::endl;
1914 }
1915 return -w;
1916 }
1917 for(int s = 0; s < numSampleWords && w < size; ++s, ++w) {
1918 // we don't care if we use dual trace and which bits are what (analog of digital waveform)
1919 // everything gets put into the normale waveform and will have to be separated during analysis
1920 // higher bits are later sample
1921 eventFrag->AddWaveformSample(data[w] & 0xffff);
1922 eventFrag->AddWaveformSample((data[w] >> 16) & 0xffff);
1923 }
1924 } else {
1925 if(w >= size) { // need to read at least the sample words plus the charge/extra word
1926 if(!Options()->SuppressErrors()) {
1927 std::cerr << "3 - Missing words, got only " << w - 1 << " words for channel " << channel << " (bank size " << size << ")" << std::endl;
1928 }
1929 return -w;
1930 }
1931 }
1932 if(extras) {
1933 //std::cout<<eventFrag->GetAddress()<<" - extra word format "<<static_cast<int>(extraFormat)<<": 0x"<<std::hex<<data[w]<<std::dec<<std::endl;
1934 switch(extraFormat) {
1935 case 0: // [31:16] extended time stamp, [15:0] trapezoid baseline*4
1936 //eventFrag->Baseline(data[w]&0xffff);
1937 eventFrag->SetTimeStamp(eventFrag->GetTimeStamp() | static_cast<uint64_t>(data[w] & 0xffff0000) << 15);
1938 break;
1939 case 2: // [31:16] extended time stamp, [15:0] fine time stamp (linear int. of RC-CR2 before and after zero-crossing)
1940 eventFrag->SetTimeStamp(eventFrag->GetTimeStamp() | static_cast<uint64_t>(data[w] & 0xffff0000) << 15);
1941 eventFrag->SetCfd(data[w] & 0xffff);
1942 break;
1943 case 4: // [31:16] lost trigger counter, [15:0] total trigger counter
1944 eventFrag->SetAcceptedChannelId(data[w] & 0xffff); // this is actually the lost trigger counter!
1945 eventFrag->SetChannelId(data[w] >> 16);
1946 break;
1947 case 5: // [31:16] sample before zero cross., [15:0] sample after zero cross.
1948 //eventFrag->CfdBeforeZC(data[w]&0xffff);
1949 //eventFrag->CfdAfterZC(data[w]>>16);
1950 ++w;
1951 break;
1952 case 1: // reserved
1953 case 3: // reserved
1954 case 7: // reserved
1955 break;
1956 default:
1957 break;
1958 }
1959 ++w;
1960 }
1961 // highest bit is actually the pile-up or roll-over bit!
1962 eventFrag->SetCharge(static_cast<Int_t>(data[w] & 0xffff));
1963 // extras [20:16] or [23:16]?
1964 // 0 - lost event due to full memory board
1965 // 1 - roll over of time stamp (set by bit[26] of 0x1n80 to create fake event with this bit set)
1966 // 2 - reserved
1967 // 3 - fake event - from time stamp roll-over
1968 // 4 - input saturation
1969 // 5 - lost trigger - every n lost events this flag is high (n from bits[17:16] of 0x1na0
1970 // 6 - total trigger - every n total events this flag is high (n from bits[17:16] of 0x1na0
1971 // 7 - match coincidence - if bit[19] of 0x1na0 set then all events matching coincidence criteria are saved with this bit
1972 // 8 - no match coincidence - if bit[19] of 0x1na0 set then all events NOT matching coincidence criteria are saved with this bit
1973 ++w;
1974 Push(GoodOutputQueues(), std::make_shared<TFragment>(*eventFrag));
1975 eventFrag->Clear();
1976 ++nofFragments;
1977 event->IncrementGoodFrags();
1978 } // while(w < size)
1979 } // for(uint8_t channel = 0; channel < 16; channel += 2)
1980 } // for(int board = 0; w < size; ++board)
1981
1982 return nofFragments;
1983}
1984
1985/////////////***************************************************************/////////////
1986/////////////***************************************************************/////////////
1987/////////////***************************************************************/////////////
1988/////////////***************************************************************/////////////
1989/////////////***************************************************************/////////////
1990/////////////***************************************************************/////////////
1991
1992int TGRSIDataParser::EPIXToScalar(float* data, int size, unsigned int midasSerialNumber, time_t midasTime)
1993{
1994 int NumFragsFound = 1;
1995 std::shared_ptr<TEpicsFrag> EXfrag = std::make_shared<TEpicsFrag>();
1996
1997 EXfrag->DaqTimeStamp(midasTime);
1998 EXfrag->DaqId(midasSerialNumber);
1999
2000 for(int x = 0; x < size; x++) {
2001 EXfrag->AddData(data[x]);
2002 EXfrag->AddName(TEpicsFrag::GetEpicsVariableName(x));
2003 }
2004
2005 ScalerOutputQueue()->Push(EXfrag);
2006 return NumFragsFound;
2007}
2008
2009/////////////***************************************************************/////////////
2010/////////////***************************************************************/////////////
2011/////////////**************************EMMA Stuff***************************/////////////
2012/////////////***************************************************************/////////////
2013/////////////***************************************************************/////////////
2014/////////////***************************************************************/////////////
2015
2016static Long64_t xferhfts; // Time stamp to be transferred from ADC to TDC; 10 ns ticks
2017static time_t xfermidts; // Midas time stamp of events, hopefully the same
2018unsigned int xfermidsn; // Midas serial number
2019
2020int TGRSIDataParser::EmmaMadcDataToFragment(const uint32_t* const data, int size, std::shared_ptr<TMidasEvent>& event)
2021{
2022 /// Converts a MIDAS File from the Emma DAQ into a TFragment.
2023 int numFragsFound = 0;
2024 std::shared_ptr<TFragment> eventFrag = std::make_shared<TFragment>();
2025 xfermidts = event->GetTimeStamp(); // to check against EMMT bank
2026 eventFrag->SetDaqTimeStamp(xfermidts);
2027 xfermidsn = event->GetSerialNumber(); // to chck againts EMMT bank
2028 eventFrag->SetDaqId(xfermidsn);
2029 eventFrag->SetDetectorType(12);
2030
2031 int x = 0;
2032 uint32_t dword = *(data + x);
2033
2034 uint32_t type = 0;
2035 uint32_t adcchannel = 0;
2036 uint32_t adcdata = 0;
2037 uint32_t adctimestamp = 0;
2038 uint32_t adchightimestamp = 0;
2039
2040 eventFrag->SetTimeStamp(0);
2041 for(x = size; x-- > 0;) { // Reads the event backwards
2042 dword = *(data + x);
2043 type = (dword & 0xf0000000) >> 28;
2044 switch(type) {
2045 case 0x0: // Reads the charge and channel number
2046 {
2047 if((dword & 0x00800000) != 0) {
2048 adchightimestamp = dword & 0x0000ffff;
2049 eventFrag->AppendTimeStamp((static_cast<Long64_t>(adchightimestamp)) * static_cast<Long64_t>(0x0000000040000000)); // This should shift the time stamp 30 bits
2050 xferhfts = eventFrag->GetTimeStamp();
2051 } else if((dword & 0x04000000) != 0) { // GH verify that this is a good ADC reading
2052 adcchannel = (dword >> 16) & 0x1F; // ADC Channel Number
2053 adcdata = (dword & 0xfff); // ADC Charge
2054 std::shared_ptr<TFragment> transferfrag = std::make_shared<TFragment>(*eventFrag);
2055 transferfrag->SetCharge(static_cast<Int_t>(adcdata));
2056 transferfrag->SetAddress(0x800000 + adcchannel);
2057 TChannel* chan = TChannel::GetChannel(transferfrag->GetAddress(), false);
2058 if(chan == nullptr) {
2059 chan = Channel();
2060 }
2061 Push(GoodOutputQueues(), transferfrag);
2062 numFragsFound++;
2063 }
2064 } break;
2065
2066 case 0x4: // First DWORD in event, read last and writes the fragment
2067 // numFragsFound++;
2068 eventFrag = nullptr;
2069 return numFragsFound;
2070 break;
2071
2072 case 0xe:
2073 case 0xf:
2074 case 0xd:
2075 case 0xc: // Last 30 bits of timestamp
2076 adctimestamp = (dword & 0x3FFFFFFF);
2077 eventFrag->AppendTimeStamp(static_cast<Long64_t>(adctimestamp));
2078 break;
2079 default: break;
2080 } // end swich
2081 } // end for read backwards
2082
2083 return numFragsFound;
2084}
2085
2086// kludge by GH
2087static uint32_t wraparoundcounter = 0xffffffff; // Needed for bad data at start of run before GRIFFIN starts
2088static uint32_t lasttimestamp; // "last" time stamp for simple wraparound algorightm
2089static uint32_t countsbetweenwraps; // number of counts between wraparounds
2090
2091int TGRSIDataParser::EmmaTdcDataToFragment(uint32_t* data, int size, std::shared_ptr<TMidasEvent>& event)
2092{
2093 /// Building TDC events, duplicating logic from EmmaMadcDataToFragment
2094 int numFragsFound = 0;
2095 std::shared_ptr<TFragment> eventFrag = std::make_shared<TFragment>();
2096 eventFrag->SetDaqTimeStamp(event->GetTimeStamp());
2097 eventFrag->SetDaqId(event->GetSerialNumber());
2098 eventFrag->SetDetectorType(13);
2099
2100 int x = 0;
2101 int failedWord = -1; // Variable stores which word we failed on (if we fail). This is somewhat duplicate information
2102 // to fState, but makes things easier to track.
2103 bool multipleErrors = false; // Variable to store if multiple errors occured parsing one fragment
2104 uint32_t tmpTimestamp = 0;
2105 uint32_t tmpAddress = 0;
2106 Long64_t ts = 0;
2107
2108 std::vector<uint32_t> addresses;
2109 std::vector<uint32_t> charges;
2110
2111 // we simply loop through the data and read what we get. No checks are made that every word we want is present.
2112 for(x = 0; x < size; ++x) {
2113 switch((data[x] >> 27) & 0x1F) {
2114 case 0x8: //global header
2115 eventFrag->SetModuleType(data[x] & 0x1f); // GEO
2116 eventFrag->SetAcceptedChannelId((data[x] >> 5) & 0x3fffff); // event count
2117 break;
2118 case 0x1: //TDC header
2119 tmpAddress = (data[x] >> 16) & 0x300; //16 = 24 - 8
2120 eventFrag->SetChannelId((data[x] >> 12) & 0xfff); // event id
2121 eventFrag->SetNetworkPacketNumber(data[x] & 0xfff); // bunch id
2122 break;
2123 case 0x0: // TDC measurement
2124 // we can get multiple of these per event, but we need the subsequent information from the trailer etc.
2125 // so we store the words for now and build fragments at the very end
2126 //
2127 // we use the trailing/leading bit as additional address information
2128 // VB's original code: addresses.push_back(((data[x] >> 18) & 0x800) | tmpAddress | ((data[x] >> 19) & 0x7f));//15 = 26 - 11
2129 addresses.push_back(0x900000 + ((data[x] >> 19) & 0xff)); // address = 0x00900000 + channel + 0x80 for a trailing measurement
2130 charges.push_back(data[x] & 0x7ffff);
2131 break;
2132 case 0x3: // TDC trailer
2133 if((tmpAddress != ((data[x] >> 16) & 0x300)) || (eventFrag->GetChannelId() != ((data[x] >> 12) & 0xfff))) {
2134 // either the trailer tdc doesn't match the header tdc, or the trailer event id doesn't match the header event id
2135 TParsingDiagnostics::Get()->BadFragment(13); // hard-coded 13 for TDC for now
2138 failedWord = x;
2139 } else {
2140 multipleErrors = true;
2141 }
2142 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*eventFrag, data, size, failedWord, multipleErrors));
2143 }
2144 eventFrag->SetNumberOfPileups(data[x] & 0xfff);
2145 break;
2146 case 0x4: // TDC error
2147 eventFrag->SetAddress((data[x] >> 16) & 0x300); //16 = 24 - 8
2148 eventFrag->SetCharge(static_cast<Int_t>((data[x]) & 0xFFF)); // error flags
2149 TParsingDiagnostics::Get()->BadFragment(13); // hard-coded 13 for TDC for now
2152 failedWord = x;
2153 } else {
2154 multipleErrors = true;
2155 }
2156 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*eventFrag, data, size, failedWord, multipleErrors));
2157 break;
2158 case 0x11: // extended trigger time
2159 tmpTimestamp = (data[x] & 0x7FFFFFF) << 5;
2160 break;
2161 case 0x10: // trailer
2162 //(data[x] >> 26) & 1 - trigger lost
2163 //(data[x] >> 25) & 1 - output buffer overflow
2164 //(data[x] >> 24) & 1 - tdc error
2165 //(data[x] >> 5) & 0xFFFF - word count
2166 tmpTimestamp = tmpTimestamp | ((data[x]) & 0x1f); // GEO bits of trailer include additional 5 bits of extended trigger time
2167 // GH Handle wraparound
2168 if(tmpTimestamp < lasttimestamp) { // Assume this means you wrapped around
2169 wraparoundcounter++; // How many times it wrapped around
2170 countsbetweenwraps = 0; // Reset wraparound counter
2171 }
2172 lasttimestamp = tmpTimestamp; // so far so good
2173 ts = static_cast<Long64_t>(lasttimestamp); // start with 32 bits
2174 ts += static_cast<Long64_t>(0x100000000) * static_cast<Long64_t>(wraparoundcounter); // add wrap around
2175 ts = ts * static_cast<Long64_t>(5); // multiply by 5
2176 ts = ts >> 1; // divide by 2
2177 // And now that we've actually done all this:
2178 // Check if there's a somewhat valid timestamp from an ADC
2179 // the && 0 at the end suppresses the xfer
2180 if((event->GetSerialNumber() == xfermidsn) && (event->GetTimeStamp() == xfermidts)) { // Valid data from prior MADC bank
2181 eventFrag->SetTimeStamp(xferhfts);
2182 } else {
2183 eventFrag->SetTimeStamp(ts);
2184 }
2185 // got all the data, so now we can loop over the hits and write them
2186 if(addresses.size() != charges.size()) {
2187 std::cout << "Something went horribly wrong, the number of addresses read " << addresses.size() << " doesn't match the number of charges read " << charges.size() << std::endl;
2188 return 0;
2189 }
2190 for(size_t i = 0; i < addresses.size(); ++i) {
2191 size_t duped = 0;
2192 if(i > 0) {
2193 for(size_t j = 0; j < i; j++) {
2194 if(addresses[i] == addresses[j]) {
2195 duped++;
2196 }
2197 }
2198 }
2199 if(duped == 0) {
2200 eventFrag->SetAddress(addresses[i]);
2201 eventFrag->SetCharge(static_cast<Int_t>(charges[i]));
2202 Push(GoodOutputQueues(), std::make_shared<TFragment>(*eventFrag));
2203 ++numFragsFound;
2204 }
2205 }
2206
2207 // clear the old data
2208 addresses.clear();
2209 charges.clear();
2210 tmpTimestamp = 0;
2211 tmpAddress = 0;
2212 break;
2213 default:
2214 TParsingDiagnostics::Get()->BadFragment(13); // hard-coded 13 for TDC for now
2217 failedWord = x;
2218 } else {
2219 multipleErrors = true;
2220 }
2221 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*eventFrag, data, size, failedWord, multipleErrors));
2222 break;
2223 }
2224 }
2225 return numFragsFound;
2226}
2227
2228int TGRSIDataParser::EmmaRawDataToFragment(uint32_t* data, int size, std::shared_ptr<TMidasEvent>&)
2229{
2230 /// Extract SRAW data, i.e. the instantaneous rates
2231 auto* scaler = new TScalerData;
2232 scaler->SetAddress(0xfffe); // magic address for raw scaler
2233 // counter used to set time
2234 static UInt_t nofRawScalers = 0;
2235 scaler->SetLowTimeStamp(nofRawScalers++);
2236 scaler->SetScaler(data, size);
2237 TRateScalerQueue::Get()->Add(scaler);
2238 return 0;
2239}
2240
2241int TGRSIDataParser::EmmaSumDataToFragment(uint32_t* data, int size, std::shared_ptr<TMidasEvent>&)
2242{
2243 /// Extract SSUM data, i.e. the cumulative counts
2244 auto* scaler = new TScalerData;
2245 scaler->SetAddress(0xffff); // magic address for sum scaler
2246 // counter used to set time
2247 static UInt_t nofSumScalers = 0;
2248 scaler->SetLowTimeStamp(nofSumScalers++);
2249 scaler->SetScaler(data, size);
2250 TRateScalerQueue::Get()->Add(scaler);
2251 return 0;
2252}
#define DYELLOW
Definition Globals.h:16
#define DRED
Definition Globals.h:18
#define BLUE
Definition Globals.h:6
#define DBLUE
Definition Globals.h:15
#define RED
Definition Globals.h:9
std::string hex(T val, int width=-1)
Definition Globals.h:129
#define RESET_COLOR
Definition Globals.h:5
static time_t xfermidts
unsigned int xfermidsn
static Long64_t xferhfts
static uint32_t lasttimestamp
static uint32_t countsbetweenwraps
static uint32_t wraparoundcounter
static TChannel * GetChannel(unsigned int temp_address, bool warn=false)
Definition TChannel.cxx:476
const char * GetDigitizerTypeString() const
Definition TChannel.h:170
bool NoWaveforms() const
TChannel * Channel() const
std::vector< std::shared_ptr< ThreadsafeQueue< std::shared_ptr< const TFragment > > > > & GoodOutputQueues()
Definition TDataParser.h:99
virtual std::shared_ptr< ThreadsafeQueue< std::shared_ptr< const TBadFragment > > > & BadOutputQueue()
Definition TDataParser.h:71
TFragmentMap FragmentMap() const
void Push(ThreadsafeQueue< std::shared_ptr< const TBadFragment > > &queue, const std::shared_ptr< TBadFragment > &frag)
std::map< UInt_t, Long64_t > LastTimeStampMap() const
virtual std::shared_ptr< ThreadsafeQueue< std::shared_ptr< TEpicsFrag > > > & ScalerOutputQueue()
Definition TDataParser.h:73
bool RecordDiag() const
static TGRSIOptions * Options()
uint64_t LastTriggerId() const
bool FragmentHasWaveform() const
uint64_t MaxTriggerId() const
void Add(TScalerData *)
static TDeadtimeScalerQueue * Get()
static std::string GetEpicsVariableName(const int &index)
bool Add(const std::shared_ptr< TFragment > &, const std::vector< Int_t > &, const std::vector< Short_t > &)
const char * what() const noexcept override
bool SetGRIFChannelTriggerId(uint32_t, const std::shared_ptr< TFragment > &)
bool SetNewPPGPattern(uint32_t, TPPGData *)
int RFScalerToFragment(uint32_t *data, int size, const std::shared_ptr< TFragment > &frag)
void SetTIGCfd(uint32_t, const std::shared_ptr< TFragment > &)
int EmmaMadcDataToFragment(const uint32_t *data, int size, std::shared_ptr< TMidasEvent > &event)
void SetTIGCharge(uint32_t, const std::shared_ptr< TFragment > &)
int GriffinDataToFragment(uint32_t *data, int size, EBank bank, unsigned int midasSerialNumber=0, time_t midasTime=0)
bool SetGRIFPrimaryFilterId(uint32_t, const std::shared_ptr< TFragment > &)
bool SetOldPPGPattern(uint32_t, TPPGData *)
void SetTIGWave(uint32_t, const std::shared_ptr< TFragment > &)
bool SetGRIFPsd(uint32_t, const std::shared_ptr< TFragment > &)
bool SetGRIFPrimaryFilterPattern(uint32_t, const std::shared_ptr< TFragment > &, EBank)
bool SetGRIFTimeStampLow(uint32_t, const std::shared_ptr< TFragment > &)
int ProcessGriffin(uint32_t *data, const int &size, const EBank &bank, std::shared_ptr< TMidasEvent > &event)
bool SetGRIFNetworkPacket(uint32_t, const std::shared_ptr< TFragment > &)
bool SetPPGLowTimeStamp(uint32_t, TPPGData *)
void SetTIGAddress(uint32_t, const std::shared_ptr< TFragment > &)
int Process(std::shared_ptr< TRawEvent >) override
int EPIXToScalar(float *data, int size, unsigned int midasSerialNumber=0, time_t midasTime=0)
int EmmaSumDataToFragment(uint32_t *data, int size, std::shared_ptr< TMidasEvent > &event)
bool SetTIGTriggerID(uint32_t, const std::shared_ptr< TFragment > &)
int CaenPsdToFragment(uint32_t *data, int size, std::shared_ptr< TMidasEvent > &event)
bool SetScalerNetworkPacket(uint32_t, TScalerData *)
bool SetTIGTimeStamp(uint32_t *, const std::shared_ptr< TFragment > &)
bool fIgnoreMissingChannel
flag that's set to TGRSIOptions::IgnoreMissingChannel
bool SetGRIFCc(uint32_t, const std::shared_ptr< TFragment > &)
bool SetScalerValue(int, uint32_t, TScalerData *)
int GriffinDataToPPGEvent(uint32_t *data, int size, unsigned int midasSerialNumber=0, time_t midasTime=0)
int CaenPhaToFragment(uint32_t *data, int size, std::shared_ptr< TMidasEvent > &event)
bool SetPPGHighTimeStamp(uint32_t, TPPGData *)
bool SetScalerLowTimeStamp(uint32_t, TScalerData *)
EDataParserState fState
bool SetGRIFDeadTime(uint32_t, const std::shared_ptr< TFragment > &)
void SetTIGLed(uint32_t, const std::shared_ptr< TFragment > &)
bool SetGRIFWaveForm(uint32_t, const std::shared_ptr< TFragment > &)
int EmmaRawDataToFragment(uint32_t *data, int size, std::shared_ptr< TMidasEvent > &event)
bool SetGRIFHeader(uint32_t, const std::shared_ptr< TFragment > &, EBank)
int EmmaTdcDataToFragment(uint32_t *data, int size, std::shared_ptr< TMidasEvent > &event)
bool SetScalerHighTimeStamp(uint32_t, TScalerData *, int &)
int GriffinDataToScalerEvent(uint32_t *data, int address)
int TigressDataToFragment(uint32_t *data, int size, std::shared_ptr< TMidasEvent > &event)
bool SetPPGNetworkPacket(uint32_t, TPPGData *)
static TGRSIOptions * Get(int argc=0, char **argv=nullptr)
Do not use!
bool SuppressErrors() const
void SetNetworkPacketId(UInt_t packet)
Definition TPPG.h:103
void SetHighTimeStamp(UInt_t highTime)
Definition TPPG.h:66
void SetNewPPG(EPpgPattern newPpg)
Definition TPPG.h:71
void SetOldPPG(EPpgPattern oldPpg)
Definition TPPG.h:87
void SetLowTimeStamp(UInt_t lowTime)
Definition TPPG.h:61
void AddData(TPPGData *pat)
Definition TPPG.cxx:121
void BadFragment(Short_t detType)
void GoodFragment(const std::shared_ptr< const TFragment > &)
void Add(TScalerData *)
static TRateScalerQueue * Get()
static void SetRunStop(double tmp)
Definition TRunInfo.h:229
static void SetRunLength()
Definition TRunInfo.h:231
void SetScaler(size_t index, UInt_t scaler)
Definition TScaler.h:51
void SetAddress(UInt_t address)
Definition TScaler.h:47
void SetNetworkPacketId(UInt_t networkId)
Definition TScaler.h:48
UInt_t GetLowTimeStamp() const
Definition TScaler.h:67
void SetLowTimeStamp(UInt_t lowTime)
Definition TScaler.h:49
void SetHighTimeStamp(UInt_t highTime)
Definition TScaler.h:50
static TParsingDiagnostics * Get(bool verbose=false)
Definition TSingleton.h:33