All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DaqDecoderICARUSPMTold_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: DaqDecoderIcarus
3 // Plugin Type: producer (art v2_09_06)
4 // File: DaqDecoderIcarus.cxx
5 //
6 ////////////////////////////////////////////////////////////////////////
7 
8 #include "art/Framework/Core/EDProducer.h"
9 #include "art/Framework/Core/ModuleMacros.h"
10 #include "art/Framework/Principal/Event.h"
11 #include "art/Framework/Principal/Handle.h"
12 #include "art/Framework/Principal/Run.h"
13 #include "art/Framework/Principal/SubRun.h"
14 #include "canvas/Utilities/InputTag.h"
15 #include "canvas/Persistency/Common/FindMany.h"
16 #include "canvas/Persistency/Common/FindOne.h"
17 #include "fhiclcpp/ParameterSet.h"
18 #include "messagefacility/MessageLogger/MessageLogger.h"
19 
22 #include "artdaq-core/Data/Fragment.hh"
23 #include "sbndaq-artdaq-core/Overlays/ICARUS/PhysCrateFragment.hh"
24 #include "sbndaq-artdaq-core/Overlays/Common/CAENV1730Fragment.hh"
25 
26 //#include "sbnddaq-datatypes/Overlays/NevisTPCFragment.hh"
27 
28 //some standard C++ includes
29 #include <iostream>
30 #include <stdlib.h>
31 #include <string>
32 #include <vector>
33 
34 namespace daq
35 {
36 
37 class DaqDecoderIcarusPMTold : public art::EDProducer
38 {
39 public:
40  explicit DaqDecoderIcarusPMTold(fhicl::ParameterSet const & p);
41 
42  // Required functions.
43  void produce(art::Event & e) override;
44 
45  // get checksum from a Icarus fragment
46  //static uint32_t compute_checksum(sbnddaq::NevisTPCFragment &fragment);
47 // static uint32_t compute_checksum(icarus::PhysCrateFragment &fragment);
48 
49 private:
50  class Config
51  {
52  public:
53  int wait_sec;
54  int wait_usec;
58  unsigned n_mode_skip;
60 
61  unsigned channel_per_slot;
62  unsigned min_slot_no;
63 
64  // for converting frame time into timestamp
65  unsigned timesize;
66  double frame_to_dt;
67 
68  Config(fhicl::ParameterSet const & p);
69  };
70 
71  // process an individual fragment inside an art event
72  void process_fragment(art::Event &event, const artdaq::Fragment &frag, std::unique_ptr<std::vector<raw::RawDigit>> &product_collectionf);
73 
74 
75  // Gets the WIRE ID of the channel. This wire id can be then passed
76  // to the Lariat geometry.
77  //raw::ChannelID_t get_wire_id(const sbnddaq::NevisTPCHeader *header, uint16_t nevis_channel_id);
78 
79  // whether the given nevis readout channel is mapped to a wire
80  //bool is_mapped_channel(const sbnddaq::NevisTPCHeader *header, uint16_t nevis_channel_id);
81 
82  art::InputTag _tag;
84  // keeping track of incrementing numbers
85  // commented out while unused
86  //uint32_t _last_event_number;
87  //uint32_t _last_trig_frame_number;
88 };
89 
90 
91 DEFINE_ART_MODULE(daq::DaqDecoderIcarusPMTold)
92 
93 DaqDecoderIcarusPMTold::DaqDecoderIcarusPMTold(fhicl::ParameterSet const & param):
94  art::EDProducer{param},
95  _tag(param.get<art::InputTag>("FragmentsLabel", "daq:CAENV1730")),
96  _config(param)//,
97  //_last_event_number(0),
98  //_last_trig_frame_number(0)
99 {
100 
101  // produce stuff
102  produces<std::vector<raw::OpDetWaveform>>();
103  // if (_config.produce_header) {
104  // produces<std::vector<tpcAnalysis::HeaderData>>();
105  // }
106 }
107 
108 DaqDecoderIcarusPMTold::Config::Config(fhicl::ParameterSet const & param)
109 {
110  // amount of time to wait in between processing events
111  // useful for debugging redis
112  double wait_time = param.get<double>("wait_time", -1 /* units of seconds */);
113  wait_sec = (int) wait_time;
114  wait_usec = (int) (wait_time / 1000000.);
115  // whether to calcualte the pedestal (and set it in SetPedestal())
116  baseline_calc = param.get<bool>("baseline_calc", false);
117  // whether to put headerinfo in the art root file
118  produce_header = param.get<bool>("produce_header", false);
119  // how many adc values to skip in mode/pedestal finding
120  n_mode_skip = param.get<unsigned>("n_mode_skip", 1);
121  // whether to subtract pedestal
122  subtract_pedestal = param.get<bool>("subtract_pedestal", false);
123 
124  // icarus readout window length
125  timesize = param.get<unsigned>("timesize", 1);
126 
127  // icarus tick length (for timestamp)
128  // should be 1/(2.5MHz) = 0.4mus
129  frame_to_dt = param.get<double>("frame_to_dt", 1);
130 
131  // number of channels in each slot
132  channel_per_slot = param.get<unsigned>("channel_per_slot", 0);
133  // index of 0th slot
134  min_slot_no = param.get<unsigned>("min_slot_no", 0);
135 }
136 
137 void DaqDecoderIcarusPMTold::produce(art::Event & event)
138 {
139  if (_config.wait_sec >= 0)
140  {
142  }
143  //auto const& daq_handle = event.getValidHandle<artdaq::Fragments>(_tag);
144 
145  // storage for waveform
146  std::unique_ptr<std::vector<raw::OpDetWaveform>> product_collection(new std::vector<raw::OpDetWaveform>());
147  // storage for header info
148  // std::unique_ptr<std::vector<tpcAnalysis::HeaderData>> header_collection(new std::vector<tpcAnalysis::HeaderData>);
149 
150  /************************************************************************************************/
151  art::Handle< std::vector<artdaq::Fragment> > rawFragHandle;
152  event.getByLabel(_tag, rawFragHandle);
153 
154  if (rawFragHandle.isValid()) {
155 
156  std::cout << "######################################################################\n";
157  std::cout << "Run " << event.run() << ", subrun " << event.subRun() << std::endl;
158 
159  for (size_t idx = 0; idx < rawFragHandle->size(); ++idx) /*loop over the fragments*/
160  {
161  //--use this fragment as a reference to the same data
162  const auto& frag((*rawFragHandle)[idx]);
163  sbndaq::CAENV1730Fragment bb(frag);
164  auto const* md = bb.Metadata();
165  sbndaq::CAENV1730Event const* event_ptr = bb.Event();
166  sbndaq::CAENV1730EventHeader header = event_ptr->Header;
167 
168  std::cout << "\tFragment ID: " << frag.fragmentID() << ", type: " << frag.typeString() << ", type: " << frag.type() << ", boardID: " << header.boardID << ", msk lo: " << header.channelMask_lo << ", hi: " << header.channelMask_hi << std::endl;
169  std::cout << "\tFrom header, event counter is " << header.eventCounter << "\n";
170  std::cout << "\tFrom header, triggerTimeTag is " << header.triggerTimeTag << "\n";
171  std::vector< std::vector<uint16_t> > fWvfmsVec;
172  size_t nChannels = md->nChannels;
173  std::cout <<"\tFrom header , no of channel is " << nChannels << "\n";
174 
175  uint32_t ev_size_quad_bytes = header.eventSize;
176  // std::cout << "Event size in quad bytes is: " << ev_size_quad_bytes << "\n";
177  uint32_t evt_header_size_quad_bytes = sizeof(sbndaq::CAENV1730EventHeader)/sizeof(uint32_t);
178  uint32_t data_size_double_bytes = 2*(ev_size_quad_bytes - evt_header_size_quad_bytes);
179  uint32_t wfm_length = data_size_double_bytes/nChannels;
180 
181  //--note, needs to take into account channel mask
182  // std::cout << "Channel waveform length = " << wfm_length << "\n";
183 
184  const uint16_t* data_begin = reinterpret_cast<const uint16_t*>(frag.dataBeginBytes()
185  + sizeof(sbndaq::CAENV1730EventHeader));
186 
187  const uint16_t* value_ptr = data_begin;
188  size_t ch_offset = 0;
189  uint16_t value;
190 
191  // loop over channels
192  for (size_t i_ch=0; i_ch<nChannels; ++i_ch)
193  {
194  //fWvfmsVec[i_ch].resize(wfm_length);
195  ch_offset = i_ch * wfm_length;
196 
197  raw::OpDetWaveform my_wf(0.00, i_ch, wfm_length);
198  my_wf.resize(wfm_length);
199  // Loop over waveform
200 
201  for(size_t i_t=0; i_t<wfm_length; ++i_t)
202  {
203  //fTicksVec[i_t] = t0*Ttt_DownSamp + i_t; /*timestamps, event level*/
204  value_ptr = data_begin + ch_offset + i_t; /*pointer arithmetic*/
205  //value_ptr = (i_t%2 == 0) ? (index+1) : (index-1);
206  value = *(value_ptr);
207  my_wf[i_t] = value;
208  //std::cout<<"Value is" << value << "and" << my_wf[i_t] << "\n";
209  //if (i_ch == 0 && fEvent == 0) h_wvfm_ev0_ch0->SetBinContent(i_t,value);
210  //fWvfmsVec[i_ch][i_t] = value;
211  } //--end loop samples
212 
213  product_collection->push_back(my_wf);
214  }// end loop over channels
215  // std::cout<<"product collection"<<product_collection->back().size()<<"\n";
216  } // end loop over fragments
217  }
218  event.put(std::move(product_collection));
219 }
220 
221 
222 /*
223 bool daq::DaqDecoderIcarusPMTold::is_mapped_channel(const sbnddaq::NevisTPCHeader *header, uint16_t nevis_channel_id) {
224  // TODO: make better
225  return true;
226 }
227 
228 raw::ChannelID_t daq::DaqDecoderIcarusPMTold::get_wire_id(const sbnddaq::NevisTPCHeader *header, uint16_t nevis_channel_id) {
229  // TODO: make better
230  return (header->getSlot() - _config.min_slot_no) * _config.channel_per_slot + nevis_channel_id;
231 }
232 */
233 void daq::DaqDecoderIcarusPMTold::process_fragment(art::Event &event, const artdaq::Fragment &frag, std::unique_ptr<std::vector<raw::RawDigit>> &product_collection)
234 {
235  // convert fragment to Nevis fragment
236  icarus::PhysCrateFragment fragment(frag);
237  std::cout << " n boards " << fragment.nBoards() << std::endl;
238  //int channel_count=0;
239 
240  for(size_t i_b=0; i_b < fragment.nBoards(); i_b++)
241  {
242  //A2795DataBlock const& block_data = *(crate_data.BoardDataBlock(i_b));
243 
244  for(size_t i_ch=0; i_ch < fragment.nChannelsPerBoard(); ++i_ch)
245  {
246  //raw::ChannelID_t channel_num = (i_ch & 0xff ) + (i_b << 8);
247  raw::ChannelID_t channel_num = i_ch+i_b*64;
248  raw::RawDigit::ADCvector_t wvfm(fragment.nSamplesPerChannel());
249 
250  for(size_t i_t=0; i_t < fragment.nSamplesPerChannel(); ++i_t)
251  {
252  wvfm[i_t] = fragment.adc_val(i_b,i_ch,i_t);
253  // if(channel_num==1855) std::cout << " sample " << i_t << " wave " << wvfm[i_t] << std::endl;
254  }
255  // product_collection->emplace_back(channel_count++,fragment.nSamplesPerChannel(),wvfm);
256  product_collection->emplace_back(channel_num,fragment.nSamplesPerChannel(),wvfm);
257  //std::cout << " channel " << channel_num << " waveform size " << fragment.nSamplesPerChannel() << std::endl;
258 
259  }//loop over channels
260 
261  }//loop over boards
262  std::cout << "Total number of channels added is " << product_collection->size() << std::endl;
263 }
264 
265 
266 // Computes the checksum, given a nevis tpc header
267 // Ideally this would be in sbnddaq-datatypes, but it's not and I can't
268 // make changes to it, so put it here for now
269 //
270 // Also note that this only works for uncompressed data
271 /*
272 uint32_t daq::DaqDecoderIcarusPMTold::compute_checksum(icarus::PhysCrateFragment &fragment) {
273  uint32_t checksum = 0;
274 
275  const sbnddaq::NevisTPC_ADC_t* data_ptr = fragment.data();
276  // RETURN VALUE OF getADCWordCount IS OFF BY 1
277  size_t n_words = fragment.header()->getADCWordCount() + 1;
278 
279  for (size_t word_ind = 0; word_ind < n_words; word_ind++) {
280  const sbnddaq::NevisTPC_ADC_t* word_ptr = data_ptr + word_ind;
281  checksum += *word_ptr;
282  }
283  // only first 6 bytes of checksum are used
284  return checksum & 0xFFFFFF;
285 
286 }
287 */
288 
289 } // end of namespace
290 
291 
292 
293 
void process_fragment(art::Event &event, const artdaq::Fragment &frag, std::unique_ptr< std::vector< raw::RawDigit >> &product_collectionf)
pdgs p
Definition: selectors.fcl:22
std::vector< short > ADCvector_t
Type representing a (compressed) vector of ADC counts.
Definition: RawDigit.h:73
Definition of basic raw digits.
microsecond microseconds
Alias for common language habits.
Definition: spacetime.h:122
second seconds
Alias for common language habits.
Definition: spacetime.h:88
DaqDecoderIcarusPMTold(fhicl::ParameterSet const &p)
void produce(art::Event &e) override
do i e
temporary value
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:28
BEGIN_PROLOG could also be cout