BadTimings_module.cc
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////
2 // Class: BadTimings
3 // Module type: analyser
4 // File: BadTimings_module.cc
5 // Author: Mike Wallbank (m.wallbank@sheffield.ac.uk), August 2016
6 //
7 // Short analyser to find any timing disparities between detector
8 // components. Written because of the observed offset between RCEs and
9 // PTB in 35ton.
10 //////////////////////////////////////////////////////////////////////////
11 
12 // Framework includes
16 #include "fhiclcpp/ParameterSet.h"
21 #include "art_root_io/TFileService.h"
22 #include "art_root_io/TFileDirectory.h"
24 
25 // lbne-raw-data includes
26 #include "lbne-raw-data/Overlays/TpcMilliSliceFragment.hh"
27 #include "lbne-raw-data/Overlays/PennMilliSlice.hh"
28 
29 // LArSoft includes
31 #include "tpcFragmentToRawDigits.h"
39 #include "PennToOffline.h"
40 
41 #include "TH1I.h"
42 #include "TTree.h"
43 
44 namespace DAQToOffline {
45  class BadTimings;
46 }
47 
49 
50 public:
51 
52  explicit BadTimings(const fhicl::ParameterSet& pset);
53 
54  void analyze(const art::Event& evt);
55 
56 private:
57 
60 
61  lbne::TpcNanoSlice::Header::nova_timestamp_t fRCETriggerTimestamp;
62  lbne::PennMilliSlice::Header::timestamp_t fPTBTriggerTimestamp;
63  // unsigned long long fRCETriggerTimestamp;
64  // unsigned long long fPTBTriggerTimestamp;
65 
68 
70  std::map<int,int> fPTBMap;
71 
72  std::vector<bool> fWithinTrigger;
73 
74  TTree* fTree;
75  int fRun, fEvent, fRCE;
78 
81 
82 };
83 
85  fTPCLabel = pset.get<std::string>("TPCLabel");
86  fTPCInstance = pset.get<std::string>("TPCInstance");
87  fPTBLabel = pset.get<std::string>("PTBLabel");
88  fPTBInstance = pset.get<std::string>("PTBInstance");
89  fPTBMapFile = pset.get<std::string>("PTBMapFile");
90 
91  fWithinTrigger = std::vector<bool>(16,false);
92 
93  hDiffTriggerTimestamps = fTFS->make<TH1I>("PTBRCEDiffTimestamps",";RCE Trigger Timestamp - PTB Trigger Timestamp (NOvA ticks);",100,0,2000);
94  hTriggerStart = fTFS->make<TH1I>("TriggerStart",";Microslice number containing trigger;",15,0,15);
95  hTriggerStart->GetXaxis()->SetNdivisions(15);
96  hTriggerStart->GetXaxis()->CenterLabels();
97 
98  fTree = fTFS->make<TTree>("BadTimings","BadTimings");
99  fTree->Branch("Run", &fRun);
100  fTree->Branch("Event", &fEvent);
101  fTree->Branch("RCE", &fRCE);
102  // fTree->Branch("RCETriggerTimestamp", &fRCETriggerTimestamp);
103  // fTree->Branch("PTBTriggerTimestamp", &fPTBTriggerTimestamp);
104  fTree->Branch("DiffTriggerTimestamps",&fDiffTriggerTimestamps);
105  fTree->Branch("MicrosliceWithTrigger",&fMicrosliceWithTrigger);
106 
107  DAQToOffline::BuildPTBChannelMap("", fPTBMapFile, fPTBMap);
108 }
109 
111 
112  fRun = evt.run();
113  fEvent = evt.event();
114 
115  // Get the TPC data out of the event
116  art::Handle<artdaq::Fragments> RCERawFragments;
117  evt.getByLabel(fTPCLabel, fTPCInstance, RCERawFragments);
118 
119  // Get the counter data out of the event
120  art::Handle<artdaq::Fragments> PTBRawFragments;
121  evt.getByLabel(fPTBLabel, fPTBInstance, PTBRawFragments);
122 
123  // Look at PTB
124  for (size_t fragIndex = 0; fragIndex < PTBRawFragments->size(); ++fragIndex) {
125  const artdaq::Fragment &singleFragment = (*PTBRawFragments)[fragIndex];
126  lbne::PennMilliSliceFragment msf(singleFragment);
127 
128  lbne::PennMicroSlice::Payload_Header *word_header = nullptr;
129  //lbne::PennMicroSlice::Payload_Counter *word_p_counter = nullptr;
130  lbne::PennMicroSlice::Payload_Trigger *word_p_trigger = nullptr;
131  lbne::PennMicroSlice::Payload_Timestamp *previous_timestamp = nullptr;
132  lbne::PennMicroSlice::Payload_Header *future_timestamp_header = nullptr;
133  lbne::PennMicroSlice::Payload_Timestamp *future_timestamp = nullptr;
134  uint8_t* payload_data = nullptr;
135  uint32_t payload_index = 0;
136 
137  uint16_t counter, trigger, timestamp, payloadCount;
138  payloadCount = msf.payloadCount(counter, trigger, timestamp);
139 
140  if (trigger != 1) {
141  //std::cout << "Event has no trigger in PTB data" << std::endl;
142  return;
143  }
144 
145  while (payload_index < uint32_t(payloadCount-1)) {
146 
147  payload_data = msf.get_next_payload(payload_index,word_header);
148  if (payload_data == nullptr)
149  continue;
150 
151  if (word_header->data_packet_type == lbne::PennMicroSlice::DataTypeTimestamp)
152  previous_timestamp = reinterpret_cast<lbne::PennMicroSlice::Payload_Timestamp*>(payload_data);
153  if (word_header->data_packet_type != lbne::PennMicroSlice::DataTypeTrigger)
154  continue;
155 
156  word_p_trigger = reinterpret_cast<lbne::PennMicroSlice::Payload_Trigger*>(payload_data);
157  if (!word_p_trigger->has_muon_trigger()) {
158  std::cout << "Trigger is not from muon" << std::endl;
159  return;
160  }
161 
162  if (previous_timestamp != nullptr)
163  fPTBTriggerTimestamp = word_header->get_full_timestamp_post(previous_timestamp->nova_timestamp);
164  else {
165  if (future_timestamp == nullptr) {
166  future_timestamp = reinterpret_cast<lbne::PennMicroSlice::Payload_Timestamp*>(msf.get_next_timestamp(future_timestamp_header));
167  if (future_timestamp == nullptr) {
168  std::cerr << "CAN'T FIND PTB TIMESTAMP WORDS IN MILLISLICE FRAGMENT!!! Logic will fail." << std::endl;
169  return;
170  }
171  }
172  fPTBTriggerTimestamp = word_header->get_full_timestamp_pre(future_timestamp->nova_timestamp);
173  }
174 
175  } // loop over payloads
176 
177  } // fragments
178 
179  // Look at RCE
180  // Create a map containing (fragmentID, fragIndex) for the event, will be used to check if each channel is present
181  std::map<unsigned int,unsigned int> mapFragID;
182  for (size_t fragIndex = 0; fragIndex < RCERawFragments->size(); ++fragIndex) {
183  const artdaq::Fragment &singleFragment = (*RCERawFragments)[fragIndex];
184  unsigned int fragmentID = singleFragment.fragmentID();
185  mapFragID.insert(std::pair<unsigned int, unsigned int>(fragmentID,fragIndex));
186  }
187 
188  int maxRCEs = 16;
189 
190  // Loop over the RCEs
191  for (std::map<unsigned int,unsigned int>::iterator rceIt = mapFragID.begin(); rceIt != mapFragID.end() and std::distance(mapFragID.begin(),rceIt) < maxRCEs; ++rceIt) {
192 
193  fRCE = rceIt->first - 100;
194 
195  // Get millislice
196  const artdaq::Fragment &singleFragment = (*RCERawFragments)[rceIt->second];
197  lbne::TpcMilliSliceFragment millisliceFragment(singleFragment);
198  //uint64_t millisliceTimestamp = millisliceFragment.microSlice(0)->software_message() & (((long int)0x1 << 56) - 1);
199 
200  // Get microslices
201  auto numMicroSlices = millisliceFragment.microSliceCount();
202  for (unsigned int i_micro = 0; i_micro < numMicroSlices; i_micro++) {
203 
204  std::unique_ptr<const lbne::TpcMicroSlice> microSlice = millisliceFragment.microSlice(i_micro);
205  uint64_t rceTriggerTimestamp = microSlice->software_message() & (((long int)0x1 << 56) - 1);
206 
207  // Get nanoslices
208  auto numNanoSlices = microSlice->nanoSliceCount();
209 
210  if (!fWithinTrigger[fRCE] and numNanoSlices) {
211 
212  // New trigger
213  fWithinTrigger[fRCE] = true;
214  std::cout << std::endl << "New trigger (RCE " << fRCE << ") on microslice " << i_micro << " (event " << evt.event() << ")" << std::endl;
215  //uint64_t nanoSliceTimestamp = microSlice->nanoSlice(0)->nova_timestamp();
216 
217  fRCETriggerTimestamp = rceTriggerTimestamp;
218  fMicrosliceWithTrigger = (rceTriggerTimestamp - microSlice->nanoSlice(0)->nova_timestamp())/*time*/ * (15.625/500)/*nova->tpc tick*/ * 1/1000/* nano->micro*/;
220 
223 
224  fTree->Fill();
225 
226  }
227  else if (fWithinTrigger[fRCE] and !numNanoSlices) {
228 
229  // End of trigger
230  fWithinTrigger[fRCE] = false;
231  std::cout << "End of trigger (RCE " << fRCE << ") on microslice " << i_micro << " (event " << evt.event() << ")" << std::endl;
232 
233  }
234 
235  } // microslices
236 
237  } // rces
238 
239  return;
240 
241 }
242 
244 
245 
246 
247 
248  // // Create a map containing (fragmentID, fragIndex) for the event, will be used to check if each channel is present
249  // std::map<unsigned int,unsigned int> mapFragID;
250  // for (size_t fragIndex = 0; fragIndex < RCERawFragments->size(); ++fragIndex) {
251  // const artdaq::Fragment &singleFragment = (*RCERawFragments)[fragIndex];
252  // unsigned int fragmentID = singleFragment.fragmentID();
253  // mapFragID.insert(std::pair<unsigned int, unsigned int>(fragmentID,fragIndex));
254  // }
255 
256  // fTimestampSet = false;
257 
258  // for (size_t chan = 0; chan < fGeometry->Nchannels(); ++chan) {
259 
260  // // Each channel is uniquely identified by (fragmentID, group, sample) in an online event
261  // unsigned int fragmentID = UnpackFragment::getFragIDForChan(chan);
262  // //unsigned int sample = UnpackFragment::getNanoSliceSampleForChan(chan);
263 
264  // if (mapFragID.find(fragmentID) == mapFragID.end())
265  // continue;
266 
267  // unsigned int fragIndex = mapFragID[fragmentID];
268 
269  // // Get millislice
270  // const artdaq::Fragment &singleFragment = (*RCERawFragments)[fragIndex];
271  // lbne::TpcMilliSliceFragment millisliceFragment(singleFragment);
272 
273  // // Get microslices
274  // auto numMicroSlices = millisliceFragment.microSliceCount();
275  // for (unsigned int i_micro = 0; i_micro < numMicroSlices; i_micro++) {
276 
277  // std::unique_ptr<const lbne::TpcMicroSlice> microSlice = millisliceFragment.microSlice(i_micro);
278  // uint64_t novaTimestamp = microSlice->software_message() & (((long int)0x1 << 56) - 1);
279 
280  // // Get nanoslices
281  // auto numNanoSlices = microSlice->nanoSliceCount();
282 
283  // // Only interested here in the first microslice in a trigger
284  // if (fragIndex == 0 and i_micro == 0 and numNanoSlices) {
285  // }
286 
287  // // Get timestamps for each RCE
288  // if (chan % 128 == 0) {
289  // if (!fWithinTrigger && numNanoSlices) {
290  // fWithinTrigger = true;
291  // uint64_t nanoSliceTimestamp = microSlice->nanoSlice(0)->nova_timestamp();
292  // //std::cout << "Timestamps: nova " << novaTimestamp << " and first nanoslice " << nanoSliceTimestamp << std::endl;
293  // fRCENanosliceTimestamp = nanoSliceTimestamp;
294  // fRCETriggerTimestamp = novaTimestamp;
295  // if (!fTimestampSet || nanoSliceTimestamp < fRCENanosliceTimestamp) {
296  // fRCENanosliceTimestamp = nanoSliceTimestamp;
297  // fTimestampSet = true;
298  // }
299  // std::cout << "Fragment " << fragmentID << ", microslice " << i_micro << ": " << std::endl << "First nanoslice: " << fRCENanosliceTimestamp << ", RCE trigger " << fRCETriggerTimestamp << " and PTB trigger " << fPTBTriggerTimestamp << " (final timestamp is " << fRCENanosliceTimestamp << ")" << std::endl;
300  // }
301  // else if (fWithinTrigger && !numNanoSlices) {
302  // fWithinTrigger = false;
303  // }
304  // }
305 
306  // } // microslices
307 
308  // } // channels
intermediate_table::iterator iterator
EventNumber_t event() const
Definition: DataViewImpl.cc:96
std::vector< bool > fWithinTrigger
art::ServiceHandle< geo::Geometry > fGeometry
std::string string
Definition: nybbler.cc:12
void BuildPTBChannelMap(std::string MapDir, std::string MapFile, std::map< int, int > &channelMap)
unsigned short uint16_t
Definition: stdint.h:125
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:27
unsigned char uint8_t
Definition: stdint.h:124
lbne::PennMilliSlice::Header::timestamp_t fPTBTriggerTimestamp
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
Definition: DataViewImpl.h:446
object containing MC truth information necessary for making RawDigits and doing back tracking ...
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
Definition: counter.h:285
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:69
unsigned int uint32_t
Definition: stdint.h:126
BadTimings(const fhicl::ParameterSet &pset)
T get(std::string const &key) const
Definition: ParameterSet.h:231
unsigned __int64 uint64_t
Definition: stdint.h:136
std::map< int, int > fPTBMap
RunNumber_t run() const
Definition: DataViewImpl.cc:82
Utility object to perform functions of association.
lbne::TpcNanoSlice::Header::nova_timestamp_t fRCETriggerTimestamp
art::ServiceHandle< art::TFileService > fTFS
TCEvent evt
Definition: DataStructs.cxx:7
void analyze(const art::Event &evt)
QTextStream & endl(QTextStream &s)