GRSISort "v4.0.0.5"
An extension of the ROOT analysis Framework
Loading...
Searching...
No Matches
THILDataParser.cxx
Go to the documentation of this file.
1#include "THILDataParser.h"
3
4#include <bitset>
5
6#include "TChannel.h"
7#include "Globals.h"
8
9#include "TScalerQueue.h"
10
11#include "TEpicsFrag.h"
12#include "TParsingDiagnostics.h"
13
14#include "Rtypes.h"
15
16#include "THILFragment.h"
17#include "TBadFragment.h"
18
24
28
29int THILDataParser::Process(std::shared_ptr<TRawEvent> rawEvent)
30{
31 /// Process this TRlmdEvent using the provided data parser.
32 /// Returns the total number of fragments read (good and bad).
33 // right now the parser only returns the total number of fragments read
34 // so we assume (for now) that all fragments are good fragments
35 int eventsProcessed = 0;
36 std::shared_ptr<TRlmdEvent> rlmdEvent = std::static_pointer_cast<TRlmdEvent>(rawEvent);
37 uint32_t size = rlmdEvent->GetDataSize();
38
39 try {
40 eventsProcessed += EagleEventToFragment(size, reinterpret_cast<uint16_t*>(rlmdEvent->GetData()));
41 for(int i = 0; i < eventsProcessed; ++i) rawEvent->IncrementGoodFrags();
42 } catch(THILDataParserException& e) {
43 eventsProcessed = -e.GetFailedWord();
44 if(!TGRSIOptions::Get()->SuppressErrors()) {
45 if(!TGRSIOptions::Get()->LogErrors()) {
46 std::cout<<std::endl<<e.what();
47 }
48 }
49 }
50
51 if(fItemsPopped != nullptr && fInputSize != nullptr) {
52 ++(*fItemsPopped);
53 --(*fInputSize);
54 }
55
56 return eventsProcessed;
57}
58
59int THILDataParser::EagleEventToFragment(uint32_t size, uint16_t* data)
60{
61 std::shared_ptr<THILFragment> eventFrag;
62 int nofEvents = 0;
63
64 // all data needs to be byte swapped!
65 // 0 - length of used data
66 uint16_t usedData = ByteSwap(data[0]);
67 if(usedData%2 == 1) {
69 }
70 // convert used data from bytes to 16bit words
71 usedData /= 2;
72 // 1 - always 0x0200 w/o byte swapping
73 if(data[1] != 0x0200) {
75 }
76 // 2+3 - buffer number
77 uint32_t bufferNumber = ByteSwap(data[2]);
78 bufferNumber = (bufferNumber << 16) | ByteSwap(data[3]);
79 uint16_t eventLength = 0;
80 uint16_t eventId = 0;
81 uint32_t acquisitionClk = 0;
82 uint32_t cpuClk = 0;
83 uint32_t eventNumber = 0;
84 uint64_t eventTime = 0;
85 uint16_t pattern = 0;
86 uint16_t usTime = 0;
87 std::bitset<16> bitPattern;
88 std::vector<uint8_t> geId;
89 std::vector<uint16_t> geTime;
90 std::vector<uint16_t> geEnergy;
91 std::vector<uint8_t> siId;
92 std::vector<uint16_t> siEnergy;
93 //std::ofstream debugFile("debug.txt", std::ios::app);
94 //debugFile<<std::hex;
95 for(size_t i = 4; i < usedData && i < size;) { // incrementation is done within the loop
96 //debugFile<<"Parsing buffer from 0x"<<i<<" to 0x"<<usedData<<std::endl;
97 // 4+x - length should not be zero
98 eventLength = ByteSwap(data[i++]);
99 if(eventLength == 0) {
101 }
102 if(eventLength%2 == 1) {
104 }
105 // 5+x - event id
106 eventId = ByteSwap(data[i++]);
107 if(eventId == 0x0001) {
108 acquisitionClk = ByteSwap(data[i++]);
109 acquisitionClk = (acquisitionClk << 16) | ByteSwap(data[i++]);
110 cpuClk = ByteSwap(data[i++]);
111 cpuClk = (cpuClk << 16) | ByteSwap(data[i++]);
112 // we advanced i 6 times so the event length should be 12 and we are done with this event
113 if(eventLength != 0x000c) {
115 }
116 //debugFile<<"acquisitionClk 0x"<<acquisitionClk<<", cpuClk 0x"<<cpuClk<<std::endl;
117 continue;
118 }
119 eventLength /= 2; // convert from bytes to 16bit words
120 // for all other IDs we only care about the high nibble
121 // we already read two 16bit words of the event
122 switch((eventId>>8)&0xff) {
123 case 0x11: // sync
124 //debugFile<<"found sync pattern, moving index from "<<i;
125 i += eventLength-2;
126 //debugFile<<" to "<<i<<std::endl;
127 break;
128 case 0x12: // scaler ??
129 //debugFile<<"found scaler pattern, moving index from "<<i;
130 i += eventLength-2;
131 //debugFile<<" to "<<i<<std::endl;
132 break;
133 case 0x70:
134 //debugFile<<"found 0x70 pattern, moving index from "<<i;
135 i += eventLength-2;
136 //debugFile<<" to "<<i<<std::endl;
137 break;
138 case 0x74:
139 //debugFile<<"found 0x74 pattern, moving index from "<<i;
140 i += eventLength-2;
141 //debugFile<<" to "<<i<<std::endl;
142 break;
143 case 0x75: // CEFE bit pattern
144 eventNumber = ByteSwap(data[i++]);
145 eventNumber = (eventNumber << 16) | ByteSwap(data[i++]);
146 eventTime = ByteSwap(data[i++]);
147 eventTime = (eventTime << 16) | ByteSwap(data[i++]);
148 eventTime = (eventTime << 16) | ByteSwap(data[i++]);
149 eventTime = (eventTime << 16) | ByteSwap(data[i++]);
150 // CEFE 0
151 // pattern and time in microseconds
152 pattern = ByteSwap(data[i++]);
153 if((pattern&0xdf00) != 0x5500) {
155 }
156 usTime = ByteSwap(data[i++]);
157 // pattern and hit pattern (plus loop for energies, ids, and times)
158 pattern = ByteSwap(data[i++]);
159 if((pattern&0xdf00) != 0x5500) {
161 }
162 //debugFile<<eventNumber<<": time 0x"<<eventTime<<" microseconds 0x"<<usTime<<" pattern 0x"<<pattern<<" at "<<i-1;
163 bitPattern = ByteSwap(data[i++]);
164 //debugFile<<" bit pattern 0x"<<bitPattern.to_ulong()<<" at "<<i-1<<std::endl;
165 if(bitPattern.any()) {
166 //debugFile<<"found Ge ";
167 for(int ch = 0; ch < 16; ++ch) {
168 if(bitPattern.test(ch)) {
169 //debugFile<<ch<<" ";
170 // for each bit that is set we should find one energy word and a combined ID and time word
171 // each preceded by a "pattern word"
172 pattern = ByteSwap(data[i++]);
173 if((pattern&0xdf00) != 0x5500) {
175 }
176 geEnergy.push_back(ByteSwap(data[i++]));
177 pattern = ByteSwap(data[i++]);
178 if((pattern&0xdf00) != 0x5500) {
180 }
181 geId.push_back((ByteSwap(data[i])>>12)&0xf);
182 geTime.push_back(ByteSwap(data[i++])&0xfff);
183 }
184 }
185 //debugFile<<std::endl;
186 }
187 // CEFE 1
188 pattern = ByteSwap(data[i++]);
189 if((pattern&0xdf00) != 0x5500) {
191 }
192 bitPattern = ByteSwap(data[i++]);
193 if(bitPattern.any()) {
194 //debugFile<<"found Si1 ";
195 for(int ch = 0; ch < 16; ++ch) {
196 if(bitPattern.test(ch)) {
197 //debugFile<<ch<<" ";
198 // for each bit that is set we should find one combined ID and energy word
199 pattern = ByteSwap(data[i++]);
200 if((pattern&0xdf00) != 0x5500) {
202 }
203 siId.push_back((ByteSwap(data[i])>>12)&0xf);
204 siEnergy.push_back(ByteSwap(data[i++])&0xfff);
205 }
206 }
207 //debugFile<<std::endl;
208 }
209 // CEFE 2
210 pattern = ByteSwap(data[i++]);
211 if((pattern&0xdf00) != 0x5500) {
213 }
214 bitPattern = ByteSwap(data[i++]);
215 if(bitPattern.any()) {
216 //debugFile<<"found Si2 ";
217 for(int ch = 0; ch < 16; ++ch) {
218 if(bitPattern.test(ch)) {
219 //debugFile<<ch<<" ";
220 // for each bit that is set we should find one combined ID and energy word
221 pattern = ByteSwap(data[i++]);
222 if((pattern&0xdf00) != 0x5500) {
224 }
225 siId.push_back(((ByteSwap(data[i])>>12)&0xf)+16);
226 siEnergy.push_back(ByteSwap(data[i++])&0xfff);
227 }
228 }
229 //debugFile<<std::endl;
230 }
231 // CEFE 3
232 pattern = ByteSwap(data[i++]);
233 if((pattern&0xdf00) != 0x5500) {
235 }
236 bitPattern = ByteSwap(data[i++]);
237 if(bitPattern.any()) {
238 //debugFile<<"found Si3 ";
239 for(int ch = 0; ch < 16; ++ch) {
240 if(bitPattern.test(ch)) {
241 //debugFile<<ch<<" ";
242 // for each bit that is set we should find one combined ID and energy word
243 pattern = ByteSwap(data[i++]);
244 if((pattern&0xdf00) != 0x5500) {
246 }
247 siId.push_back(((ByteSwap(data[i])>>12)&0xf)+32);
248 siEnergy.push_back(ByteSwap(data[i++])&0xfff);
249 }
250 }
251 //debugFile<<std::endl;
252 }
253 //debugFile<<geId.size()<<" Ge and "<<siId.size()<<" Si"<<std::endl;
254 //debugFile<<"# Ge# GeEn GeTime Si# SiEn"<<std::endl;
255 //for(size_t h = 0; h < geId.size(); ++h) {
256 // if(h < siId.size()) {
257 // debugFile<<std::setw(2)<<h<<" "<<std::setw(3)<<(int)geId.at(h)<<" "<<std::setw(4)<<geEnergy.at(h)<<" "<<std::setw(6)<<geTime.at(h)<<" "<<std::setw(3)<<(int)siId.at(h)<<" "<<std::setw(4)<<siEnergy.at(h)<<std::endl;
258 // } else {
259 // debugFile<<std::setw(2)<<h<<" "<<std::setw(3)<<(int)geId.at(h)<<" "<<std::setw(4)<<geEnergy.at(h)<<" "<<std::setw(6)<<geTime.at(h)<<std::endl;
260 // }
261 //}
262 //debugFile<<"============================"<<std::endl;
263
264 eventFrag = std::make_shared<THILFragment>();
265 // default address as this event contains multiple hits with different addresses
266 // but this makes the unpacking loop create the right detector
267 eventFrag->SetAddress(0x100);
268 eventFrag->GermaniumId(geId);
269 eventFrag->GermaniumEnergy(geEnergy);
270 eventFrag->GermaniumTime(geTime);
271 eventFrag->SiliconId(siId);
272 eventFrag->SiliconEnergy(siEnergy);
273 //eventFrag->AcquisitionClock(acquisitionClk);
274 //eventFrag->CpuClock(cpuClk);
275 eventFrag->EventNumber(eventNumber);
276 eventFrag->EventTime(eventTime);
277 eventFrag->MicrosecondTime(usTime);
278 if(eventFrag->Good()) {
279 Push(fGoodOutputQueues, eventFrag);
280 ++nofEvents;
281 } else {
282 Push(*fBadOutputQueue, std::make_shared<TBadFragment>(*eventFrag));
283 }
284 if(fRecordDiag) {
285 TParsingDiagnostics::Get()->GoodFragment(eventFrag->GetDetectorType());
286 }
287
288 geId.clear();
289 geEnergy.clear();
290 geTime.clear();
291 siId.clear();
292 siEnergy.clear();
293 break;
294 case 0xaa: // start
295 //debugFile<<"found start pattern, moving index from "<<i;
296 i += eventLength-2;
297 //debugFile<<" to "<<i<<std::endl;
298 break;
299 default:
301 break;
302 };
303 }
304 //debugFile.close();
305
306 return nofEvents;
307}
308
bool fRecordDiag
The flag to turn on diagnostics recording.
void Push(ThreadsafeQueue< std::shared_ptr< const TBadFragment > > &queue, const std::shared_ptr< TBadFragment > &frag)
std::shared_ptr< ThreadsafeQueue< std::shared_ptr< const TBadFragment > > > fBadOutputQueue
std::atomic_long * fInputSize
std::vector< std::shared_ptr< ThreadsafeQueue< std::shared_ptr< const TFragment > > > > fGoodOutputQueues
std::atomic_size_t * fItemsPopped
static TGRSIOptions * Get(int argc=0, char **argv=nullptr)
Do not use!
const char * what() const noexcept override
EDataParserState fState
uint16_t ByteSwap(const uint16_t &val)
int EagleEventToFragment(uint32_t size, uint16_t *data)
int Process(std::shared_ptr< TRawEvent >) override
void GoodFragment(const std::shared_ptr< const TFragment > &)
static TParsingDiagnostics * Get(bool verbose=false)
Definition TSingleton.h:33