LDMX Software
FiberTrackerRawDecoder.cxx
1
2
4#include "Packing/Utility/Reader.h"
5
6// un comment for FiberTrackerRawDecoder-specific debug printouts to std::cout
7// #define DEBUG
8
9namespace packing {
10
14double toDoubleFt(uint64_t i) {
15 static const unsigned int bits = 32;
16 static const unsigned int expbits = 8;
17 long double result;
18 long long shift;
19 unsigned bias;
20 unsigned significandbits = bits - expbits - 1; // -1 for sign bit
21
22 if (i == 0) return 0.0;
23
24 // pull the significand
25 result = (i & ((1LL << significandbits) - 1)); // mask
26 result /= (1LL << significandbits); // convert back to float
27 result += 1.0f; // add the one back on
28
29 // deal with the exponent
30 bias = (1 << (expbits - 1)) - 1;
31 shift = ((i >> significandbits) & ((1LL << expbits) - 1)) - bias;
32 while (shift > 0) {
33 result *= 2.0;
34 shift--;
35 }
36 while (shift < 0) {
37 result /= 2.0;
38 shift++;
39 }
40
41 // sign it
42 result *= (i >> (bits - 1)) & 1 ? -1.0 : 1.0;
43
44 return result;
45}
46
51 uint32_t field_header_;
52 std::vector<uint32_t> field_value_;
53
54 public:
60 uint32_t len;
61 r >> len >> field_header_;
62 r.read(field_value_, len - 1);
63 if (i_field != field_header_) {
64 EXCEPTION_RAISE("BadForm", "Field " + std::to_string(i_field) +
65 " has a mismatched header " +
66 std::to_string(field_header_));
67 }
68 }
69
73 int toInt(const std::size_t i = 0) const { return field_value_.at(i); }
74
78 std::string toString() const {
79 std::string str;
80 str.resize(field_value_.size());
81 for (int i{0}; i < str.size(); i++) {
82 str[i] = (char)field_value_[i];
83 }
84 return str;
85 }
86
92 long int toLong(const std::size_t i = 0) const {
93 return ((uint64_t)field_value_.at(i + 1) << 32) |
94 (uint64_t)field_value_.at(i);
95 }
96
100 double toDouble(const std::size_t i = 0) const {
101 return toDoubleFt(this->toLong(i));
102 }
103
107 const std::vector<uint32_t>& value() const { return field_value_; }
108};
109
132 int trigger_timestamp_lsb_, trigger_timestamp_msb_, event_timestamp_lsb_,
133 event_timestamp_msb_;
134 std::vector<uint32_t> channel_hits_;
135
136 FiberTrackerEvent() = default;
137
138 FiberTrackerEvent(const std::vector<uint32_t>& spill_data,
139 std::size_t i_word) {
140 trigger_timestamp_lsb_ = spill_data.at(i_word);
141 trigger_timestamp_msb_ = spill_data.at(i_word + 1);
142 event_timestamp_lsb_ = spill_data.at(i_word + 2);
143 event_timestamp_msb_ = spill_data.at(i_word + 3);
144 channel_hits_.clear();
145 channel_hits_.reserve(6);
146 for (std::size_t i{i_word + 4}; i < i_word + 10 and i < spill_data.size();
147 i++)
148 channel_hits_.push_back(spill_data.at(i));
149 }
150};
151
156 int acq_mode_;
157 long int acq_stamp_;
158 int acq_type_;
159 int acq_type_allowed_;
160 std::string coincidence_in_use_;
161 int counts_;
162 long int counts_records_;
163 long int counts_records_with_zero_events_;
164 long int counts_trigs_;
165 std::string cycle_name_;
166 long int cycle_stamp_;
167 std::string equipment_name_;
168 int event_selection_acq_;
172 std::vector<FiberTrackerEvent> events_data_;
174 int i_event_{0};
175
176 double mean_s_new_;
177 std::string message_;
178 std::vector<double> profile_;
179 std::vector<double> profile_stand_alone_;
180 std::string time_first_event_;
181 std::string time_first_trigger_;
182 std::string time_last_event_;
183 std::string time_last_trigger_;
184 int trigger_;
185 int trigger_offset_acq_;
186 int trigger_selection_acq_;
187
188 bool next(FiberTrackerEvent& e) {
189 i_event_++;
190 if (i_event_ < events_data_.size()) {
191 e = events_data_.at(i_event_);
192 return true;
193 }
194 return false;
195 }
196
201 int i_field{0};
202 acq_mode_ = FiberTrackerField(r, ++i_field).toInt();
203#ifdef DEBUG
204 std::cout << i_field << " " << "acqMode = " << acqMode << std::endl;
205#endif
206 acq_stamp_ = FiberTrackerField(r, ++i_field).toLong();
207#ifdef DEBUG
208 std::cout << i_field << " " << "acqStamp = " << acqStamp << std::endl;
209#endif
210 acq_type_ = FiberTrackerField(r, ++i_field).toInt();
211#ifdef DEBUG
212 std::cout << i_field << " " << "acqType = " << acqType << std::endl;
213#endif
214 acq_type_allowed_ = FiberTrackerField(r, ++i_field).toInt();
215#ifdef DEBUG
216 std::cout << i_field << " " << "acqTypeAllowed = " << acqTypeAllowed
217 << std::endl;
218#endif
219 coincidence_in_use_ = FiberTrackerField(r, ++i_field).toString();
220#ifdef DEBUG
221 std::cout << i_field << " " << "coincidenceInUse = " << coincidenceInUse
222 << std::endl;
223#endif
224 counts_ = FiberTrackerField(r, ++i_field).toInt();
225#ifdef DEBUG
226 std::cout << i_field << " " << "counts = " << counts << std::endl;
227#endif
228 counts_records_ = FiberTrackerField(r, ++i_field).toLong();
229#ifdef DEBUG
230 std::cout << i_field << " " << "countsRecords = " << countsRecords
231 << std::endl;
232#endif
233 counts_records_with_zero_events_ = FiberTrackerField(r, ++i_field).toLong();
234#ifdef DEBUG
235 std::cout << i_field << " "
236 << "countsRecordsWithZeroEvents = " << countsRecordsWithZeroEvents
237 << std::endl;
238#endif
239 counts_trigs_ = FiberTrackerField(r, ++i_field).toLong();
240#ifdef DEBUG
241 std::cout << i_field << " " << "countsTrigs = " << countsTrigs << std::endl;
242#endif
243 cycle_name_ = FiberTrackerField(r, ++i_field).toString();
244#ifdef DEBUG
245 std::cout << i_field << " " << "cycleName = " << cycleName << std::endl;
246#endif
247 cycle_stamp_ = FiberTrackerField(r, ++i_field).toLong();
248#ifdef DEBUG
249 std::cout << i_field << " " << "cycleStamp = " << cycleStamp << std::endl;
250#endif
251 equipment_name_ = FiberTrackerField(r, ++i_field).toString();
252#ifdef DEBUG
253 std::cout << i_field << " " << "equipmentName = " << equipmentName
254 << std::endl;
255#endif
256 event_selection_acq_ = FiberTrackerField(r, ++i_field).toInt();
257#ifdef DEBUG
258 std::cout << i_field << " " << "eventSelectionAcq = " << eventSelectionAcq
259 << std::endl;
260#endif
261 FiberTrackerField events_data_field(r, ++i_field);
262 i_event_ = -1;
263 events_data_.clear();
264 events_data_.reserve(events_data_field.value().size() / 10);
265 for (std::size_t i_word{0}; i_word < events_data_field.value().size();
266 i_word += 10) {
267 events_data_.emplace_back(events_data_field.value(), i_word);
268 }
269#ifdef DEBUG
270 std::cout << i_field << " " << "eventsData (size = " << eventsData.size()
271 << ")" << std::endl;
272#endif
273 mean_s_new_ = FiberTrackerField(r, ++i_field).toDouble();
274#ifdef DEBUG
275 std::cout << i_field << " " << "meanSNew = " << meanSNew << std::endl;
276#endif
277 message_ = FiberTrackerField(r, ++i_field).toString();
278#ifdef DEBUG
279 std::cout << i_field << " " << "message = " << message << std::endl;
280#endif
281 FiberTrackerField profile_field(r, ++i_field);
282 profile_.clear();
283 profile_.reserve(profile_field.value().size() / 2);
284 for (std::size_t i_word{0}; i_word < profile_field.value().size();
285 i_word += 2) {
286 profile_.push_back(profile_field.toDouble(i_word));
287 }
288#ifdef DEBUG
289 std::cout << i_field << " " << "profile size " << profile.size()
290 << std::endl;
291#endif
292 // fields 18 and 19 are skipped
293 i_field += 2;
294 FiberTrackerField profile_stand_alone_field(r, ++i_field);
295 profile_stand_alone_.clear();
296 profile_stand_alone_.reserve(profile_stand_alone_field.value().size() / 2);
297 for (std::size_t i_word{0};
298 i_word < profile_stand_alone_field.value().size(); i_word += 2) {
299 profile_stand_alone_.push_back(
300 profile_stand_alone_field.toDouble(i_word));
301 }
302#ifdef DEBUG
303 std::cout << i_field << " " << "profileStandAlone size "
304 << profileStandAlone.size() << std::endl;
305#endif
306 time_first_event_ = FiberTrackerField(r, ++i_field).toString();
307#ifdef DEBUG
308 std::cout << i_field << " " << "timeFirstEvent = " << timeFirstEvent
309 << std::endl;
310#endif
311 time_first_trigger_ = FiberTrackerField(r, ++i_field).toString();
312#ifdef DEBUG
313 std::cout << i_field << " " << "timeFirstTrigger = " << timeFirstTrigger
314 << std::endl;
315#endif
316 time_last_event_ = FiberTrackerField(r, ++i_field).toString();
317#ifdef DEBUG
318 std::cout << i_field << " " << "timeLastEvent = " << timeLastEvent
319 << std::endl;
320#endif
321 time_last_trigger_ = FiberTrackerField(r, ++i_field).toString();
322#ifdef DEBUG
323 std::cout << i_field << " " << "timeLastTrigger = " << timeLastTrigger
324 << std::endl;
325#endif
326 trigger_ = FiberTrackerField(r, ++i_field).toInt();
327#ifdef DEBUG
328 std::cout << i_field << " " << "trigger = " << trigger << std::endl;
329#endif
330 trigger_offset_acq_ = FiberTrackerField(r, ++i_field).toInt();
331#ifdef DEBUG
332 std::cout << i_field << " " << "triggerOffsetAcq = " << triggerOffsetAcq
333 << std::endl;
334#endif
335 trigger_selection_acq_ = FiberTrackerField(r, ++i_field).toInt();
336#ifdef DEBUG
337 std::cout << i_field << " "
338 << "triggerSelectionAcq = " << triggerSelectionAcq << std::endl;
339#endif
340 return r;
341 }
342};
343
344std::ostream& operator<<(std::ostream& os, const FiberTrackerBinaryPacket& p) {
345 return (os << "FiberTracker Packet {" << p.acq_stamp_ << "}");
346}
347
352 public:
353 FiberTrackerRawDecoder(const std::string& name, framework::Process& process)
354 : framework::Producer(name, process) {}
355 virtual ~FiberTrackerRawDecoder() = default;
356 virtual void configure(framework::config::Parameters&) final override;
357 virtual void onProcessStart() final override;
358 virtual void produce(framework::Event& event) final override;
359
360 private:
362 std::string input_file_;
364 std::string output_name_;
367
368 private:
376 TTree *tree_, *spill_tree_;
377};
378
380 input_file_ = ps.get<std::string>("input_file");
381 output_name_ = ps.get<std::string>("output_name");
382 ntuplize_ = ps.get<bool>("ntuplize");
383
385}
386
388 if (ntuplize_) {
390 tree_ = new TTree("raw", "Flattened and decoded raw FiberTracker data");
391 tree_->Branch("TriggerTSLSB", &ft_event_.trigger_timestamp_lsb_);
392 tree_->Branch("TriggerTSMSB", &ft_event_.trigger_timestamp_msb_);
393 tree_->Branch("EventTSLSB", &ft_event_.event_timestamp_lsb_);
394 tree_->Branch("EventTSMSB", &ft_event_.event_timestamp_msb_);
395 tree_->Branch("ChannelHits", &ft_event_.channel_hits_);
396
397 spill_tree_ = new TTree("spill", "Spill Meta-Data from FiberTrackerDAQ");
398 spill_tree_->Branch("acqMode", &spill_packet_.acq_mode_);
399 spill_tree_->Branch("acqStamp", &spill_packet_.acq_stamp_);
400 spill_tree_->Branch("acqType", &spill_packet_.acq_type_);
401 spill_tree_->Branch("acqTypeAllowed", &spill_packet_.acq_type_allowed_);
402 spill_tree_->Branch("counts", &spill_packet_.counts_);
403 spill_tree_->Branch("countsRecords", &spill_packet_.counts_records_);
404 spill_tree_->Branch("countsRecordsWithZeroEvents",
405 &spill_packet_.counts_records_with_zero_events_);
406 spill_tree_->Branch("countsTrigs", &spill_packet_.counts_trigs_);
407 spill_tree_->Branch("cycleStamp", &spill_packet_.cycle_stamp_);
408 spill_tree_->Branch("eventSelectionAcq",
409 &spill_packet_.event_selection_acq_);
410 spill_tree_->Branch("meanSNew", &spill_packet_.mean_s_new_);
411 spill_tree_->Branch("profile", &spill_packet_.profile_);
412 spill_tree_->Branch("profileStandAlone",
413 &spill_packet_.profile_stand_alone_);
414 spill_tree_->Branch("trigger", &spill_packet_.trigger_);
415 spill_tree_->Branch("triggerOffsetAcq", &spill_packet_.trigger_offset_acq_);
416 spill_tree_->Branch("triggerSelectionAcq",
417 &spill_packet_.trigger_selection_acq_);
418 }
419}
420
422 // only add and fill when file able to readout packet
423 if (not spill_packet_.next(ft_event_)) {
424 // no more events in this spill
426 spill_tree_->Fill();
427 // next spill loaded, pop its first event
429 } else {
430#ifdef DEBUG
431 std::cout << "no more events" << std::endl;
432#endif
433 return;
434 }
435 }
436 tree_->Fill();
437
438 event.add(output_name_ + "TriggerTSLSB", ft_event_.trigger_timestamp_lsb_);
439 event.add(output_name_ + "TriggerTSMSB", ft_event_.trigger_timestamp_msb_);
440 event.add(output_name_ + "EventTSLSB", ft_event_.event_timestamp_lsb_);
441 event.add(output_name_ + "EventTSMSB", ft_event_.event_timestamp_msb_);
442 event.add(output_name_ + "Hits", ft_event_.channel_hits_);
443 return;
444} // produce
445
446} // namespace packing
447
Base classes for all user event processing components to extend.
#define DECLARE_PRODUCER(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:40
Class which represents the process under execution.
Definition Process.h:34
Base class for a module which produces a data product.
virtual void process(Event &event) final
Processing an event for a Producer is calling produce.
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:26
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:75
Each "field" of data in a FiberTracker packet.
const std::vector< uint32_t > & value() const
Get the field value.
long int toLong(const std::size_t i=0) const
long split across two ints
int toInt(const std::size_t i=0) const
conversion to a single int
double toDouble(const std::size_t i=0) const
convert two ints into a double
std::string toString() const
conversion from series of ints to string specific to FiberTrackerDAQ
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:20
void open(const std::string &file_name)
Open a file with this reader.
Definition Reader.h:36
Reader & read(WordType *w, std::size_t count)
Read the next 'count' words into the input handle.
Definition Reader.h:114
Each one of these packets represents an entire spill of data.
std::vector< FiberTrackerEvent > events_data_
This is the actual event data in which we are interested.
int i_event_
index_ of event we are on (for next)
utility::Reader & read(utility::Reader &r)
27 fields in order, all are present
A spill of events from a FiberTracker station.