LDMX Software
FiberTrackerRawDecoder.cxx
1
2#include <bitset>
3#include <iomanip>
4#include <optional>
5
7#include "Packing/Utility/Mask.h"
8#include "Packing/Utility/Reader.h"
9
10// un comment for FiberTrackerRawDecoder-specific debug printouts to std::cout
11//#define DEBUG
12
13namespace packing {
14
18double to_double_ft(uint64_t i) {
19 static const unsigned int bits = 32;
20 static const unsigned int expbits = 8;
21 long double result;
22 long long shift;
23 unsigned bias;
24 unsigned significandbits = bits - expbits - 1; // -1 for sign bit
25
26 if (i == 0) return 0.0;
27
28 // pull the significand
29 result = (i & ((1LL << significandbits) - 1)); // mask
30 result /= (1LL << significandbits); // convert back to float
31 result += 1.0f; // add the one back on
32
33 // deal with the exponent
34 bias = (1 << (expbits - 1)) - 1;
35 shift = ((i >> significandbits) & ((1LL << expbits) - 1)) - bias;
36 while (shift > 0) {
37 result *= 2.0;
38 shift--;
39 }
40 while (shift < 0) {
41 result /= 2.0;
42 shift++;
43 }
44
45 // sign it
46 result *= (i >> (bits - 1)) & 1 ? -1.0 : 1.0;
47
48 return result;
49}
50
55 uint32_t field_header_;
56 std::vector<uint32_t> field_value_;
57
58 public:
64 uint32_t len;
65 r >> len >> field_header_;
66 r.read(field_value_, len - 1);
67 if (i_field != field_header_) {
68 EXCEPTION_RAISE("BadForm", "Field " + std::to_string(i_field) +
69 " has a mismatched header " +
70 std::to_string(field_header_));
71 }
72 }
73
77 int to_int(const std::size_t i = 0) const { return field_value_.at(i); }
78
82 std::string to_string() const {
83 std::string str;
84 str.resize(field_value_.size());
85 for (int i{0}; i < str.size(); i++) {
86 str[i] = (char)field_value_[i];
87 }
88 return str;
89 }
90
96 long int to_long(const std::size_t i = 0) const {
97 return ((uint64_t)field_value_.at(i + 1) << 32) |
98 (uint64_t)field_value_.at(i);
99 }
100
104 double to_double(const std::size_t i = 0) const {
105 return to_double_ft(this->to_long(i));
106 }
107
111 const std::vector<uint32_t>& value() const { return field_value_; }
112};
113
136 int trigger_timestamp_lsb, trigger_timestamp_msb, event_timestamp_lsb,
137 event_timestamp_msb;
138 std::vector<uint32_t> channel_hits;
139
140 FiberTrackerEvent() = default;
141
142 FiberTrackerEvent(const std::vector<uint32_t>& spill_data,
143 std::size_t i_word) {
144 trigger_timestamp_lsb = spill_data.at(i_word);
145 trigger_timestamp_msb = spill_data.at(i_word + 1);
146 event_timestamp_lsb = spill_data.at(i_word + 2);
147 event_timestamp_msb = spill_data.at(i_word + 3);
148 channel_hits.clear();
149 channel_hits.reserve(6);
150 for (std::size_t i{i_word + 4}; i < i_word + 10 and i < spill_data.size();
151 i++)
152 channel_hits.push_back(spill_data.at(i));
153 }
154};
155
160 int acqMode;
161 long int acqStamp;
162 int acqType;
163 int acqTypeAllowed;
164 std::string coincidenceInUse;
165 int counts;
166 long int countsRecords;
167 long int countsRecordsWithZeroEvents;
168 long int countsTrigs;
169 std::string cycleName;
170 long int cycleStamp;
171 std::string equipmentName;
172 int eventSelectionAcq;
176 std::vector<FiberTrackerEvent> eventsData;
178 int i_event{0};
179
180 double meanSNew;
181 std::string message;
182 std::vector<double> profile;
183 std::vector<double> profileStandAlone;
184 std::string timeFirstEvent;
185 std::string timeFirstTrigger;
186 std::string timeLastEvent;
187 std::string timeLastTrigger;
188 int trigger;
189 int triggerOffsetAcq;
190 int triggerSelectionAcq;
191
192 bool next(FiberTrackerEvent& e) {
193 i_event++;
194 if (i_event < eventsData.size()) {
195 e = eventsData.at(i_event);
196 return true;
197 }
198 return false;
199 }
200
205 int i_field{0};
206 acqMode = FiberTrackerField(r, ++i_field).to_int();
207#ifdef DEBUG
208 std::cout << i_field << " "
209 << "acqMode = " << acqMode << std::endl;
210#endif
211 acqStamp = FiberTrackerField(r, ++i_field).to_long();
212#ifdef DEBUG
213 std::cout << i_field << " "
214 << "acqStamp = " << acqStamp << std::endl;
215#endif
216 acqType = FiberTrackerField(r, ++i_field).to_int();
217#ifdef DEBUG
218 std::cout << i_field << " "
219 << "acqType = " << acqType << std::endl;
220#endif
221 acqTypeAllowed = FiberTrackerField(r, ++i_field).to_int();
222#ifdef DEBUG
223 std::cout << i_field << " "
224 << "acqTypeAllowed = " << acqTypeAllowed << std::endl;
225#endif
226 coincidenceInUse = FiberTrackerField(r, ++i_field).to_string();
227#ifdef DEBUG
228 std::cout << i_field << " "
229 << "coincidenceInUse = " << coincidenceInUse << std::endl;
230#endif
231 counts = FiberTrackerField(r, ++i_field).to_int();
232#ifdef DEBUG
233 std::cout << i_field << " "
234 << "counts = " << counts << std::endl;
235#endif
236 countsRecords = FiberTrackerField(r, ++i_field).to_long();
237#ifdef DEBUG
238 std::cout << i_field << " "
239 << "countsRecords = " << countsRecords << std::endl;
240#endif
241 countsRecordsWithZeroEvents = FiberTrackerField(r, ++i_field).to_long();
242#ifdef DEBUG
243 std::cout << i_field << " "
244 << "countsRecordsWithZeroEvents = " << countsRecordsWithZeroEvents
245 << std::endl;
246#endif
247 countsTrigs = FiberTrackerField(r, ++i_field).to_long();
248#ifdef DEBUG
249 std::cout << i_field << " "
250 << "countsTrigs = " << countsTrigs << std::endl;
251#endif
252 cycleName = FiberTrackerField(r, ++i_field).to_string();
253#ifdef DEBUG
254 std::cout << i_field << " "
255 << "cycleName = " << cycleName << std::endl;
256#endif
257 cycleStamp = FiberTrackerField(r, ++i_field).to_long();
258#ifdef DEBUG
259 std::cout << i_field << " "
260 << "cycleStamp = " << cycleStamp << std::endl;
261#endif
262 equipmentName = FiberTrackerField(r, ++i_field).to_string();
263#ifdef DEBUG
264 std::cout << i_field << " "
265 << "equipmentName = " << equipmentName << std::endl;
266#endif
267 eventSelectionAcq = FiberTrackerField(r, ++i_field).to_int();
268#ifdef DEBUG
269 std::cout << i_field << " "
270 << "eventSelectionAcq = " << eventSelectionAcq << std::endl;
271#endif
272 FiberTrackerField events_data_field(r, ++i_field);
273 i_event = -1;
274 eventsData.clear();
275 eventsData.reserve(events_data_field.value().size() / 10);
276 for (std::size_t i_word{0}; i_word < events_data_field.value().size();
277 i_word += 10) {
278 eventsData.emplace_back(events_data_field.value(), i_word);
279 }
280#ifdef DEBUG
281 std::cout << i_field << " "
282 << "eventsData (size = " << eventsData.size() << ")" << std::endl;
283#endif
284 meanSNew = FiberTrackerField(r, ++i_field).to_double();
285#ifdef DEBUG
286 std::cout << i_field << " "
287 << "meanSNew = " << meanSNew << std::endl;
288#endif
289 message = FiberTrackerField(r, ++i_field).to_string();
290#ifdef DEBUG
291 std::cout << i_field << " "
292 << "message = " << message << std::endl;
293#endif
294 FiberTrackerField profile_field(r, ++i_field);
295 profile.clear();
296 profile.reserve(profile_field.value().size() / 2);
297 for (std::size_t i_word{0}; i_word < profile_field.value().size();
298 i_word += 2) {
299 profile.push_back(profile_field.to_double(i_word));
300 }
301#ifdef DEBUG
302 std::cout << i_field << " "
303 << "profile size " << profile.size() << std::endl;
304#endif
305 // fields 18 and 19 are skipped
306 i_field += 2;
307 FiberTrackerField profileStandAlone_field(r, ++i_field);
308 profileStandAlone.clear();
309 profileStandAlone.reserve(profileStandAlone_field.value().size() / 2);
310 for (std::size_t i_word{0}; i_word < profileStandAlone_field.value().size();
311 i_word += 2) {
312 profileStandAlone.push_back(profileStandAlone_field.to_double(i_word));
313 }
314#ifdef DEBUG
315 std::cout << i_field << " "
316 << "profileStandAlone size " << profileStandAlone.size()
317 << std::endl;
318#endif
319 timeFirstEvent = FiberTrackerField(r, ++i_field).to_string();
320#ifdef DEBUG
321 std::cout << i_field << " "
322 << "timeFirstEvent = " << timeFirstEvent << std::endl;
323#endif
324 timeFirstTrigger = FiberTrackerField(r, ++i_field).to_string();
325#ifdef DEBUG
326 std::cout << i_field << " "
327 << "timeFirstTrigger = " << timeFirstTrigger << std::endl;
328#endif
329 timeLastEvent = FiberTrackerField(r, ++i_field).to_string();
330#ifdef DEBUG
331 std::cout << i_field << " "
332 << "timeLastEvent = " << timeLastEvent << std::endl;
333#endif
334 timeLastTrigger = FiberTrackerField(r, ++i_field).to_string();
335#ifdef DEBUG
336 std::cout << i_field << " "
337 << "timeLastTrigger = " << timeLastTrigger << std::endl;
338#endif
339 trigger = FiberTrackerField(r, ++i_field).to_int();
340#ifdef DEBUG
341 std::cout << i_field << " "
342 << "trigger = " << trigger << std::endl;
343#endif
344 triggerOffsetAcq = FiberTrackerField(r, ++i_field).to_int();
345#ifdef DEBUG
346 std::cout << i_field << " "
347 << "triggerOffsetAcq = " << triggerOffsetAcq << std::endl;
348#endif
349 triggerSelectionAcq = FiberTrackerField(r, ++i_field).to_int();
350#ifdef DEBUG
351 std::cout << i_field << " "
352 << "triggerSelectionAcq = " << triggerSelectionAcq << std::endl;
353#endif
354 return r;
355 }
356};
357
358std::ostream& operator<<(std::ostream& os, const FiberTrackerBinaryPacket& p) {
359 return (os << "FiberTracker Packet {" << p.acqStamp << "}");
360}
361
366 public:
367 FiberTrackerRawDecoder(const std::string& name, framework::Process& process)
368 : framework::Producer(name, process) {}
369 virtual ~FiberTrackerRawDecoder() = default;
370 virtual void configure(framework::config::Parameters&) final override;
371 virtual void onProcessStart() final override;
372 virtual void produce(framework::Event& event) final override;
373
374 private:
376 std::string input_file_;
378 std::string output_name_;
381
382 private:
390 TTree *tree_, *spill_tree_;
391};
392
394 input_file_ = ps.getParameter<std::string>("input_file");
395 output_name_ = ps.getParameter<std::string>("output_name");
396 ntuplize_ = ps.getParameter<bool>("ntuplize");
397
399}
400
402 if (ntuplize_) {
404 tree_ = new TTree("raw", "Flattened and decoded raw FiberTracker data");
405 tree_->Branch("TriggerTSLSB", &ft_event_.trigger_timestamp_lsb);
406 tree_->Branch("TriggerTSMSB", &ft_event_.trigger_timestamp_msb);
407 tree_->Branch("EventTSLSB", &ft_event_.event_timestamp_lsb);
408 tree_->Branch("EventTSMSB", &ft_event_.event_timestamp_msb);
409 tree_->Branch("ChannelHits", &ft_event_.channel_hits);
410
411 spill_tree_ = new TTree("spill", "Spill Meta-Data from FiberTrackerDAQ");
412 spill_tree_->Branch("acqMode", &spill_packet_.acqMode);
413 spill_tree_->Branch("acqStamp", &spill_packet_.acqStamp);
414 spill_tree_->Branch("acqType", &spill_packet_.acqType);
415 spill_tree_->Branch("acqTypeAllowed", &spill_packet_.acqTypeAllowed);
416 spill_tree_->Branch("counts", &spill_packet_.counts);
417 spill_tree_->Branch("countsRecords", &spill_packet_.countsRecords);
418 spill_tree_->Branch("countsRecordsWithZeroEvents",
419 &spill_packet_.countsRecordsWithZeroEvents);
420 spill_tree_->Branch("countsTrigs", &spill_packet_.countsTrigs);
421 spill_tree_->Branch("cycleStamp", &spill_packet_.cycleStamp);
422 spill_tree_->Branch("eventSelectionAcq", &spill_packet_.eventSelectionAcq);
423 spill_tree_->Branch("meanSNew", &spill_packet_.meanSNew);
424 spill_tree_->Branch("profile", &spill_packet_.profile);
425 spill_tree_->Branch("profileStandAlone", &spill_packet_.profileStandAlone);
426 spill_tree_->Branch("trigger", &spill_packet_.trigger);
427 spill_tree_->Branch("triggerOffsetAcq", &spill_packet_.triggerOffsetAcq);
428 spill_tree_->Branch("triggerSelectionAcq",
429 &spill_packet_.triggerSelectionAcq);
430 }
431}
432
434 // only add and fill when file able to readout packet
435 if (not spill_packet_.next(ft_event_)) {
436 // no more events in this spill
438 spill_tree_->Fill();
439 // next spill loaded, pop its first event
441 } else {
442#ifdef DEBUG
443 std::cout << "no more events" << std::endl;
444#endif
445 return;
446 }
447 }
448 tree_->Fill();
449
450 event.add(output_name_ + "TriggerTSLSB", ft_event_.trigger_timestamp_lsb);
451 event.add(output_name_ + "TriggerTSMSB", ft_event_.trigger_timestamp_msb);
452 event.add(output_name_ + "EventTSLSB", ft_event_.event_timestamp_lsb);
453 event.add(output_name_ + "EventTSMSB", ft_event_.event_timestamp_msb);
454 event.add(output_name_ + "Hits", ft_event_.channel_hits);
455 return;
456} // produce
457
458} // namespace packing
459
460DECLARE_PRODUCER_NS(packing, FiberTrackerRawDecoder);
Base classes for all user event processing components to extend.
#define DECLARE_PRODUCER_NS(NS, CLASS)
Macro which allows the framework to construct a producer given its name during configuration.
TDirectory * getHistoDirectory()
Access/create a directory in the histogram file for this event processor to create histograms and ana...
Implements an event buffer system for storing event data.
Definition Event.h:41
Class which represents the process under execution.
Definition Process.h:36
Base class for a module which produces a data product.
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:27
T getParameter(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:89
Each "field" of data in a FiberTracker packet.
double to_double(const std::size_t i=0) const
convert two ints into a double
const std::vector< uint32_t > & value() const
Get the field value.
int to_int(const std::size_t i=0) const
conversion to a single int
std::string to_string() const
conversion from series of ints to string specific to FiberTrackerDAQ
long int to_long(const std::size_t i=0) const
long split across two ints
FiberTrackerField(utility::Reader &r, int i_field)
r - reader i_field - field we are supposed to be reading from
std::string output_name_
output object to put onto event bus
virtual void produce(framework::Event &event) final override
Process the event and put new data products into it.
virtual void configure(framework::config::Parameters &) final override
Callback for the EventProcessor to configure itself from the given set of parameters.
FiberTrackerEvent ft_event_
Current Event.
FiberTrackerBinaryPacket spill_packet_
packet being used for decoding
virtual void onProcessStart() final override
Callback for the EventProcessor to take any necessary action when the processing of events starts,...
packing::utility::Reader file_reader_
the file reader (if we are doing that)
Reading a raw data file.
Definition Reader.h:19
void open(const std::string &file_name)
Open a file with this reader.
Definition Reader.h:35
Reader & read(WordType *w, std::size_t count)
Read the next 'count' words into the input handle.
Definition Reader.h:113
Each one of these packets represents an entire spill of data.
std::vector< FiberTrackerEvent > eventsData
This is the actual event data in which we are interested.
utility::Reader & read(utility::Reader &r)
27 fields in order, all are present
int i_event
index of event we are on (for next)
A spill of events from a FiberTracker station.