LDMX Software
Public Member Functions | Private Attributes | List of all members
trigscint::QIEEncoder Class Reference

Public Member Functions

 QIEEncoder (const std::string &name, framework::Process &process)
 
virtual ~QIEEncoder ()=default
 Default destructor, closes up boost archive and input stream.
 
void configure (framework::config::Parameters &ps) override
 Configure our converter based off the configuration parameters decoded from the passed python script.
 
void produce (framework::Event &event) override
 Process the event and put new data products into it.
 
void onProcessStart () override
 Callback for the EventProcessor to take any necessary action when the processing of events starts, such as creating histograms.
 
void onProcessEnd () override
 Callback for the EventProcessor to take any necessary action when the processing of events finishes, such as calculating job-summary quantities.
 
- Public Member Functions inherited from framework::Producer
 Producer (const std::string &name, Process &process)
 Class constructor.
 
virtual void beforeNewRun (ldmx::RunHeader &header)
 Handle allowing producers to modify run headers before the run begins.
 
- Public Member Functions inherited from framework::EventProcessor
 EventProcessor (const std::string &name, Process &process)
 Class constructor.
 
virtual ~EventProcessor ()
 Class destructor.
 
virtual void onNewRun (const ldmx::RunHeader &runHeader)
 Callback for the EventProcessor to take any necessary action when the run being processed changes.
 
virtual void onFileOpen (EventFile &eventFile)
 Callback for the EventProcessor to take any necessary action when a new event input ROOT file is opened.
 
virtual void onFileClose (EventFile &eventFile)
 Callback for the EventProcessor to take any necessary action when a event input ROOT file is closed.
 
template<class T >
const T & getCondition (const std::string &condition_name)
 Access a conditions object for the current event.
 
TDirectory * getHistoDirectory ()
 Access/create a directory in the histogram file for this event processor to create histograms and analysis tuples.
 
void setStorageHint (framework::StorageControl::Hint hint)
 Mark the current event as having the given storage control hint from this module.
 
void setStorageHint (framework::StorageControl::Hint hint, const std::string &purposeString)
 Mark the current event as having the given storage control hint from this module and the given purpose string.
 
int getLogFrequency () const
 Get the current logging frequency from the process.
 
int getRunNumber () const
 Get the run number from the process.
 
std::string getName () const
 Get the processor name.
 
void createHistograms (const std::vector< framework::config::Parameters > &histos)
 Internal function which is used to create histograms passed from the python configuration @parma histos vector of Parameters that configure histograms to create.
 

Private Attributes

std::string channelMapFileName_
 
std::ifstream channelMapFile_
 
std::map< int, int > channelMap_
 
std::string inputCollection_
 
std::string inputPassName_
 
std::string outputCollection_
 
bool verbose_ {false}
 
int nChannels_ {50}
 

Additional Inherited Members

- Static Public Member Functions inherited from framework::EventProcessor
static void declare (const std::string &classname, int classtype, EventProcessorMaker *)
 Internal function which is part of the PluginFactory machinery.
 
- Static Public Attributes inherited from framework::Producer
static const int CLASSTYPE {1}
 Constant used to track EventProcessor types by the PluginFactory.
 
- Protected Member Functions inherited from framework::EventProcessor
void abortEvent ()
 Abort the event immediately.
 
- Protected Attributes inherited from framework::EventProcessor
HistogramHelper histograms_
 Interface class for making and filling histograms.
 
NtupleManagerntuple_ {NtupleManager::getInstance()}
 Manager for any ntuples.
 
logging::logger theLog_
 The logger for this EventProcessor.
 

Detailed Description

Definition at line 15 of file QIEEncoder.h.

Constructor & Destructor Documentation

◆ QIEEncoder()

trigscint::QIEEncoder::QIEEncoder ( const std::string &  name,
framework::Process process 
)
inline

Definition at line 17 of file QIEEncoder.h.

18 : Producer(name, process) {}
Producer(const std::string &name, Process &process)
Class constructor.

Member Function Documentation

◆ configure()

void trigscint::QIEEncoder::configure ( framework::config::Parameters ps)
overridevirtual

Configure our converter based off the configuration parameters decoded from the passed python script.

Reimplemented from framework::EventProcessor.

Definition at line 8 of file QIEEncoder.cxx.

8 {
9 // Configure this instance of the encoder
10 outputCollection_ = ps.getParameter<std::string>("output_collection");
11 inputCollection_ = ps.getParameter<std::string>("input_collection");
12 inputPassName_ = ps.getParameter<std::string>("input_pass_name");
13 channelMapFileName_ = ps.getParameter<std::string>("channel_map_file");
14 nChannels_ = ps.getParameter<int>("number_channels");
15 verbose_ = ps.getParameter<bool>("verbose");
16
17 ldmx_log(debug) << "In configure, got parameters:"
18 << "\noutput_collection = " << outputCollection_
19 << "\ninput_collection = " << inputCollection_
20 << "\ninput_pass_name = " << inputPassName_
21 << "\nchannel_map_file = " << channelMapFileName_
22 << "\nnumber_channels = " << nChannels_
23 << "\nverbose = " << verbose_;
24
25 // set up channel mapping
26 channelMapFile_.open(channelMapFileName_, std::ios::in);
27 if (!channelMapFile_.is_open()) {
28 EXCEPTION_RAISE(
29 "BadMapFile",
30 "The channel mapping file cannot be opened."); // <-- appears this
31 // needs implementing
32 // first
33 ldmx_log(fatal) << "The channel mapping file cannot be opened.";
34 return;
35 }
36 int chID, elID;
37 while (!channelMapFile_.eof()) {
38 channelMapFile_ >> elID >> chID;
39 // for test beam, we will only know the elecID from
40 // the position of the word in the stream.
41 // so these need to be strictly ordered in the map.
42 // barID can always be set, or looked up, as a property of the digi.
43
44 // make this based on channel ID. this is like looking up the position in a
45 // vector of a certain value. but it's fine
46 channelMap_.insert(std::pair<int, int>(chID, elID));
47 ldmx_log(debug) << "elID " << elID << " chID " << chID;
48 }
49 if (elID != nChannels_ - 1)
50 ldmx_log(fatal) << "The set number of channels " << nChannels_
51 << " seems not to match the number from the map (+1) :"
52 << elID;
53 channelMapFile_.close();
54
55 return;
56}
T getParameter(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:89

References framework::config::Parameters::getParameter().

◆ onProcessEnd()

void trigscint::QIEEncoder::onProcessEnd ( )
overridevirtual

Callback for the EventProcessor to take any necessary action when the processing of events finishes, such as calculating job-summary quantities.

Reimplemented from framework::EventProcessor.

Definition at line 236 of file QIEEncoder.cxx.

236 {
237 ldmx_log(debug) << "Process ends!";
238
239 return;
240}

◆ onProcessStart()

void trigscint::QIEEncoder::onProcessStart ( )
overridevirtual

Callback for the EventProcessor to take any necessary action when the processing of events starts, such as creating histograms.

Reimplemented from framework::EventProcessor.

Definition at line 230 of file QIEEncoder.cxx.

230 {
231 ldmx_log(debug) << "Process starts!";
232
233 return;
234}

◆ produce()

void trigscint::QIEEncoder::produce ( framework::Event event)
overridevirtual

Process the event and put new data products into it.

Parameters
eventThe Event to process.

Implements framework::Producer.

Definition at line 58 of file QIEEncoder.cxx.

58 {
59 ldmx_log(debug) << "QIEEncoder: produce() starts! Event number: "
60 << event.getEventHeader().getEventNumber();
61
62 std::vector<trigscint::QIEStream> qieOuts;
63 int nSamp = QIEStream::NUM_SAMPLES;
64 std::vector<int> initVec(nSamp, 0);
65 ldmx_log(debug) << "num samples = " << nSamp;
66
67 // we're keeping a list ordered in elec ID since this is the order we'll use
68 // to write them to stream
69 for (int iQ = 0; iQ < nChannels_; iQ++) {
70 QIEStream qieOut;
71 qieOut.setADC(initVec);
72 qieOut.setTDC(initVec);
73 qieOut.setCID(initVec);
74 qieOut.setElectronicsID(iQ); // assume id is index
75
76 qieOuts.push_back(qieOut);
77 }
78
79 ldmx_log(debug) << "Looking up input collection " << inputCollection_ << "_"
80 << inputPassName_;
81 const auto digis{event.getCollection<trigscint::TrigScintQIEDigis>(
82 inputCollection_, inputPassName_)};
83 ldmx_log(debug) << "Got input collection" << inputCollection_ << "_"
84 << inputPassName_;
85
86 bool isCIDunsync = false; // mismatch between CID reported by channels within
87 // the same time sample
88 bool isCIDskipped = false; // a gap in the CID increment
89 bool isCRC0malformed = false; // an issue with CRC from fiber0
90 bool isCRC1malformed = false; // an issue with CRC from fiber1
91
92 int firstCID = -1;
93 ldmx_log(debug) << "entering loop over digis ";
94 for (auto &digi : digis) {
95 int bar = digi.getChanID();
96 auto itr = channelMap_.find(bar);
97 if (itr == channelMap_.end()) { // yikes! didn't find the bar in the map
98 ldmx_log(fatal) << "Couldn't find an entry for bar " << bar
99 << "; check the (choice of) channel map!. Exiting event "
100 << event.getEventHeader().getEventNumber();
101 return;
102 }
103 int idx = itr->second; // here we're just using the order. no actual elID
104 // is assumed.
105 qieOuts.at(idx).setChannelID(bar);
106 qieOuts.at(idx).setElectronicsID(idx);
107 ldmx_log(debug) << "Channel " << bar << " elec ID "
108 << qieOuts.at(idx).getElectronicsID();
109 std::vector<int> LEtdcs; // make the LE (Leading Edge) truncation explicit
110 std::vector<uint8_t> cids;
111 for (int iS = 0; iS < nSamp; iS++) {
112 int tdc = digi.getTDC().at(iS);
113 int cid = digi.getCID().at(iS);
114 if (cids.size() > 0 && (cid % 4) != ((cids.back() + 1) % 4)) {
115 // by construction shouldn't happen in simulation. still, explicitly
116 // checking here, considering any future changes to our CID simulation.
117 isCIDskipped = true;
118 }
119 if (verbose_) { // all this is only useful for debugging
120 std::vector<uint8_t> adcs;
121 int adc = digi.getADC().at(iS);
122 uint8_t mant = adc % 64;
123 uint8_t exp = adc / 64;
124 ldmx_log(debug) << "\tSample " << iS << std::left << std::setw(6)
125 << " ADC " << adc << ",\texp " << unsigned(exp)
126 << " mant " << unsigned(mant) << ",\tTDC = " << tdc
127 << ", LE TDC = " << std::bitset<8>(tdc / 16)
128 << " and capID= " << cid;
129 adcs.push_back(64 * exp + mant);
130 ldmx_log(debug) << "Combined ADC: " << std::showbase
131 << std::bitset<8>(adcs.back()) << " and original adc "
132 << std::bitset<8>(adc) << std::dec;
133 } // if verbose
134
135 tdc /= 16; // do LE (leading edge) TDC
136 LEtdcs.push_back(tdc);
137 cids.push_back((uint8_t)cid);
138 } // over samples
139 if (firstCID == -1) {
140 // just store the 5th one, doesn't matter; if all channels
141 // are aligned then cids should match at any given time sample
142 firstCID = cids.back();
143 }
144 if (firstCID != cids.back()) {
145 isCIDunsync =
146 true; // any one channel not aligned is enough to set this bool
147 }
148 qieOuts.at(idx).setADC(digi.getADC());
149 qieOuts.at(idx).setTDC(LEtdcs);
150 } // over digis
151 if (isCIDunsync) ldmx_log(debug) << "Found unsynced CIDs!";
152 if (isCIDskipped) ldmx_log(info) << "Found skipped CIDs!";
153
154 // data format:
155 // RM ID: we don't set it for testbeam so skip for now.
156 // 16 bit trigger ID.
157 // 4 bits of flags, then 4 reserved 0 for now
158 // some 8-bit error word/checksum.
159 // all channel 8-bit ADCs.
160 // all channel TDCS.
161 // done.
162
163 uint16_t triggerID = event.getEventHeader().getEventNumber();
164 uint8_t randomChecksum =
165 30; // just some number for now. TODO implement a checksum
166 uint8_t flags = 0; // we use this to contain the four reserved 0's too
167 // put it all in, at the assigned position
168 flags |= (isCRC0malformed << QIEStream::CRC0_ERR_POS);
169 flags |= (isCRC1malformed << QIEStream::CRC1_ERR_POS);
170 flags |= (isCIDunsync << QIEStream::CID_UNSYNC_POS);
171 flags |= (isCIDskipped << QIEStream::CID_SKIP_POS);
172 ldmx_log(debug) << "FLAGS: " << std::bitset<8>(flags);
173
174 std::vector<uint8_t> outWord;
175 std::vector<uint8_t> triggerIDwords;
176 for (int iW = QIEStream::TRIGID_LEN_BYTES - 1; iW >= 0; iW--) {
177 // assume the whole 2B are written as a single 16-bit word
178 uint8_t tIDword = triggerID >> iW * 8; // shift by a byte at a time
179 triggerIDwords.push_back(tIDword);
180 outWord.push_back(tIDword);
181 }
182
183 outWord.push_back(flags);
184 outWord.push_back(randomChecksum);
185
186 if (verbose_) {
187 std::cout << "header word ";
188 for (auto word : outWord) std::cout << std::bitset<8>(word) << " ";
189 std::cout << std::endl;
190 }
191
192 // now write this in sequence: ADC of all channels, then TDC; repeat for all
193 // samples
194 for (int iS = 0; iS < nSamp; iS++) {
195 for (int iQ = 0; iQ < nChannels_; iQ++) {
196 outWord.push_back(qieOuts.at(iQ).getADC().at(iS));
197 } // over channels : ADC
198 for (int iQ = 0; iQ < nChannels_; iQ++) {
199 outWord.push_back(qieOuts.at(iQ).getTDC().at(iS));
200 } // over channels: TDC
201 } // over time samples
202
203 // in verbose mode, print this all to screen
204 if (verbose_) {
205 std::cout << "total word ";
206 int widx = 0;
207 int iWstart =
208 std::max(std::max(QIEStream::ERROR_POS, QIEStream::CHECKSUM_POS),
209 QIEStream::TRIGID_POS + (QIEStream::TRIGID_LEN_BYTES)) +
210 1; // probably overkill :D should be 4
211 for (auto word : outWord) {
212 if ((widx - iWstart) % nChannels_ == 0) {
213 int sample = (widx - iWstart) / nChannels_;
214 if (sample % 2 == 0)
215 std::cout << "\n sample " << sample / 2 << " | ";
216 else
217 std::cout << "\n TDC: ";
218 }
219 std::cout << (unsigned)word << " ";
220 // std::cout << std::bitset<8>(word) << " " ; //for binary output
221 // format
222 widx++;
223 }
224 std::cout << std::endl;
225 } // if verbose
226
227 event.add(outputCollection_, outWord);
228}
class for storing QIE output

References trigscint::QIEStream::setADC(), trigscint::QIEStream::setCID(), trigscint::QIEStream::setElectronicsID(), and trigscint::QIEStream::setTDC().

Member Data Documentation

◆ channelMap_

std::map<int, int> trigscint::QIEEncoder::channelMap_
private

Definition at line 41 of file QIEEncoder.h.

◆ channelMapFile_

std::ifstream trigscint::QIEEncoder::channelMapFile_
private

Definition at line 40 of file QIEEncoder.h.

◆ channelMapFileName_

std::string trigscint::QIEEncoder::channelMapFileName_
private

Definition at line 39 of file QIEEncoder.h.

◆ inputCollection_

std::string trigscint::QIEEncoder::inputCollection_
private

Definition at line 44 of file QIEEncoder.h.

◆ inputPassName_

std::string trigscint::QIEEncoder::inputPassName_
private

Definition at line 45 of file QIEEncoder.h.

◆ nChannels_

int trigscint::QIEEncoder::nChannels_ {50}
private

Definition at line 54 of file QIEEncoder.h.

54{50};

◆ outputCollection_

std::string trigscint::QIEEncoder::outputCollection_
private

Definition at line 47 of file QIEEncoder.h.

◆ verbose_

bool trigscint::QIEEncoder::verbose_ {false}
private

Definition at line 51 of file QIEEncoder.h.

51{false};

The documentation for this class was generated from the following files: