VDColdboxDataInterface_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 //The file handle is from the raw::DUNEHDF5FileInfo data product that the source puts into the event. Art's getHandle<type> is usedto retrieve a data product from the event.
23 // The idea is hand this function an art event and it will return you APA/CRU info FOR THE VDColdbox.
24 
26 {
27 
28  using namespace dune::HDF5Utils;
29  auto infoHandle = evt.getHandle <raw::DUNEHDF5FileInfo> ("daq");
30  std::cout << "Got infos? " << infoHandle << std::endl;
31 
32  const std::string & toplevel_groupname = infoHandle->GetEventGroupName();
33  const std::string & file_name = infoHandle->GetFileName();
34  hid_t file_id = infoHandle->GetHDF5FileHandle();
35 
36  std::cout << "Top-Level Group Name: " << toplevel_groupname << std::endl;
37  std::cout << "HDF5 FileName: " << file_name << std::endl;
38 
39  // now look inside those "Top-Level Group Name" for "Detector type".
40  hid_t requestedGroup = getGroupFromPath(file_id, toplevel_groupname);
41 
42  std::deque<std::string> detectorTypeNames = getMidLevelGroupNames(requestedGroup);
43 
44  for (auto& detectorTypeName : detectorTypeNames)
45  {
46  if (detectorTypeName == "TPC" && detectorTypeName != "TriggerRecordHeader")
47  {
48  std::cout << " Detector type: " << detectorTypeName << std::endl;
49  std::string geoPath = toplevel_groupname + "/" + detectorTypeName;
50  hid_t geoGroup = getGroupFromPath(file_id,geoPath);
51  std::deque<std::string> apaNames = getMidLevelGroupNames(geoGroup);
52 
53  // loop over APAs
54  for (auto& apaName : apaNames)
55  {
56  std::string apaGroupPath = geoPath + "/" + apaName;
57  std::cout << " Geo path: " << apaGroupPath << std::endl;
58  hid_t linkGroup = getGroupFromPath(file_id,apaGroupPath);
59  std::deque<std::string> linkNames = getMidLevelGroupNames(linkGroup);
60 
61  // loop over Links
62  for (auto& linkName : linkNames)
63  {
64  std::string dataSetPath = apaGroupPath + "/" + linkName;
65  std::cout << " Data Set Path: " << dataSetPath << std::endl;
66  hid_t datasetid = H5Dopen(linkGroup,linkName.data(),H5P_DEFAULT);
67  hsize_t ds_size = H5Dget_storage_size(datasetid);
68  std::cout << " Data Set Size (bytes): " << ds_size << std::endl;
69 
70  if (ds_size < 80) continue;
71 
72  size_t narray = ds_size / sizeof(char);
73  size_t rdr = ds_size % sizeof(char);
74  if (rdr > 0 || narray == 0) narray++;
75  char *ds_data = new char[narray];
76  herr_t ecode = H5Dread(datasetid, H5T_STD_I8LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, ds_data);
77  int firstbyte = ds_data[0];
78  firstbyte &= 0xFF;
79  int lastbyte = ds_data[narray-1];
80  lastbyte &= 0xFF;
81 
82  std::cout << std::hex << " Retrieved data: ecode: " << ecode << " first byte: " << firstbyte
83  << " last byte: " << lastbyte << std::dec << std::endl;
84 
85 
86  int magic_word = 0;
87  memcpy(&magic_word,&ds_data[0],4);
88  std::cout << " Magic word: 0x" << std::hex << magic_word << std::dec << std::endl;
89 
90  int version = 0;
91  memcpy(&version, &ds_data[4],4);
92  std::cout << " Version: " << std::dec << version << std::dec << std::endl;
93 
94  uint64_t fragsize=0;
95  memcpy(&fragsize, &ds_data[8],8);
96  std::cout << " Frag Size: " << std::dec << fragsize << std::dec << std::endl;
97 
98  uint64_t trignum=0;
99  memcpy(&trignum, &ds_data[16],8);
100  std::cout << " Trig Num: " << std::dec << trignum << std::dec << std::endl;
101 
102  uint64_t trig_timestamp=0;
103  memcpy(&trig_timestamp, &ds_data[24],8);
104  std::cout << " Trig Timestamp: " << std::dec << trig_timestamp << std::dec << std::endl;
105 
106  uint64_t windowbeg=0;
107  memcpy(&windowbeg, &ds_data[32],8);
108  std::cout << " Window Begin: " << std::dec << windowbeg << std::dec << std::endl;
109 
110  uint64_t windowend=0;
111  memcpy(&windowend, &ds_data[40],8);
112  std::cout << " Window End: " << std::dec << windowend << std::dec << std::endl;
113 
114  int runno=0;
115  memcpy(&runno, &ds_data[48], 4);
116  std::cout << " Run Number: " << std::dec << runno << std::endl;
117 
118  int errbits=0;
119  memcpy(&errbits, &ds_data[52], 4);
120  std::cout << " Error bits: " << std::dec << errbits << std::endl;
121 
122  int fragtype=0;
123  memcpy(&fragtype, &ds_data[56], 4);
124  std::cout << " Fragment type: " << std::dec << fragtype << std::endl;
125 
126  int fragpadding=0;
127  memcpy(&fragtype, &ds_data[60], 4);
128  std::cout << " Fragment padding: " << std::dec << fragpadding << std::endl;
129 
130  int geoidversion=0;
131  memcpy(&geoidversion, &ds_data[64], 4);
132  std::cout << " GeoID version: " << std::dec << geoidversion << std::endl;
133 
134  unsigned short geoidtype;
135  memcpy(&geoidtype, &ds_data[70], 1);
136  std::cout << " GeoID type: " << geoidtype << std::endl;
137 
138  unsigned short geoidregion=0;
139  memcpy(&geoidregion, &ds_data[71], 1);
140  std::cout << " GeoID region: " << std::dec << geoidregion << std::endl;
141 
142  int geoidelement=0;
143  memcpy(&geoidelement, &ds_data[72], 4);
144  std::cout << " GeoID element: " << std::dec << geoidelement << std::endl;
145 
146  int geoidpadding=0;
147  memcpy(&geoidpadding, &ds_data[76], 4);
148  std::cout << " GeoID padding: " << std::dec << geoidpadding << std::endl;
149 
150  delete[] ds_data; // free up memory
151 
152  }
153  }
154  }
155  }
156 
157 }
158 
159 // Keep this here for now. This needs scrutiny regarding whether the input labels are fetching right values.
161  : fForceOpen(p.get<bool>("ForceOpen", false)),
162  fFileInfoLabel(p.get<std::string>("FileInfoLabel", "daq")),
163  fMaxChan(p.get<int>("MaxChan",1000000)) {
164 }
165 
166 
168  std::string inputLabel,
169  std::vector<raw::RawDigit> &raw_digits,
170  std::vector<raw::RDTimeStamp> &rd_timestamps,
171  std::vector<raw::RDStatus> &rdstatuses) {
172  return 0;
173 }
174 
175 
177  std::vector<raw::RawDigit> &raw_digits,
178  std::vector<raw::RDTimeStamp> &rd_timestamps,
179  std::vector<raw::RDStatus> &rdstatuses,
180  std::vector<int> &apalist)
181 {
182  using namespace dune::HDF5Utils;
183  auto infoHandle = evt.getHandle<raw::DUNEHDF5FileInfo>(fFileInfoLabel);
184  const std::string & toplevel_groupname = infoHandle->GetEventGroupName();
185  const std::string & file_name = infoHandle->GetFileName();
186  hid_t file_id = infoHandle->GetHDF5FileHandle();
187 
188  std::cout << "HDF5 FileName: " << file_name << std::endl;
189  std::cout << "Top-Level Group Name: " << toplevel_groupname << std::endl;
190 
191  //If the fcl file said to force open the file
192  //(i.e. because one is just running DataPrep), then open
193  //but only if we are on a new file -- identified by if the handle
194  //stored in the event is different
195  if (fForceOpen && (file_id != fPrevStoredHandle))
196  {
197  std::cout << "Opening" << std::endl;
198  fHDFFile = H5Fopen(file_name.data(), H5F_ACC_RDONLY, H5P_DEFAULT);
199  }//If the handle is the same, fHDFFile won't change
200  else if (!fForceOpen)
201  {
202  fHDFFile = file_id;
203  }
204  fPrevStoredHandle = file_id;
205 
206  hid_t the_group = getGroupFromPath(fHDFFile, toplevel_groupname);
207 
208  std::cout << "Retrieving Data for " << apalist.size() << " APA " << std::endl;
209 
210  // NOTE: The "apalist" that DataPrep hands to the method is always of size 1.
211  // Also "apalist" should technically hand you the current APA No. we are looking at but there is exception.
212  // CAUTION: This is only and only for VDColdBox.The reason is VDColdBox has only one APA/CRU.
213  for (const int & i : apalist)
214  {
215  int apano = i;
216  std::cout << "apano: " << i << std::endl;
217 
218  getFragmentsForEvent(the_group, raw_digits, rd_timestamps, apano, fMaxChan);
219 
220  //Currently putting in dummy values for the RD Statuses
221  rdstatuses.clear();
222  rdstatuses.emplace_back(false, false, 0);
223  }
224 
225  return 0;
226 }
227 
228 
229 // get data for a specific label, but only return those raw digits that correspond to APA's on the list
231  art::Event &evt,
232  std::string inputLabel,
233  std::vector<raw::RawDigit> &raw_digits,
234  std::vector<raw::RDTimeStamp> &rd_timestamps,
235  std::vector<raw::RDStatus> &rdstatuses,
236  std::vector<int> &apalist) {
237  return 0;
238 }
239 
240 
241 // This is designed to read 1APA/CRU, only for VDColdBox data. The function uses "apano", handed by DataPrep,
242 // as an argument.
244  hid_t the_group, RawDigits& raw_digits, RDTimeStamps &timestamps,
245  int apano, int maxchan) {
246 
247  using namespace dune::HDF5Utils;
248  using dunedaq::detdataformats::wib::WIBFrame;
249  using dunedaq::detdataformats::wib::WIBHeader;
250 
252 
253  std::deque<std::string> det_types
254  = getMidLevelGroupNames(the_group);
255 
256  for (const auto & det : det_types)
257  {
258  if (det != "TPC") continue;
259  //std::cout << " Detector type: " << det << std::endl;
260  hid_t geoGroup = getGroupFromPath(the_group, det);
261  std::deque<std::string> apaNames
262  = getMidLevelGroupNames(geoGroup);
263 
264  std::cout << "Size of apaNames: " << apaNames.size() << std::endl;
265  std::cout << "apaNames[apano]: " << apaNames[apano-1] << std::endl;
266 
267  // apaNames is a vector whose elements start at [0].
268  hid_t linkGroup = getGroupFromPath(geoGroup, apaNames[apano-1]);
269  std::deque<std::string> linkNames
270  = getMidLevelGroupNames(linkGroup);
271  for (const auto & t : linkNames)
272  {
273  hid_t dataset = H5Dopen(linkGroup, t.data(), H5P_DEFAULT);
274  hsize_t ds_size = H5Dget_storage_size(dataset);
275  if (ds_size <= sizeof(FragmentHeader)) continue; //Too small
276 
277  std::vector<char> ds_data(ds_size);
278  H5Dread(dataset, H5T_STD_I8LE, H5S_ALL, H5S_ALL, H5P_DEFAULT,
279  ds_data.data());
280  H5Dclose(dataset);
281 
282  //Each fragment is a collection of WIB Frames
283  Fragment frag(&ds_data[0], Fragment::BufferAdoptionMode::kReadOnlyMode);
284  size_t n_frames = (ds_size - sizeof(FragmentHeader))/sizeof(WIBFrame);
285  std::vector<raw::RawDigit::ADCvector_t> adc_vectors(256);
286  uint32_t slot = 0, fiber = 0;
287  for (size_t i = 0; i < n_frames; ++i)
288  {
289  auto frame = reinterpret_cast<WIBFrame*>(static_cast<uint8_t*>(frag.get_data()) + i*sizeof(WIBFrame));
290  for (size_t j = 0; j < adc_vectors.size(); ++j)
291  {
292  adc_vectors[j].push_back(frame->get_channel(j));
293  }
294 
295  if (i == 0)
296  {
297  slot = frame->get_wib_header()->slot_no;
298  fiber = frame->get_wib_header()->fiber_no;
299  }
300  }
301  //std::cout << "slot, fiber: " << slot << ", " << fiber << std::endl;
302  for (size_t iChan = 0; iChan < 256; ++iChan)
303  {
304  const raw::RawDigit::ADCvector_t & v_adc = adc_vectors[iChan];
305  //std::cout << "Channel: " << iChan << " N ticks: " << v_adc.size() << " Timestamp: " << frag.get_trigger_timestamp() << std::endl;
306 
307  int offline_chan = channelMap->getOfflChanFromSlotFiberChan(slot, fiber, iChan);
308  if (offline_chan < 0) continue;
309  if (offline_chan > maxchan) continue;
310  raw::RDTimeStamp rd_ts(frag.get_trigger_timestamp(), offline_chan);
311  timestamps.push_back(rd_ts);
312 
313  float median = 0., sigma = 0.;
314  getMedianSigma(v_adc, median, sigma);
315  raw::RawDigit rd(offline_chan, v_adc.size(), v_adc);
316  rd.SetPedestal(median, sigma);
317  raw_digits.push_back(rd);
318  }
319 
320  }
321  H5Gclose(linkGroup);
322  }
323 
324 }
325 
326 
328  const raw::RawDigit::ADCvector_t &v_adc, float &median,
329  float &sigma) {
330  size_t asiz = v_adc.size();
331  int imed=0;
332  if (asiz == 0) {
333  median = 0;
334  sigma = 0;
335  }
336  else {
337  // the RMS includes tails from bad samples and signals and may not be the best RMS calc.
338 
339  imed = TMath::Median(asiz,v_adc.data()) + 0.01; // add an offset to make sure the floor gets the right integer
340  median = imed;
341  sigma = TMath::RMS(asiz,v_adc.data());
342 
343  // add in a correction suggested by David Adams, May 6, 2019
344 
345  size_t s1 = 0;
346  size_t sm = 0;
347  for (size_t i = 0; i < asiz; ++i) {
348  if (v_adc.at(i) < imed) s1++;
349  if (v_adc.at(i) == imed) sm++;
350  }
351  if (sm > 0) {
352  float mcorr = (-0.5 + (0.5*(float) asiz - (float) s1)/ ((float) sm) );
353  //if (std::abs(mcorr)>1.0) std::cout << "mcorr: " << mcorr << std::endl;
354  median += mcorr;
355  }
356  }
357 
358 }
359 
void readFragmentsForEvent(art::Event &evt)
#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 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)
Handle< PROD > getHandle(SelectorBase const &) const
Definition: DataViewImpl.h:382
std::string string
Definition: nybbler.cc:12
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)
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
std::deque< std::string > getMidLevelGroupNames(hid_t grp)
Definition: HDF5Utils.cc:43
STL namespace.
QTextStream & hex(QTextStream &s)
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)
QCString file_name
std::vector< raw::RDTimeStamp > RDTimeStamps
Definition: HDF5Utils.h:24
std::list< std::string > getMidLevelGroupNames(hid_t grp)
VDColdboxDataInterface(fhicl::ParameterSet const &ps)
p
Definition: test.py:223
void getFragmentsForEvent(hid_t the_group, RawDigits &raw_digits, RDTimeStamps &timestamps, int apano, int maxchan)
QTextStream & dec(QTextStream &s)
void getMedianSigma(const raw::RawDigit::ADCvector_t &v_adc, float &median, float &sigma)
hid_t getGroupFromPath(hid_t fd, const std::string &path)
Definition: HDF5Utils.cc:91
void SetPedestal(float ped, float sigma=1.)
Set pedestal and its RMS (the latter is 0 by default)
Definition: RawDigit.cxx:68
int getOfflChanFromSlotFiberChan(int slot, int fiber, int chan)
TCEvent evt
Definition: DataStructs.cxx:7
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
int bool
Definition: qglobal.h:345
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)