NovaDDTHitProducer_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: NovaDDTHitProducer
3 // Module Type: producer
4 // File: NovaDDTHitProducer_module.cc
5 //
6 // Generated at Tue May 8 11:50:49 2012 by Chris Green using artmod
7 // from art v1_00_12.
8 ////////////////////////////////////////////////////////////////////////
9 
14 #include "artdaq-core/Data/Fragment.hh"
15 
16 #include "DAQDataFormats/RawMicroSlice.h"
17 #include "DAQDataFormats/RawMilliBlock.h"
18 #include "DAQDataFormats/RawMilliBlockHeader.h"
19 #include "DAQDataFormats/RawMilliSlice.h"
20 #include "DAQDataFormats/RawNanoSlice.h"
21 #include "DAQChannelMap/DAQChannelMap.h"
22 
26 
30 
31 class NovaDDTHitProducer;
32 
34 public:
35  explicit NovaDDTHitProducer(fhicl::ParameterSet const & p);
36  virtual ~NovaDDTHitProducer();
37 
38  virtual void produce(art::Event & e);
39 
40 private:
41  size_t populateMilliBlock(void const * image, RawMilliBlock & mb, novaddt::EventHeader* evt_header);
44 
46 
47  bool offline_;
48 };
49 
50 
52  :
53  raw_label_(p.get<std::string>("raw_label"))
54  , offline_(p.get<bool>("offline_mode", false))
55 {
56  produces<std::vector<novaddt::DAQHit>>("AllHits");
57  produces<novaddt::EventHeader>("DDTdaq");
58  // produces<std::vector<novaddt::DAQHit>>("MCSHits");
59 #ifdef NEED_MILLIBLOCK_IN_EVENT
60  produces<RawMilliBlock>();
61 #endif
62 }
63 
65 {
66 }
67 
69 (void const * image, RawMilliBlock & mb, novaddt::EventHeader* evt_header)
70 {
71  // This code follows the code in Ron R's getMilliBlock, but omits the part
72  // where the data is read out of the shared memory. Instead, the data is
73  // assumed to be here in *image.
74  size_t total_bytes = 0;
75  std::vector<RawMilliSlice> rms_vec;
77  mb.set_ovrwrt(false);
78  RawMilliBlockHeader const * rmbhp =
79  reinterpret_cast<RawMilliBlockHeader const *>(image);
80  RawMilliBlockHeader const & rmbh(*rmbhp);
81  assert(rmbh.millislice_count > 0);
82  rms_vec.reserve(rmbh.millislice_count);
83  if (rmbh.flags.overflowCorruption == 1) {
84  mb.set_ovrwrt(true);
85  return 0;
86  }
87 
88  void * msdataptr = const_cast<void *>(reinterpret_cast<void const *>(rmbhp + 1));
89  uint32_t retrieved_millislice = 0;
90  for (; retrieved_millislice < rmbh.millislice_count; ++retrieved_millislice) {
91  rms_vec.push_back(rms_tmp);
92  msdataptr = rms_vec.at(retrieved_millislice).readData(msdataptr);
93  // the readData method figures how much data to copy, puts it
94  // into the millislice, and returns the pointer advanced to the end
95  // of that data.
96  total_bytes += rms_vec.at(retrieved_millislice).sizeofdata() * sizeof(uint32_t);
97  }
98  assert(retrieved_millislice > 0);
99  mb.set(rmbh.seqNum, rmbh.timeStart, rmbh.timeEnd, rmbh.flags.truncated);
100 
101  // This code will add the EventHeader to the live data stream events as well
102  evt_header->totalBytes = total_bytes;
103  evt_header->eventNumber = rmbh.seqNum;
104  evt_header->timeStart = rmbh.timeStart;
105  evt_header->missingData = rmbh.flags.incomplete;
106  evt_header->datablockCount = rmbh.millislice_count;
107 
108  mb.slices.swap(rms_vec); // swap vectors to get data into the mb.
109 
110  return total_bytes;
111 } // populateMilliBlock
112 
114 {
115  // If we want to test offline the hits should already exist so we can just return here
116  if (offline_) return;
117 
118  typedef novaddt::DAQHit Hit;
119  // Obtain the fragments from the event.
121  e.getByLabel(raw_label_, handle);
122  // Sanity check.
123  assert(handle->size() == 1);
124  // Now initialize a RawMilliBlock with the fragment payload.
125  // Not quite -- do the work to do so, but the data on the heap has to be
126  // just the HitData, and we don't want to do two copies. So we interrupt
127  // the work at a key point, to make and push_back DAQHits.
128  std::unique_ptr<RawMilliBlock> mbp(new RawMilliBlock);
129  novaddt::EventHeader evt_header;
130 
131  size_t total_bytes =
132  populateMilliBlock(&*(handle->front().dataBegin()), *mbp, &evt_header);
133  std::unique_ptr<std::vector<Hit>> hits(new std::vector<Hit>);
134  std::unique_ptr<novaddt::EventHeader > mbhead(new novaddt::EventHeader(evt_header));
135 
136  // std::unique_ptr<std::vector<Hit>> MCShits(new std::vector<Hit>);
137 
138 
139  size_t const nanoSliceSize = 12; // Each nano-slice is *at least* 12 bytes
140  hits->reserve(total_bytes / nanoSliceSize); // definitely enough.
141  // Now code taken from A. Norman's GetDAQHits-SHM
142  // First Loop over the MilliBlock to get the millislices
143 
144  // for (auto & millislice : mbp->slices) {
145  for (unsigned n = 0; n != mbp->slices.size(); ++n)
146  {
147  // Now for each millislice we loop over the microslices
148  // I would LOVE to do this without the weird floating micro slice but...
149  for (uint32_t imicro = 0; mbp->slices.at(n).setFloatingMicroSlice(imicro); ++imicro) {
150  RawMicroSlice * theSlice = mbp->slices.at(n).getFloatingMicroSlice();
151  for (uint32_t inano = 0; inano < theSlice->getNumNanoSlices(); ++inano) {
152  theSlice->setFloatingNanoSlice(inano);
153  //new way
154  daqdataformats::RawMilliSlice* theMilli = &mbp->slices.at(n);
155  daqdataformats::RawNanoSlice* theNano = theSlice->getFloatingNanoSlice();
156  int detID = theMilli->getHeader()->getDetId();
157  wpr->setup(theSlice, theNano);
158  hits->emplace_back( detID,
160  ->encodeDChan(detID,
161  theMilli->getHeader()->getDiblockId(),
162  theMilli->getHeader()->getDCMId(),
163  theNano->getHeader()->getFEBId(),
164  theNano->getHeader()->getPixelAddr()),
165  wpr->getADC(),
166  wpr->getTDC() );
167 
168  // if (passes_MCS_filter(theNano))
169  // {
170  // MCShits->emplace_back( detID,
171  // daqchannelmap::DAQChannelMap::getInstance(detID)
172  // ->encodeDChan(detID,
173  // theMilli->getHeader()->getDiblockId(),
174  // theMilli->getHeader()->getDCMId(),
175  // theNano->getHeader()->getFEBId(),
176  // theNano->getHeader()->getPixelAddr()),
177  // wpr->getADC(),
178  // wpr->getTDC() );
179  // }
180 
181  //old way
182  //hits->emplace_back(&mbp->slices.at(n),
183  // theSlice->getFloatingNanoSlice());
184  } // Loop over microslices (imicro, as ranged using setFloatingNanoSlice)
185  } // Loop over microslices (inano, as ranged using setFloatingMicroSlice)
186  } // Loop over millislices {millislice ranged over mb.slices}
187  e.put(std::move(hits),"AllHits");
188  e.put(std::move(mbhead),"DDTdaq");
189  // e.put(std::move(MCShits),"MCSHits");
190 #ifdef NEED_MILLIBLOCK_IN_EVENT
191  e.put(std::move(mbp));
192 #endif
193 }
195 {
196  //check that multipoint can be used
197  const uint32_t version = fNano->getHeader()->getVersion();
199  const unsigned int nSamples = conv.getNSamples(version);
200  const unsigned int nPretrig = conv.getNPretriggeredSamples(version);
201 
202  //MCS filter will not work under this case, use normal way:
203  if (nPretrig<3 || nSamples <= nPretrig || version==0) return false;
204 
205  //I require all the ADC values monotonously increase before trigger:
206  for (unsigned i = 1; i!= nPretrig; ++i) {
207  int16_t adc_pre = fNano->getValue(i-1);
208  int16_t adc_cur = fNano->getValue(i);
209  if (adc_pre > adc_cur) return false;
210  }
211 
212  return true;
213 
214 }
215 
IMPLEMENT_MAIN_STANDARD IMPLEMENT_MAIN_setBufferSource daqdataformats::RawNanoSliceHeader * getHeader() const
Get the NanoSlice header pointer.
Definition: RawNanoSlice.h:57
const char * p
Definition: xmltok.h:285
size_t populateMilliBlock(void const *image, RawMilliBlock &mb, novaddt::EventHeader *evt_header)
uint32_t getNumNanoSlices() const
Get current Hit Probability (for a microslice generation)
DEFINE_ART_MODULE(TestTMapFile)
uint32_t datablockCount
Definition: EventHeader.h:26
ProductID put(std::unique_ptr< PROD > &&product)
Definition: Event.h:102
virtual void produce(art::Event &e)
void hits()
Definition: readHits.C:15
bool setFloatingNanoSlice(const uint32_t inano) const
Set the SIM flag.
daqdataformats::RawMilliSliceHeader * getHeader() const
Definition: RawMilliSlice.h:47
bool passes_MCS_filter(daqdataformats::RawNanoSlice *fNano) const
uint32_t getNSamples(const version_t ver) const
Get the number of samples.
uint32_t getNPretriggeredSamples(const version_t ver) const
Get number of pretriggered samples.
static DAQChannelMap * getInstance(int detID)
NovaDDTHitProducer(fhicl::ParameterSet const &p)
std::vector< daqdataformats::RawMilliSlice > slices
Definition: RawMilliBlock.h:35
void setup(daqdataformats::RawMicroSlice *theMicro, daqdataformats::RawNanoSlice *theNano)
const XML_Char * version
Definition: expat.h:187
Service for extracting timing and pulse height information from traces with multipoint readout...
art::ServiceHandle< novaddt::WaveformProcessor > wpr
::xsd::cxx::tree::string< char, simple_type > string
Definition: Database.h:154
Class to hold the MicroSlice data.
Definition: RawMicroSlice.h:48
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
Definition: DataViewImpl.h:344
void set_ovrwrt(bool ovrwrt)
Definition: RawMilliBlock.h:33
assert(nhit_max >=nhit_nbins)
struct RawMilliBlockHeader::@12 flags
Float_t e
Definition: plot.C:35
int set(uint32_t sn, uint64_t start, uint64_t end, bool ovrflw)
Definition: RawMilliBlock.h:26
daqdataformats::RawNanoSlice * getFloatingNanoSlice() const
Get the MicroSlice Timing Marker.