RceRawDecoder_module.cc
Go to the documentation of this file.
1 // art includes
11 #include "art_root_io/TFileService.h"
12 
13 // artdaq and dune-raw-data includes
15 #include "artdaq-core/Data/Fragment.hh"
16 #include "artdaq-core/Data/ContainerFragment.hh"
19 
20 // larsoft includes
22 
23 // ROOT includes
24 #include "TH1.h"
25 #include "TH2F.h"
26 #include "TProfile.h"
27 
28 // C++ Includes
29 #include <memory>
30 #include <iostream>
31 
32 namespace dune {
33  class RceRawDecoder;
34 }
35 
37 public:
38  explicit RceRawDecoder(fhicl::ParameterSet const & p);
39  // The destructor generated by the compiler is fine for classes
40  // without bare pointers or other resource use.
41 
42  // Plugins should not be copied or assigned.
43  RceRawDecoder(RceRawDecoder const &) = delete;
44  RceRawDecoder(RceRawDecoder &&) = delete;
45  RceRawDecoder & operator = (RceRawDecoder const &) = delete;
47 
48  // Required functions.
49  void produce(art::Event & e) override;
50  void reconfigure(const fhicl::ParameterSet &pset);
51  void beginJob() override;
52 
53  void setRootObjects();
54 
55 private:
56  typedef std::vector<raw::RawDigit> RawDigits;
57 
58  bool _process(
59  const artdaq::Fragment& frag,
60  RawDigits& raw_digits);
61 
62  // Declare member data here.
66 
67  TH1D* _h_nticks;
70  TH1I* _h_slot_IDs;
71  TH1I* _h_fiber_IDs;
74  std::vector<TH2F*> _h_mean_slot_channels;
75  std::vector<TH2F*> _h_rms_slot_channels;
76  std::vector<TProfile*> _h_mean_slot_channels_pfx;
77  std::vector<TProfile*> _h_rms_slot_channels_pfx;
78  std::vector<TH2I*> _h_fiber_persistent_wav;
79  std::vector<int16_t> _buffer;
80 
81  // define my rms and mean functions
84 };
85 
86 
88  : EDProducer{pset}
89 // Initialize member data here.
90 {
92  //fs->registerFileSwitchCallback(this, &RceRawDecoder::setRootObjects);
94 
95  reconfigure(pset);
96  // Call appropriate produces<>() functions here.
97  //produces< std::vector<raw::RawDigit> > ( _output_label );
98  produces<RawDigits>( _output_label );
99 }
100 
102 
103  _input_label = pset.get<std::string>("RawDataLabel");
104  _output_label = pset.get<std::string>("OutputDataLabel");
105  _expect_container_fragments = pset.get<bool>("ExpectContainerFragments", true);
106 }
107 
109  //clear vectors
110  _h_mean_slot_channels.clear();
111  _h_rms_slot_channels.clear();
113  _h_rms_slot_channels_pfx.clear();
114  _h_fiber_persistent_wav.clear();
115  // place to define the histograms
117  _h_nticks = file_srv->make<TH1D>("rce_NTicks","TPC: Number of ticks", 100, 0, 20000);
118  _h_nticks->SetXTitle("NTicks");
119  _h_all_adc_values = file_srv->make<TH1I>("rce_All_ADC_values","TPC: All_ADC_values", 5000, 0, 5000);
120  _h_all_adc_values->SetXTitle("ADC");
121  _h_crate_numbers = file_srv->make<TH1I>("rce_All_crate_numbers","TPC: Crate Numbers", 6, 0, 6);
122  _h_crate_numbers->SetXTitle("Crate Number");
123  _h_slot_IDs = file_srv->make<TH1I>("rce_All_slot_IDs","TPC: Slot IDs", 30, 0, 30);
124  _h_slot_IDs->SetXTitle("Slot ID");
125  _h_fiber_IDs = file_srv->make<TH1I>("rce_All_fiber_IDs","TPC: Fiber IDs", 120, 0, 120);
126  _h_fiber_IDs->SetXTitle("Fiber ID");
127  _h_online_channels = file_srv->make<TH1I>("rce_Online_Channels", "TPC: Online Channel ID", 5000, 0, 5000);
128  _h_offline_channels = file_srv->make<TH1I>("rce_Offline_Channels", "TPC: Offline Channel ID", 5000, 0, 5000);
129  for(int i=0;i<30;i++) {
130  _h_mean_slot_channels.push_back(file_srv->make<TH2F>(Form("Slot%d_Mean", i), Form("Slot%d:Mean_vs_SlotChannel", i), 512, 0, 512, 5000, .0, 5000)); //hard-coded for now. Will be moved to the analyzer module. Feb 7, 2018
131  _h_rms_slot_channels.push_back(file_srv->make<TH2F>(Form("Slot%d_RMS", i), Form("Slot%d:RMS_vs_SlotChannel", i), 512, 0, 512, 5000, .0, 5000)); //hard-coded for now. Will be moved to the analyzer module. Feb 7, 2018
132  _h_mean_slot_channels_pfx.push_back(file_srv->make<TProfile>(Form("Slot%d_Mean_pfx", i), Form("Slot%d:Mean_vs_SlotChannel_pfx", i), 512, 0, 512)); //hard-coded for now. Will be moved to the analyzer module. Feb 7, 2018
133  _h_rms_slot_channels_pfx.push_back(file_srv->make<TProfile>(Form("Slot%d_RMS_pfx", i), Form("Slot%d:RMS_vs_SlotChannel_pfx", i), 512, 0, 512)); //hard-coded for now. Will be moved to the analyzer module. Feb 7, 2018
134 
135  _h_mean_slot_channels[i]->GetXaxis()->SetTitle("Slot Channel"); _h_mean_slot_channels[i]->GetYaxis()->SetTitle("Raw Mean");
136  _h_rms_slot_channels[i]->GetXaxis()->SetTitle("Slot Channel"); _h_rms_slot_channels[i]->GetYaxis()->SetTitle("Raw RMS");
137  _h_mean_slot_channels_pfx[i]->GetXaxis()->SetTitle("Slot Channel"); _h_mean_slot_channels_pfx[i]->GetYaxis()->SetTitle("Profiled Mean");
138  _h_rms_slot_channels_pfx[i]->GetXaxis()->SetTitle("Slot Channel"); _h_rms_slot_channels_pfx[i]->GetYaxis()->SetTitle("Profiled RMS");
139  }
140  for(int i=0;i<120;i++) {
141  _h_fiber_persistent_wav.push_back(file_srv->make<TH2I>(Form("Persistent_Waveform_Fiber#%d", i), Form("Persistent_Waveform_Fiber#%d", i), 10000, 0, 10000, 500, 0, 5000));
142  }
143 
144 }
146 }
147 
149  // TODO Use MF_LOG_DEBUG
150  MF_LOG_INFO("RceRawDecoder")
151  << "-------------------- RCE RawDecoder -------------------";
152 
153  RawDigits raw_digits;
154  unsigned int n_rce_frags = 0;
155 
157  art::InputTag itag1(_input_label, "ContainerTPC");
158  auto cont_frags = evt.getHandle<artdaq::Fragments>(itag1);
159  art::EventNumber_t eventNumber = evt.event();
160  // Check if there is Timing data in this event
161  // Don't crash code if not present, just don't save anything
162  try { cont_frags->size(); }
163  catch(std::exception const&) {
164  std::cout << "WARNING: Container TPC/RCE data not found in event " << eventNumber << std::endl;
165  std::vector<raw::RawDigit> digits;
166  evt.put(std::make_unique<std::vector<raw::RawDigit>>(std::move(digits)), _output_label);
167  return;
168  }
169  //Check that the data is valid
170  if(!cont_frags){
171  MF_LOG_ERROR("RceRawDecoder")
172  << "Run: " << evt.run()
173  << ", SubRun: " << evt.subRun()
174  << ", Event: " << evt.event()
175  << " Container Fragments is NOT VALID";
176  }
177 
178  for (auto const& cont : *cont_frags)
179  {
180  artdaq::ContainerFragment cont_frag(cont);
181  for (size_t ii = 0; ii < cont_frag.block_count(); ++ii)
182  {
183  //artdaq::Fragment frag;
184  //size_t frag_size = cont_frag.fragSize(ii);
185  //frag.resizeBytes(frag_size);
186  //memcpy(frag.headerAddress(), cont_frag.at(ii), frag_size);
187  if (_process(*cont_frag[ii], raw_digits)) ++n_rce_frags;
188  }
189  }
190  }
191  else
192  {
193  art::InputTag itag2(_input_label, "TPC");
194  auto frags = evt.getHandle<artdaq::Fragments>(itag2);
195 
196  // Check if there is Timing data in this event
197  // Don't crash code if not present, just don't save anything
198  art::EventNumber_t eventNumber = evt.event();
199  try { frags->size(); }
200  catch(std::exception const&) {
201  std::cout << "WARNING: Raw TPC/RCE data not found in event " << eventNumber << std::endl;
202  std::vector<raw::RawDigit> digits;
203  evt.put(std::make_unique<std::vector<raw::RawDigit>>(std::move(digits)), _output_label);
204  return;
205  }
206 
207  //Check that the data is valid
208  if(!frags.isValid()){
209  MF_LOG_ERROR("RceRawDecoder")
210  << "Run: " << evt.run()
211  << ", SubRun: " << evt.subRun()
212  << ", Event: " << evt.event()
213  << " Fragments is NOT VALID";
214  }
215 
216  for(auto const& frag: *frags)
217  {
218  if (_process(frag, raw_digits)) ++n_rce_frags;
219  }
220  }
221 
222  MF_LOG_INFO("RceRawDecoder")
223  << " Processed " << n_rce_frags
224  << " RCE Fragments, "
225  << raw_digits.size()
226  << " RawDigits.";
227 
228  evt.put(std::make_unique<decltype(raw_digits)>(std::move(raw_digits)),
229  _output_label);
230 }
231 
233  const artdaq::Fragment& frag,
234  RawDigits& raw_digits
235  )
236 {
237  // FIXME: Remove hard-coded fragment type
238  if((unsigned)frag.type() != 2) return false;
239 
240  MF_LOG_INFO("RceRawDecoder")
241  << " SequenceID = " << frag.sequenceID()
242  << " fragmentID = " << frag.fragmentID()
243  << " fragmentType = " << (unsigned)frag.type()
244  << " Timestamp = " << frag.timestamp();
246  dune::RceFragment rce(frag);
247 
248  uint32_t ch_counter = 0;
249  for (int i = 0; i < rce.size(); ++i)
250  {
251  auto const * rce_stream = rce.get_stream(i);
252  int n_ch = rce_stream->getNChannels();
253  int n_ticks = rce_stream->getNTicks();
254  auto const identifier = rce_stream->getIdentifier();
255  uint32_t crateNumber = identifier.getCrate();
256  uint32_t slotNumber = identifier.getSlot();
257  uint32_t fiberNumber = identifier.getFiber();
258  std::cout<<"crate, slot, fiber = "<<crateNumber<<", "<<slotNumber<<", "<<fiberNumber<<std::endl;
259  uint32_t fiberID = (crateNumber*5+slotNumber)*4 + fiberNumber;
260  _h_fiber_IDs->Fill(fiberID);
261  MF_LOG_INFO("RceRawDecoder")
262  << "RceFragment timestamp: " << rce_stream->getTimeStamp()
263  << ", NChannels: " << n_ch
264  << ", NTicks: " << n_ticks;
265 
266  _h_nticks->Fill(n_ticks);
267 
268  size_t buffer_size = n_ch * n_ticks;
269  if (_buffer.capacity() < buffer_size)
270  {
271  MF_LOG_INFO("RceRawDecoder")
272  << "Increase buffer size from " << _buffer.capacity()
273  << " to " << buffer_size;
274 
275  _buffer.reserve(buffer_size);
276  }
277 
278  int16_t* adcs = _buffer.data();
279  rce_stream->getMultiChannelData(adcs);
280 
282  for (int i_ch = 0; i_ch < n_ch; i_ch++)
283  {
284  if(i==0 && i_ch ==0) std::cout<<" ADCs for the the 100 ticks in the 1st channel of the 1st RCE "<<std::endl;
285  v_adc.clear();
286  for (int i_tick = 0; i_tick < n_ticks; i_tick++)
287  {
288  //print ADCs for the the 100 ticks in the 1st channel of the 1st RCE
289  if(i==0 && i_ch==0 && i_tick<100) {
290  std::cout<<adcs[i_tick]<<"\t";
291  if(i_tick==99) std::cout<<std::endl;
292  }
293  v_adc.push_back(adcs[i_tick]);
294  _h_all_adc_values->Fill(adcs[i_tick]);
295  //save the 1st waveform in a fiber
296  _h_fiber_persistent_wav.at(fiberID)->Fill(i_tick, adcs[i_tick]);
297  }
298  adcs += n_ticks;
299 
300  ch_counter++;
301  int offlineChannel = -1;
302  offlineChannel = channelMap->GetOfflineNumberFromDetectorElements(crateNumber, slotNumber, fiberNumber, i_ch, dune::PdspChannelMapService::kRCE);
303  _h_offline_channels->Fill(offlineChannel);
304  raw::RawDigit raw_digit(offlineChannel, n_ticks, v_adc);
305  raw_digits.push_back(raw_digit);
306 
307  //=========== fill Mean and RMS with slotchannel number=====================
308  uint32_t slotID = crateNumber*5 + slotNumber; //0 - 29
309  _h_slot_IDs->Fill(slotID);
310  uint32_t slotchannel = 0; // 0 - 127
311  slotchannel = fiberNumber*128 + i_ch; //hard-coded. will be moved to analyzer module. Feb 7, 2018
312  float mean = meanADC(v_adc);
313  float rms = rmsADC(v_adc);
314  _h_mean_slot_channels.at(slotID)->Fill(slotchannel, mean);
315  _h_rms_slot_channels.at(slotID)->Fill(slotchannel, rms);
316  _h_mean_slot_channels_pfx.at(slotID)->Fill(slotchannel, mean, 1);
317  _h_rms_slot_channels_pfx.at(slotID)->Fill(slotchannel, rms, 1);
318  //==========================================================================
319 
320 
321  }
322  }
323 
324  return true;
325 }
326 
327 //-----------------------------------------------------------------------
328  // define RMS
330  {
331  int n = wav.size();
332  float sum = 0.;
333  for(int i = 0; i < n; i++){
334  if(wav[i]!=0) sum += wav[i];
335  }
336  float mean = sum / n;
337  sum = 0;
338  for(int i = 0; i < n; i++)
339  {
340  if (wav[i]!=0) sum += (wav[i]-mean)*(wav[i]-mean);
341  }
342  return sqrt(sum / n);
343  }
344 
345  //-----------------------------------------------------------------------
346  //define Mean
348  {
349  int n = wav.size();
350  float sum = 0.;
351  for(int i = 0; i < n; i++)
352  {
353  if (wav[i]!=0) sum += abs(wav[i]);
354  }
355  return sum / n;
356  }
357 
std::vector< int16_t > _buffer
EventNumber_t event() const
Definition: DataViewImpl.cc:85
Collection of charge vs time digitized from a single readout channel.
Definition: RawDigit.h:69
TpcStreamUnpack const * get_stream(int i) const
Definition: RceFragment.cc:48
double rms(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:40
void reconfigure(const fhicl::ParameterSet &pset)
Handle< PROD > getHandle(SelectorBase const &) const
Definition: DataViewImpl.h:382
std::string string
Definition: nybbler.cc:12
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
std::vector< TProfile * > _h_mean_slot_channels_pfx
bool _process(const artdaq::Fragment &frag, RawDigits &raw_digits)
static constexpr double fs
Definition: Units.h:100
#define MF_LOG_ERROR(category)
std::vector< short > ADCvector_t
Type representing a (compressed) vector of ADC counts.
Definition: RawDigit.h:73
RceRawDecoder(fhicl::ParameterSet const &p)
std::vector< TH2F * > _h_rms_slot_channels
int size() const
Definition: RceFragment.hh:25
unsigned int GetOfflineNumberFromDetectorElements(unsigned int crate, unsigned int slot, unsigned int fiber, unsigned int fembchannel, FelixOrRCE frswitch)
T abs(T value)
const double e
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
std::void_t< T > n
float meanADC(raw::RawDigit::ADCvector_t &wav)
def move(depos, offset)
Definition: depos.py:107
T get(std::string const &key) const
Definition: ParameterSet.h:271
p
Definition: test.py:223
SubRunNumber_t subRun() const
Definition: DataViewImpl.cc:78
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
RunNumber_t run() const
Definition: DataViewImpl.cc:71
#define MF_LOG_INFO(category)
float rmsADC(raw::RawDigit::ADCvector_t &wav)
std::vector< raw::RawDigit > RawDigits
std::vector< TH2F * > _h_mean_slot_channels
IDNumber_t< Level::Event > EventNumber_t
Definition: IDNumber.h:118
std::vector< TProfile * > _h_rms_slot_channels_pfx
TCEvent evt
Definition: DataStructs.cxx:7
std::vector< TH2I * > _h_fiber_persistent_wav
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:16
std::vector< Fragment > Fragments
Definition: HDF5Utils.h:57
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
void produce(art::Event &e) override
QTextStream & endl(QTextStream &s)
RceRawDecoder & operator=(RceRawDecoder const &)=delete