HDColdboxDataInterface_tool.cc
Go to the documentation of this file.
2 
3 #include <hdf5.h>
4 #include <iostream>
5 #include <list>
6 #include <set>
7 #include <sstream>
8 #include <cstring>
9 #include <string>
10 #include "TMath.h"
11 #include "TString.h"
12 
14 
18 #include "detdataformats/wib/WIBFrame.hpp"
20 
21 
22 
24  : fForceOpen(p.get<bool>("ForceOpen", false)),
25  fFileInfoLabel(p.get<std::string>("FileInfoLabel", "daq")),
26  fMaxChan(p.get<int>("MaxChan",1000000)),
27  fDefaultCrate(p.get<unsigned int>("DefaultCrate", 3)),
28  fDebugLevel(p.get<int>("DebugLevel",0))
29 {
30 }
31 
32 
34  std::string inputLabel,
35  std::vector<raw::RawDigit> &raw_digits,
36  std::vector<raw::RDTimeStamp> &rd_timestamps,
37  std::vector<raw::RDStatus> &rdstatuses) {
38  return 0;
39 }
40 
41 
43  std::vector<raw::RawDigit> &raw_digits,
44  std::vector<raw::RDTimeStamp> &rd_timestamps,
45  std::vector<raw::RDStatus> &rdstatuses,
46  std::vector<int> &apalist)
47 {
48  using namespace dune::HDF5Utils;
49  auto infoHandle = evt.getHandle<raw::DUNEHDF5FileInfo>(fFileInfoLabel);
50  const std::string & toplevel_groupname = infoHandle->GetEventGroupName();
51  const std::string & file_name = infoHandle->GetFileName();
52  hid_t file_id = infoHandle->GetHDF5FileHandle();
53 
54  if (fDebugLevel > 0)
55  {
56  std::cout << "HDColdboxDataInterface : " << "HDF5 FileName: " << file_name << std::endl;
57  std::cout << "HDColdboxDataInterface :" << "Top-Level Group Name: " << toplevel_groupname << std::endl;
58  }
59 
60  // If the fcl file said to force open the file (i.e. because one is just running DataPrep), then open
61  // but only if we are on a new file -- identified by if the handle stored in the event is different.
62  if (fForceOpen && (file_id != fPrevStoredHandle))
63  {
64  fHDFFile = H5Fopen(file_name.data(), H5F_ACC_RDONLY, H5P_DEFAULT);
65  } // If the handle is the same, fHDFFile won't change
66  else if (!fForceOpen)
67  {
68  fHDFFile = file_id;
69  }
70  fPrevStoredHandle = file_id;
71 
72  hid_t the_group = getGroupFromPath(fHDFFile, toplevel_groupname);
73 
74  if (fDebugLevel > 0)
75  {
76  std::cout << "HDColdboxDataInterface : " << "Retrieving Data for " << apalist.size() << " APAs " << std::endl;
77  }
78 
79  // NOTE: The "apalist" that DataPrep hands to the method is always of size 1.
80  // Also "apalist" should technically hand you the current APA No. we are looking at but there is exception.
81  // CAUTION: This is only and only for HDColdBox.The reason is VDColdBox has only one APA/CRU.
82  for (const int & i : apalist)
83  {
84  int apano = i;
85  if (fDebugLevel > 0)
86  {
87  std::cout << "HDColdboxDataInterface :" << "apano: " << i << std::endl;
88  }
89 
90  getFragmentsForEvent(the_group, raw_digits, rd_timestamps, apano, fMaxChan);
91 
92  //Currently putting in dummy values for the RD Statuses
93  rdstatuses.clear();
94  rdstatuses.emplace_back(false, false, 0);
95  }
96 
97  return 0;
98 }
99 
100 
101 // get data for a specific label, but only return those raw digits that correspond to APA's on the list
103  std::string inputLabel,
104  std::vector<raw::RawDigit> &raw_digits,
105  std::vector<raw::RDTimeStamp> &rd_timestamps,
106  std::vector<raw::RDStatus> &rdstatuses,
107  std::vector<int> &apalist)
108 {
109  return 0;
110 }
111 
112 
113 // This is designed to read 1APA/CRU, only for VDColdBox data. The function uses "apano", handed by DataPrep,
114 // as an argument.
115 void HDColdboxDataInterface::getFragmentsForEvent(hid_t the_group, RawDigits& raw_digits, RDTimeStamps &timestamps,
116  int apano, unsigned int maxchan)
117 {
118  using namespace dune::HDF5Utils;
119  using dunedaq::detdataformats::wib::WIBFrame;
120  using dunedaq::detdataformats::wib::WIBHeader;
121 
123 
124  std::deque<std::string> det_types
125  = getMidLevelGroupNames(the_group);
126 
127  for (const auto & det : det_types)
128  {
129  if (det != "TPC") continue;
130  if (fDebugLevel > 0)
131  {
132  std::cout << "HDColdboxDataInterface :" << "Detector type: " << det << std::endl;
133  }
134  hid_t geoGroup = getGroupFromPath(the_group, det);
135  std::deque<std::string> apaNames
136  = getMidLevelGroupNames(geoGroup);
137 
138  if (fDebugLevel > 0)
139  {
140  std::cout << "HDColdboxDataInterface :" << "Size of apaNames: " << apaNames.size() << std::endl;
141  std::cout << "HDColdboxDataInterface :" << "apaNames[apano]: " << apaNames[apano-1] << std::endl;
142  }
143  // apaNames is a vector whose elements start at [0].
144  hid_t linkGroup = getGroupFromPath(geoGroup, apaNames[apano-1]);
145  std::deque<std::string> linkNames = getMidLevelGroupNames(linkGroup);
146 
147  for (const auto & t : linkNames)
148  {
149  hid_t dataset = H5Dopen(linkGroup, t.data(), H5P_DEFAULT);
150  hsize_t ds_size = H5Dget_storage_size(dataset);
151  if (ds_size <= sizeof(FragmentHeader)) continue; //Too small
152 
153  std::vector<char> ds_data(ds_size);
154  H5Dread(dataset, H5T_STD_I8LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, ds_data.data());
155  H5Dclose(dataset);
156 
157  //Each fragment is a collection of WIB Frames
158  Fragment frag(&ds_data[0], Fragment::BufferAdoptionMode::kReadOnlyMode);
159  size_t n_frames = (ds_size - sizeof(FragmentHeader))/sizeof(WIBFrame);
160  if (fDebugLevel > 0)
161  {
162  std::cout << "HDColdboxDataInterface :" << "n_frames : " << n_frames << std::endl;
163  }
164  std::vector<raw::RawDigit::ADCvector_t> adc_vectors(256);
165  unsigned int slot = 0, fiber = 0;
166 
167  for (size_t i = 0; i < n_frames; ++i)
168  {
169  auto frame = reinterpret_cast<WIBFrame*>(static_cast<uint8_t*>(frag.get_data()) + i*sizeof(WIBFrame));
170  if (fDebugLevel > 0)
171  {
172  std::cout << "HDColdboxDataInterface :" << "frame : " << frame << std::endl;
173  }
174  for (size_t j = 0; j < adc_vectors.size(); ++j)
175  {
176  adc_vectors[j].push_back(frame->get_channel(j));
177  }
178 
179  if (i == 0)
180  {
181  slot = frame->get_wib_header()->slot_no;
182  fiber = frame->get_wib_header()->fiber_no;
183  }
184  }
185  if (fDebugLevel > 0)
186  {
187  std::cout << "HDColdboxDataInterface :" << "slot, fiber: " << slot << ", " << fiber << std::endl;
188  }
189  for (size_t iChan = 0; iChan < 256; ++iChan)
190  {
191  const raw::RawDigit::ADCvector_t & v_adc = adc_vectors[iChan];
192  if (fDebugLevel > 0)
193  {
194  std::cout << "HDColdboxDataInterface : " << "Channel: " << iChan << " N ticks: " << v_adc.size() << " Timestamp: " << frag.get_trigger_timestamp() << std::endl;
195  }
196  // handle 256 channels on two fibers -- use the channel map that assumes 128 chans per fiber (=FEMB)
197  // Channels 0-127 are on "fiberloc" 1 and channels 128-255 are on fiberloc 2.
198  // Use separate variables, for example, "fiberloc" and "chloc" to keep track of the actual channel and fiber and to accommodate future needs.
199  unsigned int fiberloc = 0;
200  if (fiber == 1)
201  {
202  fiberloc = 1;
203  }
204 
205  else if (fiber == 2)
206  {
207  fiberloc = 3;
208  }
209  else
210  {
211  MF_LOG_WARNING("_process_FELIX_AUX:") << " Fiber number " << (int) fiber << " is expected to be 1 or 2 -- revisit logic";
212  fiberloc = 1;
213  }
214 
215  unsigned int chloc = iChan;
216  if (chloc > 127)
217  {
218  chloc -= 128;
219  fiberloc++;
220  }
221 
222  //In the channel map call, the crate number is ill-defined for the HD coldbox, as there is only one crate, and the dataprep and event display have room for six. Pick Default Crate number 3 to send in to the call
223  unsigned int offline_chan = channelMap->GetOfflineNumberFromDetectorElements(fDefaultCrate, slot, fiberloc, chloc, dune::PdspChannelMapService::kFELIX);
224  if (fDebugLevel > 0)
225  {
226  std::cout << "HDColdboxDataInterface : " << "iChan : " << iChan << std::endl;
227  std::cout << "HDColdboxDataInterface : " << "offline_chan : " << offline_chan << std::endl;
228  }
229  if (offline_chan < 0) continue;
230  if (offline_chan > maxchan) continue;
231  raw::RDTimeStamp rd_ts(frag.get_trigger_timestamp(), offline_chan);
232  timestamps.push_back(rd_ts);
233 
234  float median = 0., sigma = 0.;
235  getMedianSigma(v_adc, median, sigma);
236  raw::RawDigit rd(offline_chan, v_adc.size(), v_adc);
237  rd.SetPedestal(median, sigma);
238  raw_digits.push_back(rd);
239  }
240 
241  }
242  H5Gclose(linkGroup);
243  }
244 
245 }
246 
247 
249  const raw::RawDigit::ADCvector_t &v_adc, float &median,
250  float &sigma) {
251  size_t asiz = v_adc.size();
252  int imed=0;
253  if (asiz == 0) {
254  median = 0;
255  sigma = 0;
256  }
257  else {
258  // the RMS includes tails from bad samples and signals and may not be the best RMS calc.
259 
260  imed = TMath::Median(asiz,v_adc.data()) + 0.01; // add an offset to make sure the floor gets the right integer
261  median = imed;
262  sigma = TMath::RMS(asiz,v_adc.data());
263 
264  // add in a correction suggested by David Adams, May 6, 2019
265 
266  size_t s1 = 0;
267  size_t sm = 0;
268  for (size_t i = 0; i < asiz; ++i) {
269  if (v_adc.at(i) < imed) s1++;
270  if (v_adc.at(i) == imed) sm++;
271  }
272  if (sm > 0) {
273  float mcorr = (-0.5 + (0.5*(float) asiz - (float) s1)/ ((float) sm) );
274  if (fDebugLevel > 0)
275  {
276  if (std::abs(mcorr)>1.0) std::cout << "mcorr: " << mcorr << std::endl;
277  }
278  median += mcorr;
279  }
280  }
281 
282 }
283 
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:42
Collection of charge vs time digitized from a single readout channel.
Definition: RawDigit.h:69
int retrieveDataForSpecifiedAPAs(art::Event &evt, std::vector< raw::RawDigit > &raw_digits, std::vector< raw::RDTimeStamp > &rd_timestamps, std::vector< raw::RDStatus > &rdstatuses, std::vector< int > &apalist)
Handle< PROD > getHandle(SelectorBase const &) const
Definition: DataViewImpl.h:382
std::string string
Definition: nybbler.cc:12
std::vector< short > ADCvector_t
Type representing a (compressed) vector of ADC counts.
Definition: RawDigit.h:73
std::vector< raw::RawDigit > RawDigits
Definition: HDF5Utils.h:23
STL namespace.
HDColdboxDataInterface(fhicl::ParameterSet const &ps)
QCString file_name
unsigned int GetOfflineNumberFromDetectorElements(unsigned int crate, unsigned int slot, unsigned int fiber, unsigned int fembchannel, FelixOrRCE frswitch)
void getMedianSigma(const raw::RawDigit::ADCvector_t &v_adc, float &median, float &sigma)
std::vector< raw::RDTimeStamp > RDTimeStamps
Definition: HDF5Utils.h:24
std::list< std::string > getMidLevelGroupNames(hid_t grp)
T abs(T value)
int retrieveData(art::Event &evt, std::string inputlabel, std::vector< raw::RawDigit > &raw_digits, std::vector< raw::RDTimeStamp > &rd_timestamps, std::vector< raw::RDStatus > &rdstatuses)
p
Definition: test.py:223
void getFragmentsForEvent(hid_t the_group, RawDigits &raw_digits, RDTimeStamps &timestamps, int apano, unsigned int maxchan)
void SetPedestal(float ped, float sigma=1.)
Set pedestal and its RMS (the latter is 0 by default)
Definition: RawDigit.cxx:68
TCEvent evt
Definition: DataStructs.cxx:7
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
#define MF_LOG_WARNING(category)
int bool
Definition: qglobal.h:345
int retrieveDataAPAListWithLabels(art::Event &evt, std::string inputlabel, std::vector< raw::RawDigit > &raw_digits, std::vector< raw::RDTimeStamp > &rd_timestamps, std::vector< raw::RDStatus > &rdstatuses, std::vector< int > &apalist)
hid_t getGroupFromPath(HDFFileInfoPtr &hdfFileInfoPtr, const std::string &path)
double median(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:26
QTextStream & endl(QTextStream &s)