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 throw TGRSIDataParserException(fState, failedWord, false);
1515 }
1516 // followed by four scaler words (32 bits each)
1517 for(int i = 0; i < 4; ++i) {
1518 if(!SetScalerValue(i, data[x++], scalerEvent)) {
1519 TParsingDiagnostics::Get()->BadFragment(-3); // use detector type -3 for scaler data
1521 failedWord = x;
1522 throw TGRSIDataParserException(fState, failedWord, false);
1523 }
1524 }
1525 // and finally the trailer word with the highest 24 bits of the timestamp
1526 int scalerType = 0;
1527 if(!SetScalerHighTimeStamp(data[x++], scalerEvent, scalerType)) {
1528 TParsingDiagnostics::Get()->BadFragment(-3); // use detector type -3 for scaler data
1530 failedWord = x;
1531 throw TGRSIDataParserException(fState, failedWord, false);
1532 }
1533
1534 if(scalerType == 0) { // deadtime scaler
1535 TDeadtimeScalerQueue::Get()->Add(scalerEvent);
1536 } else if(scalerType == 1) { // rate scaler
1537 // the rate scaler has only one real value, the rate
1538 scalerEvent->ResizeScaler();
1539 TRateScalerQueue::Get()->Add(scalerEvent);
1540 } else { // unknown scaler type
1541 TParsingDiagnostics::Get()->BadFragment(-3); // use detector type -3 for scaler data
1543 failedWord = x;
1544 throw TGRSIDataParserException(fState, failedWord, false);
1545 }
1546
1547 TParsingDiagnostics::Get()->GoodFragment(-3); // use detector type -3 for scaler data
1548 return x;
1549}
1550
1552{
1553 if((value >> 28) != 0xd) {
1554 return false;
1555 }
1556 scalerEvent->SetNetworkPacketId(value & 0x0fffffff);
1557 return true;
1558}
1559
1560bool TGRSIDataParser::SetScalerLowTimeStamp(uint32_t value, TScalerData* scalerEvent)
1561{
1562 // the scaler stores the raw values of low and high timestamp
1563 // GetTimeStamp caluculates the correct (multiplied by 10) timestamp from these
1564 if((value >> 28) != 0xa) {
1565 return false;
1566 }
1567 scalerEvent->SetLowTimeStamp(value & 0x0fffffff);
1568 return true;
1569}
1570
1571bool TGRSIDataParser::SetScalerHighTimeStamp(uint32_t value, TScalerData* scalerEvent, int& type)
1572{
1573 // the scaler stores the raw values of low and high timestamp
1574 // GetTimeStamp caluculates the correct (multiplied by 10) timestamp from these
1575 if((value >> 28) != 0xe || (value & 0xff) != (scalerEvent->GetLowTimeStamp() >> 20)) {
1576 return false;
1577 }
1578 scalerEvent->SetHighTimeStamp((value >> 8) & 0x0000ffff);
1579 type = (value >> 24 & 0xf);
1580 return true;
1581}
1582
1583bool TGRSIDataParser::SetScalerValue(int index, uint32_t value, TScalerData* scalerEvent)
1584{
1585 scalerEvent->SetScaler(index, value);
1586 return true;
1587}
1588
1589int TGRSIDataParser::CaenPsdToFragment(uint32_t* data, int size, std::shared_ptr<TMidasEvent>& event)
1590{
1591 /// Converts a Caen flavoured MIDAS events into TFragments and returns the number of events processed
1592 std::shared_ptr<TFragment> eventFrag = std::make_shared<TFragment>();
1593 int w = 0;
1594 int nofFragments = 0;
1595
1596 if(Options() == nullptr) {
1598 }
1599
1600 for(int board = 0; w < size; ++board) {
1601 // read board aggregate header
1602 if(data[w] >> 28 != 0xa) {
1603 if(data[w] == 0x0) {
1604 while(w < size) {
1605 if(data[w++] != 0x0) {
1606 if(!Options()->SuppressErrors()) {
1607 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;
1608 }
1609 return -w;
1610 }
1611 }
1612 return nofFragments;
1613 }
1614 if(!Options()->SuppressErrors()) {
1615 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;
1616 }
1617 return -w;
1618 }
1619 int32_t numWordsBoard = data[w++] & 0xfffffff; // this is the number of 32-bit words from this board
1620 if(w - 1 + numWordsBoard > size) {
1621 if(!Options()->SuppressErrors()) {
1622 std::cerr << "0 - Missing words, at word " << w - 1 << ", expecting " << numWordsBoard << " more words for board " << board << " (bank size " << size << ")" << std::endl;
1623 }
1624 return -w;
1625 }
1626 uint8_t boardId = data[w] >> 27; // GEO address of board (can be set via register 0xef08 for VME)
1627 //uint16_t pattern = (data[w]>>8) & 0x7fff; // value read from LVDS I/O (VME only)
1628 uint8_t channelMask = data[w++] & 0xff; // which channels are in this board aggregate
1629 ++w; //uint32_t boardCounter = data[w++]&0x7fffff; // ??? "counts the board aggregate"
1630 uint32_t boardTime = data[w++]; // time of creation of aggregate (does not correspond to a physical quantity)
1631 //if(boardCounter < gBoardCounter) {
1632 // std::cerr<<"current board counter "<<boardCounter<<" is less than previous one "<<gBoardCounter<<", skipping this data"<<std::endl;
1633 // return nofFragments;
1634 //}
1635 //gBoardCounter = boardCounter;
1636
1637 for(uint8_t channel = 0; channel < 16; channel += 2) {
1638 if(((channelMask >> (channel / 2)) & 0x1) == 0x0) {
1639 continue;
1640 }
1641 // read channel aggregate header
1642 if(data[w] >> 31 != 0x1) {
1643 if(!Options()->SuppressErrors()) {
1644 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;
1645 }
1646 return -w;
1647 }
1648 int32_t numWords = data[w++] & 0x3fffff; //per channel
1649 if(w >= size) {
1650 if(!Options()->SuppressErrors()) {
1651 std::cerr << "1 - Missing words, got only " << w - 1 << " words for channel " << channel << " (bank size " << size << ")" << std::endl;
1652 }
1653 return -w;
1654 }
1655 if(((data[w] >> 29) & 0x3) != 0x3) {
1656 if(!Options()->SuppressErrors()) {
1657 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;
1658 }
1659 return -w;
1660 }
1661 bool dualTrace = ((data[w] >> 31) == 0x1);
1662 bool extras = (((data[w] >> 28) & 0x1) == 0x1);
1663 bool waveform = (((data[w] >> 27) & 0x1) == 0x1);
1664 uint8_t extraFormat = ((data[w] >> 24) & 0x7);
1665 //for now we ignore the information which traces are stored:
1666 //bits 22,23: if(dualTrace) 00 = "Input and baseline", 01 = "CFD and Baseline", 10 = "Input and CFD"
1667 // else 00 = "Input", 01 = "CFD"
1668 //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"
1669 //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"
1670 int numSampleWords = 4 * (data[w++] & 0xffff); // this is actually the number of samples divided by eight, 2 sample per word => 4*
1671 if(w >= size) {
1672 if(!Options()->SuppressErrors()) {
1673 std::cerr << "2 - Missing words, got only " << w - 1 << " words for channel " << channel << " (bank size " << size << ")" << std::endl;
1674 }
1675 return -w;
1676 }
1677 int eventSize = numSampleWords + 2; // +2 = trigger time words and charge word
1678 if(extras) { ++eventSize; }
1679 if(numWords % eventSize != 2 && !(eventSize == 2 && numWords % eventSize == 0)) { // 2 header words plus n*eventSize should make up one channel aggregate
1680 if(!Options()->SuppressErrors()) {
1681 std::cerr << numWords << " words in channel aggregate, event size is " << eventSize << " => " << static_cast<double>(numWords - 2.) / static_cast<double>(eventSize) << " events?" << std::endl;
1682 }
1683 return -w;
1684 }
1685
1686 // read channel data
1687 for(int ev = 0; ev < (numWords - 2) / eventSize; ++ev) { // -2 = 2 header words for channel aggregate
1688 eventFrag->SetDaqTimeStamp(boardTime);
1689 eventFrag->SetAddress(0x8000 + (boardId * 0x100) + channel + (data[w] >> 31)); // highest bit indicates odd channel
1690 if(eventFrag->GetAddress() == 0x8000) {
1691 eventFrag->SetDetectorType(9); //ZDS will always be in channel 0
1692 } else {
1693 eventFrag->SetDetectorType(6);
1694 }
1695 // these timestamps are in 2ns units
1696 eventFrag->SetTimeStamp(data[w] & 0x7fffffff);
1697 ++w;
1698 if(waveform) {
1699 if(w + numSampleWords >= size) { // need to read at least the sample words plus the charge/extra word
1700 if(!Options()->SuppressErrors()) {
1701 std::cerr << "3 - Missing " << numSampleWords << " waveform words, got only " << w - 1 << " words for channel " << channel << " (bank size " << size << ")" << std::endl;
1702 }
1703 return -w;
1704 }
1705 for(int s = 0; s < numSampleWords && w < size; ++s, ++w) {
1706 //eventFrag->AddDigitalWaveformSample(0, (data[w]>>14)&0x1);
1707 //eventFrag->AddDigitalWaveformSample(1, (data[w]>>15)&0x1);
1708 if(dualTrace) {
1709 // all even samples are from the first trace, all odd ones from the second trace
1710 //eventFrag->AddWaveformSample(data[w]&0x3fff);
1711 //eventFrag->AddWaveformSample((data[w]>>16)&0x3fff);
1712 eventFrag->AddWaveformSample(data[w] & 0xffff);
1713 eventFrag->AddWaveformSample((data[w] >> 16) & 0xffff);
1714 } else {
1715 // both samples are from the first trace
1716 //eventFrag->AddWaveformSample(data[w]&0x3fff);
1717 //eventFrag->AddWaveformSample((data[w]>>16)&0x3fff);
1718 eventFrag->AddWaveformSample(data[w] & 0xffff);
1719 eventFrag->AddWaveformSample((data[w] >> 16) & 0xffff);
1720 }
1721 //eventFrag->AddDigitalWaveformSample(0, (data[w]>>30)&0x1);
1722 //eventFrag->AddDigitalWaveformSample(1, (data[w]>>31)&0x1);
1723 }
1724 } else {
1725 if(w >= size) { // need to read at least the sample words plus the charge/extra word
1726 if(!Options()->SuppressErrors()) {
1727 std::cerr << "3 - Missing words, got only " << w - 1 << " words for channel " << channel << " (bank size " << size << ")" << std::endl;
1728 }
1729 return -w;
1730 }
1731 }
1732 if(extras) {
1733 //std::cout<<eventFrag->GetAddress()<<" - extra word format "<<static_cast<int>(extraFormat)<<": 0x"<<std::hex<<data[w]<<std::dec<<std::endl;
1734 switch(extraFormat) {
1735 case 0: // [31:16] extended time stamp, [15:0] baseline*4
1736 //eventFrag->Baseline(data[w]&0xffff);
1737 eventFrag->SetTimeStamp(eventFrag->GetTimeStamp() | static_cast<uint64_t>(data[w] & 0xffff0000) << 15);
1738 break;
1739 case 1: // [31:16] extended time stamp, 15 trigger lost, 14 over range, 13 1024 triggers, 12 n lost triggers
1740 eventFrag->SetNetworkPacketNumber((data[w] >> 12) & 0xf);
1741 //eventFrag->NLostCount(((data[w]>>12)&0x1) == 0x1);
1742 //eventFrag->KiloCount(((data[w]>>13)&0x1) == 0x1);
1743 //eventFrag->OverRange(((data[w]>>14)&0x1) == 0x1);
1744 //eventFrag->LostTrigger(((data[w]>>15)&0x1) == 0x1);
1745 eventFrag->SetTimeStamp(eventFrag->GetTimeStamp() | static_cast<uint64_t>(data[w] & 0xffff0000) << 15);
1746 break;
1747 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
1748 eventFrag->SetTimeStamp(eventFrag->GetTimeStamp() | static_cast<uint64_t>(data[w] & 0xffff0000) << 15);
1749 eventFrag->SetCfd(data[w] & 0x3ff);
1750 eventFrag->SetNetworkPacketNumber((data[w] >> 12) & 0xf);
1751 //eventFrag->NLostCount(((data[w]>>12)&0x1) == 0x1);
1752 //eventFrag->KiloCount(((data[w]>>13)&0x1) == 0x1);
1753 //eventFrag->OverRange(((data[w]>>14)&0x1) == 0x1);
1754 //eventFrag->LostTrigger(((data[w]>>15)&0x1) == 0x1);
1755 break;
1756 case 4: // [31:16] lost trigger counter, [15:0] total trigger counter
1757 eventFrag->SetAcceptedChannelId(data[w] & 0xffff); // this is actually the lost trigger counter!
1758 eventFrag->SetChannelId(data[w] >> 16);
1759 break;
1760 case 5: // [31:16] CFD sample after zero cross., [15:0] CFD sample before zero cross.
1761 //eventFrag->CfdAfterZC(data[w]&0xffff);
1762 //eventFrag->CfdBeforeZC(data[w]>>16);
1763 w++;
1764 break;
1765 case 7: // fixed value of 0x12345678
1766 if(data[w] != 0x12345678) {
1767 if(!Options()->SuppressErrors()) {
1768 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;
1769 }
1770 break;
1771 }
1772 break;
1773 default:
1774 break;
1775 }
1776 ++w;
1777 }
1778 eventFrag->SetCcShort(data[w] & 0x7fff);
1779 eventFrag->SetCcLong((data[w] >> 15) & 0x1); //this is actually the over-range bit!
1780 eventFrag->SetCharge(static_cast<Int_t>(data[w++] >> 16));
1781 Push(GoodOutputQueues(), std::make_shared<TFragment>(*eventFrag));
1782 eventFrag->Clear();
1783 ++nofFragments;
1784 event->IncrementGoodFrags();
1785 } // while(w < size)
1786 } // for(uint8_t channel = 0; channel < 16; channel += 2)
1787 } // for(int board = 0; w < size; ++board)
1788
1789 return nofFragments;
1790}
1791
1792int TGRSIDataParser::CaenPhaToFragment(uint32_t* data, int size, std::shared_ptr<TMidasEvent>& event)
1793{
1794 /// Converts a Caen flavoured MIDAS events into TFragments and returns the number of events processed
1795 std::shared_ptr<TFragment> eventFrag = std::make_shared<TFragment>();
1796 int w = 0;
1797 int nofFragments = 0;
1798
1799 if(Options() == nullptr) {
1801 }
1802
1803 for(int board = 0; w < size; ++board) {
1804 // read board aggregate header
1805 if(data[w] >> 28 != 0xa) {
1806 if(data[w] == 0x0) {
1807 while(w < size) {
1808 if(data[w++] != 0x0) {
1809 if(!Options()->SuppressErrors()) {
1810 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;
1811 }
1812 return -w;
1813 }
1814 }
1815 return nofFragments;
1816 }
1817 if(!Options()->SuppressErrors()) {
1818 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;
1819 }
1820 return -w;
1821 }
1822 int32_t numWordsBoard = data[w++] & 0xfffffff; // this is the number of 32-bit words from this board
1823 if(w - 1 + numWordsBoard > size) {
1824 if(!Options()->SuppressErrors()) {
1825 std::cerr << "0 - Missing words, at word " << w - 1 << ", expecting " << numWordsBoard << " more words for board " << board << " (bank size " << size << ")" << std::endl;
1826 }
1827 return -w;
1828 }
1829 uint8_t boardId = data[w] >> 27; // GEO address of board (can be set via register 0xef08 for VME)
1830 //bool failFlag = (data[w]>>26) & 0x1; // board fail flag (PLL lock lost or overheating)
1831 //uint16_t pattern = (data[w]>>8) & 0x7fff; // value read from LVDS I/O (VME only)
1832 uint8_t channelMask = data[w++] & 0xff; // which channels are in this board aggregate
1833 ++w; //uint32_t boardCounter = data[w++]&0x7fffff; // ??? "counts the board aggregate"
1834 uint32_t boardTime = data[w++]; // time of creation of aggregate (does not correspond to a physical quantity)
1835 //if(boardCounter < gBoardCounter) {
1836 // std::cerr<<"current board counter "<<boardCounter<<" is less than previous one "<<gBoardCounter<<", skipping this data"<<std::endl;
1837 // return nofFragments;
1838 //}
1839 //gBoardCounter = boardCounter;
1840
1841 for(uint8_t channel = 0; channel < 8; ++channel) {
1842 // check if the bit for this channel is set in the channel mask
1843 if(((channelMask >> channel) & 0x1) == 0x0) {
1844 continue;
1845 }
1846 // read channel aggregate header
1847 if(data[w] >> 31 != 0x1) {
1848 if(!Options()->SuppressErrors()) {
1849 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;
1850 }
1851 return -w;
1852 }
1853 int32_t numWords = data[w++] & 0x7fffffff; //per channel
1854 if(w >= size) {
1855 if(!Options()->SuppressErrors()) {
1856 std::cerr << "1 - Missing words, got only " << w - 1 << " words for channel " << channel << " (bank size " << size << ")" << std::endl;
1857 }
1858 return -w;
1859 }
1860 //bool dualTrace = ((data[w]>>31) == 0x1);
1861 //bool energyEnabled = ((data[w]>>30) == 0x1);
1862 //bool timeEnabled = ((data[w]>>29) == 0x1);
1863 bool extras = (((data[w] >> 28) & 0x1) == 0x1);
1864 bool waveform = (((data[w] >> 27) & 0x1) == 0x1);
1865 uint8_t extraFormat = ((data[w] >> 24) & 0x7);
1866 //for now we ignore the information which traces are stored:
1867 //bits 22,23: 00 = "Input", 01 = "RC-CR - first step", 10 = "RC-CR2 - second step", 11 = "Trapezoid"
1868 //bits 20,21: 00 = "Input", 01 = "Threshold - of RC-CR2", 10 = "Trapezoid minus baseline", 11 = "baseline of trapezoid"
1869 //bits 16-19: 0000 = "Peaking" - aka when energy is evaluated,
1870 // 0001 = "Armed" - when RC-CR2 crosses threshold,
1871 // 0010 = "Peak Run" - starts with trigger until end of event,
1872 // 0011 = "Pile-Up" - time interval when energy calc. is disabled due to pile-up,
1873 // 0100 = "Peaking" - aka when energy is evaluated (again?),
1874 // 0101 = "Trg Validation Window" - trigger validation acceptance window TVAW,
1875 // 0110 = "BSL Freeze" - shows when baseline is frozen for energy evaluation,
1876 // 0111 = "Trg Holdoff" - shows trigger holdoff parameter,
1877 // 1000 = "Trg Validation" - shows trigger validation signal TRG_VAL,
1878 // 1001 = "Acq Busy" - 1 if board is busy or vetoed,
1879 // 1010 = "Trg Window" - not used,
1880 // 1011 = "Ext Trg" - shows external trigger when available,
1881 // 1100 = "Busy" - shows when memory board is full
1882 int numSampleWords = 4 * (data[w++] & 0xffff); // this is actually the number of samples divided by eight, 2 sample per word => 4*
1883 if(w >= size) {
1884 if(!Options()->SuppressErrors()) {
1885 std::cerr << "2 - Missing words, got only " << w - 1 << " words for channel " << channel << " (bank size " << size << ")" << std::endl;
1886 }
1887 return -w;
1888 }
1889 int eventSize = numSampleWords + 2; // +2 = trigger time words and charge word
1890 if(extras) { ++eventSize; }
1891 if(numWords % eventSize != 2 && !(eventSize == 2 && numWords % eventSize == 0)) { // 2 header words plus n*eventSize should make up one channel aggregate
1892 if(!Options()->SuppressErrors()) {
1893 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;
1894 }
1895 return -w;
1896 }
1897
1898 // read channel data
1899 for(int ev = 0; ev < (numWords - 2) / eventSize; ++ev) { // -2 = 2 header words for channel aggregate
1900 eventFrag->SetDaqTimeStamp(boardTime);
1901 eventFrag->SetAddress(0x8000 + (boardId * 0x100) + channel + (data[w] >> 31)); // highest bit indicates odd channel
1902 eventFrag->SetDetectorType(0); // PHA firmware only used for HPGe?
1903 // these timestamps are in 2ns units
1904 eventFrag->SetTimeStamp(data[w++] & 0x7fffffff);
1905 if(waveform) {
1906 if(w + numSampleWords >= size) { // need to read at least the sample words plus the charge/extra word
1907 if(!Options()->SuppressErrors()) {
1908 std::cerr << "3 - Missing " << numSampleWords << " waveform words, got only " << w - 1 << " words for channel " << channel << " (bank size " << size << ")" << std::endl;
1909 }
1910 return -w;
1911 }
1912 for(int s = 0; s < numSampleWords && w < size; ++s, ++w) {
1913 // we don't care if we use dual trace and which bits are what (analog of digital waveform)
1914 // everything gets put into the normale waveform and will have to be separated during analysis
1915 // higher bits are later sample
1916 eventFrag->AddWaveformSample(data[w] & 0xffff);
1917 eventFrag->AddWaveformSample((data[w] >> 16) & 0xffff);
1918 }
1919 } else {
1920 if(w >= size) { // need to read at least the sample words plus the charge/extra word
1921 if(!Options()->SuppressErrors()) {
1922 std::cerr << "3 - Missing words, got only " << w - 1 << " words for channel " << channel << " (bank size " << size << ")" << std::endl;
1923 }
1924 return -w;
1925 }
1926 }
1927 if(extras) {
1928 //std::cout<<eventFrag->GetAddress()<<" - extra word format "<<static_cast<int>(extraFormat)<<": 0x"<<std::hex<<data[w]<<std::dec<<std::endl;
1929 switch(extraFormat) {
1930 case 0: // [31:16] extended time stamp, [15:0] trapezoid baseline*4
1931 //eventFrag->Baseline(data[w]&0xffff);
1932 eventFrag->SetTimeStamp(eventFrag->GetTimeStamp() | static_cast<uint64_t>(data[w] & 0xffff0000) << 15);
1933 break;
1934 case 2: // [31:16] extended time stamp, [15:0] fine time stamp (linear int. of RC-CR2 before and after zero-crossing)
1935 eventFrag->SetTimeStamp(eventFrag->GetTimeStamp() | static_cast<uint64_t>(data[w] & 0xffff0000) << 15);
1936 eventFrag->SetCfd(data[w] & 0xffff);
1937 break;
1938 case 4: // [31:16] lost trigger counter, [15:0] total trigger counter
1939 eventFrag->SetAcceptedChannelId(data[w] & 0xffff); // this is actually the lost trigger counter!
1940 eventFrag->SetChannelId(data[w] >> 16);
1941 break;
1942 case 5: // [31:16] sample before zero cross., [15:0] sample after zero cross.
1943 //eventFrag->CfdBeforeZC(data[w]&0xffff);
1944 //eventFrag->CfdAfterZC(data[w]>>16);
1945 ++w;
1946 break;
1947 case 1: // reserved
1948 case 3: // reserved
1949 case 7: // reserved
1950 break;
1951 default:
1952 break;
1953 }
1954 ++w;
1955 }
1956 // highest bit is actually the pile-up or roll-over bit!
1957 eventFrag->SetCharge(static_cast<Int_t>(data[w] & 0xffff));
1958 // extras [20:16] or [23:16]?
1959 // 0 - lost event due to full memory board
1960 // 1 - roll over of time stamp (set by bit[26] of 0x1n80 to create fake event with this bit set)
1961 // 2 - reserved
1962 // 3 - fake event - from time stamp roll-over
1963 // 4 - input saturation
1964 // 5 - lost trigger - every n lost events this flag is high (n from bits[17:16] of 0x1na0
1965 // 6 - total trigger - every n total events this flag is high (n from bits[17:16] of 0x1na0
1966 // 7 - match coincidence - if bit[19] of 0x1na0 set then all events matching coincidence criteria are saved with this bit
1967 // 8 - no match coincidence - if bit[19] of 0x1na0 set then all events NOT matching coincidence criteria are saved with this bit
1968 ++w;
1969 Push(GoodOutputQueues(), std::make_shared<TFragment>(*eventFrag));
1970 eventFrag->Clear();
1971 ++nofFragments;
1972 event->IncrementGoodFrags();
1973 } // while(w < size)
1974 } // for(uint8_t channel = 0; channel < 16; channel += 2)
1975 } // for(int board = 0; w < size; ++board)
1976
1977 return nofFragments;
1978}
1979
1980/////////////***************************************************************/////////////
1981/////////////***************************************************************/////////////
1982/////////////***************************************************************/////////////
1983/////////////***************************************************************/////////////
1984/////////////***************************************************************/////////////
1985/////////////***************************************************************/////////////
1986
1987int TGRSIDataParser::EPIXToScalar(float* data, int size, unsigned int midasSerialNumber, time_t midasTime)
1988{
1989 int NumFragsFound = 1;
1990 std::shared_ptr<TEpicsFrag> EXfrag = std::make_shared<TEpicsFrag>();
1991
1992 EXfrag->DaqTimeStamp(midasTime);
1993 EXfrag->DaqId(midasSerialNumber);
1994
1995 for(int x = 0; x < size; x++) {
1996 EXfrag->AddData(data[x]);
1997 EXfrag->AddName(TEpicsFrag::GetEpicsVariableName(x));
1998 }
1999
2000 ScalerOutputQueue()->Push(EXfrag);
2001 return NumFragsFound;
2002}
2003
2004/////////////***************************************************************/////////////
2005/////////////***************************************************************/////////////
2006/////////////**************************EMMA Stuff***************************/////////////
2007/////////////***************************************************************/////////////
2008/////////////***************************************************************/////////////
2009/////////////***************************************************************/////////////
2010
2011static Long64_t xferhfts; // Time stamp to be transferred from ADC to TDC; 10 ns ticks
2012static time_t xfermidts; // Midas time stamp of events, hopefully the same
2013unsigned int xfermidsn; // Midas serial number
2014
2015int TGRSIDataParser::EmmaMadcDataToFragment(const uint32_t* const data, int size, std::shared_ptr<TMidasEvent>& event)
2016{
2017 /// Converts a MIDAS File from the Emma DAQ into a TFragment.
2018 int numFragsFound = 0;
2019 std::shared_ptr<TFragment> eventFrag = std::make_shared<TFragment>();
2020 xfermidts = event->GetTimeStamp(); // to check against EMMT bank
2021 eventFrag->SetDaqTimeStamp(xfermidts);
2022 xfermidsn = event->GetSerialNumber(); // to chck againts EMMT bank
2023 eventFrag->SetDaqId(xfermidsn);
2024 eventFrag->SetDetectorType(12);
2025
2026 int x = 0;
2027 uint32_t dword = *(data + x);
2028
2029 uint32_t type = 0;
2030 uint32_t adcchannel = 0;
2031 uint32_t adcdata = 0;
2032 uint32_t adctimestamp = 0;
2033 uint32_t adchightimestamp = 0;
2034
2035 eventFrag->SetTimeStamp(0);
2036 for(x = size; x-- > 0;) { // Reads the event backwards
2037 dword = *(data + x);
2038 type = (dword & 0xf0000000) >> 28;
2039 switch(type) {
2040 case 0x0: // Reads the charge and channel number
2041 {
2042 if((dword & 0x00800000) != 0) {
2043 adchightimestamp = dword & 0x0000ffff;
2044 eventFrag->AppendTimeStamp((static_cast<Long64_t>(adchightimestamp)) * static_cast<Long64_t>(0x0000000040000000)); // This should shift the time stamp 30 bits
2045 xferhfts = eventFrag->GetTimeStamp();
2046 } else if((dword & 0x04000000) != 0) { // GH verify that this is a good ADC reading
2047 adcchannel = (dword >> 16) & 0x1F; // ADC Channel Number
2048 adcdata = (dword & 0xfff); // ADC Charge
2049 std::shared_ptr<TFragment> transferfrag = std::make_shared<TFragment>(*eventFrag);
2050 transferfrag->SetCharge(static_cast<Int_t>(adcdata));
2051 transferfrag->SetAddress(0x800000 + adcchannel);
2052 TChannel* chan = TChannel::GetChannel(transferfrag->GetAddress(), false);
2053 if(chan == nullptr) {
2054 chan = Channel();
2055 }
2056 Push(GoodOutputQueues(), transferfrag);
2057 numFragsFound++;
2058 }
2059 } break;
2060
2061 case 0x4: // First DWORD in event, read last and writes the fragment
2062 // numFragsFound++;
2063 eventFrag = nullptr;
2064 return numFragsFound;
2065 break;
2066
2067 case 0xe:
2068 case 0xf:
2069 case 0xd:
2070 case 0xc: // Last 30 bits of timestamp
2071 adctimestamp = (dword & 0x3FFFFFFF);
2072 eventFrag->AppendTimeStamp(static_cast<Long64_t>(adctimestamp));
2073 break;
2074 default: break;
2075 } // end swich
2076 } // end for read backwards
2077
2078 return numFragsFound;
2079}
2080
2081// kludge by GH
2082static uint32_t wraparoundcounter = 0xffffffff; // Needed for bad data at start of run before GRIFFIN starts
2083static uint32_t lasttimestamp; // "last" time stamp for simple wraparound algorightm
2084static uint32_t countsbetweenwraps; // number of counts between wraparounds
2085
2086int TGRSIDataParser::EmmaTdcDataToFragment(uint32_t* data, int size, std::shared_ptr<TMidasEvent>& event)
2087{
2088 /// Building TDC events, duplicating logic from EmmaMadcDataToFragment
2089 int numFragsFound = 0;
2090 std::shared_ptr<TFragment> eventFrag = std::make_shared<TFragment>();
2091 eventFrag->SetDaqTimeStamp(event->GetTimeStamp());
2092 eventFrag->SetDaqId(event->GetSerialNumber());
2093 eventFrag->SetDetectorType(13);
2094
2095 int x = 0;
2096 int failedWord = -1; // Variable stores which word we failed on (if we fail). This is somewhat duplicate information
2097 // to fState, but makes things easier to track.
2098 bool multipleErrors = false; // Variable to store if multiple errors occured parsing one fragment
2099 uint32_t tmpTimestamp = 0;
2100 uint32_t tmpAddress = 0;
2101 Long64_t ts = 0;
2102
2103 std::vector<uint32_t> addresses;
2104 std::vector<uint32_t> charges;
2105
2106 // we simply loop through the data and read what we get. No checks are made that every word we want is present.
2107 for(x = 0; x < size; ++x) {
2108 switch((data[x] >> 27) & 0x1F) {
2109 case 0x8: //global header
2110 eventFrag->SetModuleType(data[x] & 0x1f); // GEO
2111 eventFrag->SetAcceptedChannelId((data[x] >> 5) & 0x3fffff); // event count
2112 break;
2113 case 0x1: //TDC header
2114 tmpAddress = (data[x] >> 16) & 0x300; //16 = 24 - 8
2115 eventFrag->SetChannelId((data[x] >> 12) & 0xfff); // event id
2116 eventFrag->SetNetworkPacketNumber(data[x] & 0xfff); // bunch id
2117 break;
2118 case 0x0: // TDC measurement
2119 // we can get multiple of these per event, but we need the subsequent information from the trailer etc.
2120 // so we store the words for now and build fragments at the very end
2121 //
2122 // we use the trailing/leading bit as additional address information
2123 // VB's original code: addresses.push_back(((data[x] >> 18) & 0x800) | tmpAddress | ((data[x] >> 19) & 0x7f));//15 = 26 - 11
2124 addresses.push_back(0x900000 + ((data[x] >> 19) & 0xff)); // address = 0x00900000 + channel + 0x80 for a trailing measurement
2125 charges.push_back(data[x] & 0x7ffff);
2126 break;
2127 case 0x3: // TDC trailer
2128 if((tmpAddress != ((data[x] >> 16) & 0x300)) || (eventFrag->GetChannelId() != ((data[x] >> 12) & 0xfff))) {
2129 // either the trailer tdc doesn't match the header tdc, or the trailer event id doesn't match the header event id
2130 TParsingDiagnostics::Get()->BadFragment(13); // hard-coded 13 for TDC for now
2133 failedWord = x;
2134 } else {
2135 multipleErrors = true;
2136 }
2137 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*eventFrag, data, size, failedWord, multipleErrors));
2138 }
2139 eventFrag->SetNumberOfPileups(data[x] & 0xfff);
2140 break;
2141 case 0x4: // TDC error
2142 eventFrag->SetAddress((data[x] >> 16) & 0x300); //16 = 24 - 8
2143 eventFrag->SetCharge(static_cast<Int_t>((data[x]) & 0xFFF)); // error flags
2144 TParsingDiagnostics::Get()->BadFragment(13); // hard-coded 13 for TDC for now
2147 failedWord = x;
2148 } else {
2149 multipleErrors = true;
2150 }
2151 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*eventFrag, data, size, failedWord, multipleErrors));
2152 break;
2153 case 0x11: // extended trigger time
2154 tmpTimestamp = (data[x] & 0x7FFFFFF) << 5;
2155 break;
2156 case 0x10: // trailer
2157 //(data[x] >> 26) & 1 - trigger lost
2158 //(data[x] >> 25) & 1 - output buffer overflow
2159 //(data[x] >> 24) & 1 - tdc error
2160 //(data[x] >> 5) & 0xFFFF - word count
2161 tmpTimestamp = tmpTimestamp | ((data[x]) & 0x1f); // GEO bits of trailer include additional 5 bits of extended trigger time
2162 // GH Handle wraparound
2163 if(tmpTimestamp < lasttimestamp) { // Assume this means you wrapped around
2164 wraparoundcounter++; // How many times it wrapped around
2165 countsbetweenwraps = 0; // Reset wraparound counter
2166 }
2167 lasttimestamp = tmpTimestamp; // so far so good
2168 ts = static_cast<Long64_t>(lasttimestamp); // start with 32 bits
2169 ts += static_cast<Long64_t>(0x100000000) * static_cast<Long64_t>(wraparoundcounter); // add wrap around
2170 ts = ts * static_cast<Long64_t>(5); // multiply by 5
2171 ts = ts >> 1; // divide by 2
2172 // And now that we've actually done all this:
2173 // Check if there's a somewhat valid timestamp from an ADC
2174 // the && 0 at the end suppresses the xfer
2175 if((event->GetSerialNumber() == xfermidsn) && (event->GetTimeStamp() == xfermidts)) { // Valid data from prior MADC bank
2176 eventFrag->SetTimeStamp(xferhfts);
2177 } else {
2178 eventFrag->SetTimeStamp(ts);
2179 }
2180 // got all the data, so now we can loop over the hits and write them
2181 if(addresses.size() != charges.size()) {
2182 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;
2183 return 0;
2184 }
2185 for(size_t i = 0; i < addresses.size(); ++i) {
2186 size_t duped = 0;
2187 if(i > 0) {
2188 for(size_t j = 0; j < i; j++) {
2189 if(addresses[i] == addresses[j]) {
2190 duped++;
2191 }
2192 }
2193 }
2194 if(duped == 0) {
2195 eventFrag->SetAddress(addresses[i]);
2196 eventFrag->SetCharge(static_cast<Int_t>(charges[i]));
2197 Push(GoodOutputQueues(), std::make_shared<TFragment>(*eventFrag));
2198 ++numFragsFound;
2199 }
2200 }
2201
2202 // clear the old data
2203 addresses.clear();
2204 charges.clear();
2205 tmpTimestamp = 0;
2206 tmpAddress = 0;
2207 break;
2208 default:
2209 TParsingDiagnostics::Get()->BadFragment(13); // hard-coded 13 for TDC for now
2212 failedWord = x;
2213 } else {
2214 multipleErrors = true;
2215 }
2216 Push(*BadOutputQueue(), std::make_shared<TBadFragment>(*eventFrag, data, size, failedWord, multipleErrors));
2217 break;
2218 }
2219 }
2220 return numFragsFound;
2221}
2222
2223int TGRSIDataParser::EmmaRawDataToFragment(uint32_t* data, int size, std::shared_ptr<TMidasEvent>&)
2224{
2225 /// Extract SRAW data, i.e. the instantaneous rates
2226 auto* scaler = new TScalerData;
2227 scaler->SetAddress(0xfffe); // magic address for raw scaler
2228 // counter used to set time
2229 static UInt_t nofRawScalers = 0;
2230 scaler->SetLowTimeStamp(nofRawScalers++);
2231 scaler->SetScaler(data, size);
2232 TRateScalerQueue::Get()->Add(scaler);
2233 return 0;
2234}
2235
2236int TGRSIDataParser::EmmaSumDataToFragment(uint32_t* data, int size, std::shared_ptr<TMidasEvent>&)
2237{
2238 /// Extract SSUM data, i.e. the cumulative counts
2239 auto* scaler = new TScalerData;
2240 scaler->SetAddress(0xffff); // magic address for sum scaler
2241 // counter used to set time
2242 static UInt_t nofSumScalers = 0;
2243 scaler->SetLowTimeStamp(nofSumScalers++);
2244 scaler->SetScaler(data, size);
2245 TRateScalerQueue::Get()->Add(scaler);
2246 return 0;
2247}
#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
const Double_t s
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:459
const char * GetDigitizerTypeString() const
Definition TChannel.h:173
bool NoWaveforms() const
TChannel * Channel() const
std::vector< std::shared_ptr< ThreadsafeQueue< std::shared_ptr< const TFragment > > > > & GoodOutputQueues()
virtual std::shared_ptr< ThreadsafeQueue< std::shared_ptr< const TBadFragment > > > & BadOutputQueue()
Definition TDataParser.h:73
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:75
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:105
void SetHighTimeStamp(UInt_t highTime)
Definition TPPG.h:68
void SetNewPPG(EPpgPattern newPpg)
Definition TPPG.h:73
void SetOldPPG(EPpgPattern oldPpg)
Definition TPPG.h:89
void SetLowTimeStamp(UInt_t lowTime)
Definition TPPG.h:63
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:223
static void SetRunLength()
Definition TRunInfo.h:225
void SetScaler(size_t index, UInt_t scaler)
Definition TScaler.h:52
void SetAddress(UInt_t address)
Definition TScaler.h:48
void SetNetworkPacketId(UInt_t networkId)
Definition TScaler.h:49
UInt_t GetLowTimeStamp() const
Definition TScaler.h:68
void SetLowTimeStamp(UInt_t lowTime)
Definition TScaler.h:50
void SetHighTimeStamp(UInt_t highTime)
Definition TScaler.h:51
static TParsingDiagnostics * Get(bool verbose=false)
Definition TSingleton.h:33