RecDataWriter.cc
Go to the documentation of this file.
1 #include "RecDataWriter.h"
2 
3 #include "Offline2ADST.h"
4 
5 #include "FOVCalculator.h"
6 
7 #include <fwk/CentralConfig.h>
8 #include <fwk/LocalCoordinateSystem.h>
9 #include <fwk/CoordinateSystemRegistry.h>
10 
11 #include <det/Detector.h>
12 
13 #include <fdet/FDetector.h>
14 #include <fdet/Pixel.h>
15 #include <fdet/Eye.h>
16 #include <fdet/Camera.h>
17 #include <fdet/Telescope.h>
18 
19 #include <sdet/SDetector.h>
20 #include <sdet/Station.h>
21 
22 #include <evt/Event.h>
23 #include <evt/ShowerRecData.h>
24 #include <evt/ShowerSimData.h>
25 #include <evt/ShowerFRecData.h>
26 #include <evt/ShowerSRecData.h>
27 #include <evt/VGaisserHillasParameter.h>
28 #include <evt/GaisserHillas4Parameter.h>
29 #include <evt/GaisserHillas6Parameter.h>
30 #include <evt/ShowerSimData.h>
31 
32 #include <fevt/FEvent.h>
33 #include <fevt/Header.h>
34 #include <fevt/Eye.h>
35 #include <fevt/Telescope.h>
36 #include <fevt/EyeHeader.h>
37 #include <fevt/EyeRecData.h>
38 #include <fevt/TelescopeSimData.h>
39 #include <fevt/TelescopeRecData.h>
40 #include <fevt/Pixel.h>
41 #include <fevt/PixelRecData.h>
42 
43 #include <sevt/SEvent.h>
44 #include <sevt/Station.h>
45 #include <sevt/Header.h>
46 #include <sevt/StationRecData.h>
47 #include <sevt/StationSimData.h>
48 #include <sevt/StationTriggerData.h>
49 #include <sevt/SortCriteria.h>
50 #include <sevt/PMT.h>
51 #include <sevt/PMTRecData.h>
52 #include <sevt/PMTCalibData.h>
53 #include <sevt/StationConstants.h>
54 
55 #include <revt/REvent.h>
56 #include <revt/Station.h>
57 #include <revt/Channel.h>
58 #include <revt/EventTrigger.h>
59 #include <revt/Header.h>
60 #include <revt/StationGPSData.h>
61 #include <revt/StationRecData.h>
62 #include <revt/StationSimData.h>
63 #include <revt/StationTriggerData.h>
64 
65 #include <rdet/RDetector.h>
66 
67 #include <utl/Reader.h>
68 #include <utl/ErrorLogger.h>
69 #include <utl/TimeStamp.h>
70 #include <utl/ModifiedJulianDate.h>
71 #include <utl/UTCDateTime.h>
72 #include <utl/ReferenceEllipsoid.h>
73 #include <utl/AugerUnits.h>
74 #include <utl/Point.h>
75 #include <utl/Vector.h>
76 #include <utl/UTMPoint.h>
77 #include <utl/Transformation.h>
78 #include <utl/Trace.h>
79 #include <utl/AugerUnits.h>
80 #include <utl/MathConstants.h>
81 #include <utl/PhysicalConstants.h>
82 #include <utl/PhysicalFunctions.h>
83 #include <utl/config.h>
84 #include <utl/Particle.h>
85 #include <utl/CoordinateSystemPtr.h>
86 #include <utl/SaveCurrentTDirectory.h>
87 #include <utl/String.h>
88 
89 #include <atm/ProfileResult.h>
90 #include <atm/MolecularDB.h>
91 #include <atm/MolecularZone.h>
92 #include <atm/Atmosphere.h>
93 #include <atm/LidarDB.h>
94 #include <atm/LidarZone.h>
95 
96 #ifdef INCLUDE_HAS
97 # include <has/MuonProfile.h>
98 # include <has/VTankResponse.h>
99 # include <has/TankResponseFactory.h>
100 # include <has/EMComponent.h>
101 # include <has/HASUtilities.h>
102 #endif
103 
104 #include <boost/tuple/tuple.hpp>
105 
106 #include <adst/Detector.h>
107 #include <adst/FileInfo.h>
108 #include <adst/SDEvent.h>
109 #include <adst/FDEvent.h>
110 #include <adst/RecEvent.h>
111 #include <adst/FdRecApertureLight.h>
112 #include <adst/FdGenApertureLight.h>
113 #include <adst/FdRecPixel.h>
114 #include <adst/FdGenShower.h>
115 #include <adst/FdRecLevel.h>
116 #include <adst/SdRecLevel.h>
117 #include <adst/DetectorGeometry.h>
118 #include <adst/FdRecLevel.h>
119 #include <adst/FdLidarData.h>
120 #include <adst/FdAerosols.h>
121 #include <adst/Traces.h>
122 
123 #include <adst/AsciiSDConverter.h>
124 #include <adst/AsciiHybridConverter.h>
125 #include <adst/AsciiHybridOnlineConverter.h>
126 
127 #include <adst/RdEvent.h>
128 #include <adst/RdTrace.h>
129 #include "RdFiller.h"
130 
131 #include <cmath>
132 #include <vector>
133 #include <sstream>
134 #include <iostream>
135 #include <set>
136 
137 using namespace otoa;
138 using namespace fwk;
139 using namespace fdet;
140 using namespace sdet;
141 using namespace fevt;
142 using namespace sevt;
143 using namespace utl;
144 using namespace atm;
145 using namespace std;
146 #ifdef INCLUDE_HAS
147 using namespace HASTools;
148 using namespace HASUtilities;
149 #endif
150 
151 
152 namespace RecDataWriterNG {
153 
154  RecDataWriter::RecDataWriter() :
155  fADSTConverter(new otoa::Offline2ADST)
156  { }
157 
158 
160  {
161  delete fRecEvent;
162  delete fADSTConverter;
163  }
164 
165 
168  {
169  if (!ReadConfig())
170  return eFailure;
171 
172  const auto& cfg = fADSTConverter->Config();
173 
174  // info output
175  ostringstream info;
176  info << "Parameters:\n"
177  " output file: " << fRootOutputFileName << "\n"
178  " min ASCII FD rec level: " << fAsciiMinFdRecLevel << "\n"
179  " min ASCII SD rec level: " << fAsciiMinSdRecLevel << "\n"
180  " save FD traces: " << cfg.StoreFDTraces() << "\n"
181  " save SD traces: " << cfg.StoreSDTraces() << "\n"
182  " save MC traces: " << cfg.StoreMCTraces() << "\n"
183  " use weather station: " << cfg.UseWeatherStations() << "\n"
184  " connect to databases: " << cfg.ConnectToDatabases() << "\n"
185  " store Lidar data: " << cfg.StoreLidarData() << "\n"
186  " store cloud camera data: " << cfg.StoreCloudCameraData() << "\n"
187  " store GOES cloud data: " << cfg.StoreGOESData() << "\n"
188  " store all pixels: " << cfg.StoreAllPixels() << "\n"
189  " untriggered MC profile: " << (cfg.DropUntriggeredMCProfiles() ? "drop" :"keep") << "\n"
190  " untriggered MC tels: " << (cfg.DropUntriggeredMCTelescopes() ? "drop" :"keep") << "\n"
191  " untriggered detector: " << (cfg.DropUntriggeredDetector() ? "drop" :"keep") << "\n"
192  " re-bin sim. tel traces: ";
193  if (cfg.GetRebinSimTelescopeTraces() > 0)
194  info << cfg.GetRebinSimTelescopeTraces()/ns << " ns\n";
195  else
196  info << "NO\n";
197  info << " store photoelectrons: " << cfg.StoreSDPETimeDistribution() << "\n"
198  " Mie att. prof. sampling: " << cfg.AerosolAttenuationLengthSampling()/m << " m\n"
199  " Laser wavelength: " << cfg.LaserWavelength()/nanometer << " nm\n"
200  " store particles: " << cfg.StoreSDParticles() << "\n"
201  " Radio Save level: " << cfg.StoreRadioLevel() << "\n"
202  " save MD traces (AMIGA): " << cfg.StoreMDTraces();
203  INFO(info);
204 
205  if (cfg.AerosolAttenuationLengthSampling() > 0 && cfg.AerosolAttenuationLengthSampling() != 200*m) {
206  ERROR("Aerosol attenuation length sampling was not 200 m; this will invoke interpolation "
207  "which is not properly implemented, so the aerosol data stored in the ADST will not "
208  "be accurate. Please check your configuration and use 200 m!");
209  }
210 
211  // This radio part just checks that the radio save level is good
212  switch (cfg.StoreRadioLevel()) {
213  case -1:
214  INFO("Radio will not be saved");
215  break;
216  case 0:
217  INFO("Only Radio shower and station information will be saved");
218  break;
219  case 1:
220  INFO("Radio data will be saved at the station level");
221  break;
222  case 2:
223  INFO("Radio data will be saved at the Channel level");
224  break;
225  default:
226  INFO("Correct Values for SaveRadio field are -1/0/1/2! "
227  "Defaulting to saving the radio at the shower level! "
228  "Check RecDataWriter.xml");
229  break;
230  }
231 
232  return eSuccess;
233  }
234 
235 
238  {
239  // initialize RecEvent and RecEventFile first
240  if (!PrepareRecEventAndRootFile()) // checks fWriteROOT!
241  return eFailure;
242 
243  // initialize AsciiConverter first
245  return eFailure;
246 
247  if (!fWriteASCII && !fWriteROOT)
248  return eSuccess;
249 
250  const bool okay = fADSTConverter->Convert(event, *fRecEvent);
251  if (!okay)
252  return eSuccess; // skip
253 
254  if (fWriteROOT && fRecEventFile)
255  fRecEventFile->WriteEvent();
256 
258  fAsciiConverter->Convert(*fRecEvent);
259 
260  ++fNWritten;
261 
262  switch (fRecEvent->GetNEyes()) {
263  case 2:
264  ++fNWrittenStereo;
265  break;
266  case 3:
267  ++fNWrittenTriple;
268  break;
269  case 4:
271  break;
272  default:
273  break;
274  }
275 
276  return eSuccess;
277  }
278 
279 
282  {
283  if (fRecEventFile) {
285 
286  if (fVerbosity > -1)
287  INFO("writing detector");
288  fRecEventFile->WriteDetectorGeometry(fADSTConverter->GetDetectorGeometry());
289 
290  if (fVerbosity > -1)
291  INFO("writing file info");
292  fRecEventFile->WriteFileInfo(fADSTConverter->GetFileInfo());
293 
294  fRecEventFile->Close();
295  delete fRecEventFile;
296  fRecEventFile = nullptr;
297 
298  ostringstream info;
299  info << fNWritten << " event" << String::Plural(fNWritten) << " written to ADST ROOT file: "
300  << fNWrittenStereo << " stereo | "
301  << fNWrittenTriple << " triple | "
302  << fNWrittenQuadruple << " quadruple";
303  INFO(info);
304  }
305 
306  // finish ASCII writing
307  if (fAsciiConverter) {
308  delete fAsciiConverter;
309  fAsciiConverter = nullptr;
310  }
311 
312  return eSuccess;
313  }
314 
315 
316  bool
318  {
319  const auto cc = CentralConfig::GetInstance();
320  auto topB = cc->GetTopBranch("RecDataWriter");
321 
322  if (!topB) {
323  ERROR("Could not find configuration branch RecDataWriter");
324  return eFailure;
325  }
326 
327  auto& adstCfg = fADSTConverter->Config();
328 
329  if (!ReadRootConfig(topB) || !ReadAsciiConfig(topB))
330  return false;
331 
332  topB.GetChild("verbosity").GetData(fVerbosity);
333  adstCfg.SetVerbosity(fVerbosity);
334 
335  // configuration of WHAT is written to ADST
336  adstCfg.SetWriteFD(topB.GetChild("writeFD").Get<bool>());
337  adstCfg.SetWriteSD(topB.GetChild("writeSD").Get<bool>());
338 
339  // "Mostly" FD stuff
340  adstCfg.SetUseWeatherStations(topB.GetChild("useWeatherStations").Get<bool>());
341  adstCfg.SetConnectToDatabases(topB.GetChild("connectToDatabases").Get<bool>());
342  adstCfg.SetStoreLidarData(topB.GetChild("storeLidarData").Get<bool>());
343  adstCfg.SetStoreCloudCameraData(topB.GetChild("storeCloudCameraData").Get<int>());
344  adstCfg.SetStoreGOESData(topB.GetChild("storeGOESData").Get<int>());
345  adstCfg.SetStoreAllPixels(topB.GetChild("storeAllPixels").Get<bool>());
346  adstCfg.SetStoreFDTraces(topB.GetChild("saveFDTraces").Get<int>());
347  adstCfg.SetStoreLCEfficiency(topB.GetChild("saveLCEfficiency").Get<bool>());
348  adstCfg.SetVAODReferenceHeight(topB.GetChild("vaodReferenceHeight").Get<double>());
349  adstCfg.SetFieldOfViewOption(topB.GetChild("calculateFOVs").Get<int>());
350  adstCfg.SetAerosolAttenuationLengthSampling(topB.GetChild("aerosolAttenuationLengthSampling").Get<double>());
351  adstCfg.SetLaserWavelength(topB.GetChild("laserWavelength").Get<double>());
352 
353  // "mostly" SD stuff
354  adstCfg.SetStoreSDTraces(topB.GetChild("saveSDTraces").Get<int>());
355  adstCfg.SetStoreCalibHistos(topB.GetChild("storeCalibHistos").Get<int>());
356  adstCfg.SetStoreSDTracesMinEnergy(topB.GetChild("minEnergyForTraces").Get<double>());
357  adstCfg.SetStoreMPDsMinEnergy(topB.GetChild("minEnergyForStationsMPDs").Get<double>());
358  adstCfg.SetStoreSDPETimeDistribution(topB.GetChild("savePETimeDistribution").Get<bool>());
359  adstCfg.SetStoreMCTraces(topB.GetChild("saveMCTraces").Get<bool>());
360  adstCfg.SetStoreSDParticles(topB.GetChild("saveParticles").Get<bool>());
361 
362  auto saveParticleTypesB = topB.GetChild("saveParticleTypes");
363  if (saveParticleTypesB) {
364  const auto p = topB.GetChild("saveParticleTypes").Get<vector<int>>();
365  adstCfg.SetStoreSDParticleTypes(std::set<int>(p.begin(), p.end()));
366  }
367 
368  // MC stuff
369  adstCfg.SetDropUntriggeredMCProfiles(topB.GetChild("dropUntriggeredMCProfiles").Get<bool>());
370 
371  adstCfg.SetDropUntriggeredMCTelescopes(topB.GetChild("dropUntriggeredMCTelescopes").Get<bool>());
372 
373  adstCfg.SetDropUntriggeredDetector(topB.GetChild("dropUntriggeredDetector").Get<bool>());
374 
375  adstCfg.SetRebinSimTelescopeTraces(topB.GetChild("rebinSimTelescopesTraces").Get<double>());
376 
377  // Radio stuff
378  adstCfg.SetStoreRadioLevel(topB.GetChild("SaveRadio").Get<int>());
379  adstCfg.SetStoreExcludedRdStations(topB.GetChild("StoreExcludedRdStations").Get<bool>());
380 
381  // Muon detector stuff
382  adstCfg.SetStoreMDTraces(topB.GetChild("saveMDTraces").Get<bool>());
383  adstCfg.SetStoreMDInjectedParticles(topB.GetChild("saveMDInjectedParticles").Get<bool>());
384  auto saveMDParticleTypesB = topB.GetChild("saveMDParticleTypes");
385  if (saveMDParticleTypesB) {
386  const auto p = saveMDParticleTypesB.Get<vector<int>>();
387  adstCfg.SetStoreMDParticleTypes(std::set<int>(p.begin(), p.end()));
388  }
389 
390  // FIXME move HAS stuff to otoa
391  #ifdef INCLUDE_HAS
392  const auto hasB = cc->GetTopBranch("SdHorizontalReconstruction");
393 
394  if (hasB) {
395  const auto muonProfile = hasB.GetChild("MuonProfile").Get<string>();
396  auto muonMapBranch = cc->GetTopBranch("MuonProfile").GetChild(muonProfile);
397  fMuonProfile = new HASTools::MuonProfile(muonMapBranch);
398  const string tmp = "MuonProfile";
399  fMuonMapType = muonProfile.substr(0, muonProfile.length() - tmp.length());
400 
401  const auto tankResponse = hasB.GetChild("TankResponse").Get<string>();
402  auto tankResponseBranch = cc->GetTopBranch("TankResponse").GetChild(tankResponse);
403  fTankResponse = &HASTools::TankResponseFactory::GetInstance().GetTankResponse(tankResponseBranch);
404 
405  const auto emComponent = hasB.GetChild("EMComponent").Get<string>();
406  auto EMComponentBranch = cc->GetTopBranch("EMComponent").GetChild(emComponent);
407  fEMComponent = new HASTools::EMComponent(EMComponentBranch);
408 
409  const auto muonMapB = topB.GetChild("muonMap");
410  muonMapB.GetChild("nrOfPointsPerContour").GetData(fNoOfPoints);
411  muonMapB.GetChild("nrOfContours").GetData(fNoOfContours);
412  muonMapB.GetChild("contourSignalFactor").GetData(fContourSignalFactor);
413  } else {
414  INFO("Configuration for SdHorizontalReconstruction not found, no special treatment for horizontal events.");
415  }
416  #endif
417  return true;
418  }
419 
420 
421  bool
423  {
424  auto outputB = topB.GetChild("rootOutput");
425  if (!outputB)
426  return false;
427  outputB.GetChild("outputFileName").GetData(fRootOutputFileName);
428  INFO("ROOT output to " + fRootOutputFileName);
429  const auto writeMode = outputB.GetChild("outputFileMode").Get<string>();
430  if (writeMode == "eWrite") {
432  fWriteROOT = true;
433  } else if (writeMode == "eAppend") {
435  fWriteROOT = true;
436  } else if (writeMode == "eNone") {
438  fWriteROOT = false;
439  } else {
440  ostringstream err;
441  err << "Unrecognized file mode \"" << writeMode << "\"";
442  ERROR(err);
444  }
445 
446  return true;
447  }
448 
449 
450  bool
452  {
453  auto aOutputB = topB.GetChild("asciiOutput");
454  if (!aOutputB)
455  return false;
456 
457  const auto aWriteMode = aOutputB.GetChild("outputFileMode").Get<string>();
458  if (aWriteMode == "eWrite") {
460  fWriteASCII = true;
461  } else if (aWriteMode == "eAppend") {
463  fWriteASCII = true;
464  } else if (aWriteMode == "eNone") {
466  fWriteASCII = false;
467  } else {
468  ostringstream err;
469  err << "Unrecognized ASCII file mode \"" << aWriteMode << "\"";
470  ERROR(err);
472  }
473  aOutputB.GetChild("mode").GetData(fAsciiDataMode);
474 
475  if (fWriteASCII) {
476  aOutputB.GetChild("minimumFDRecLevel").GetData(fAsciiMinFdRecLevel);
477  aOutputB.GetChild("minimumSDRecLevel").GetData(fAsciiMinSdRecLevel);
478  aOutputB.GetChild("outputFileName").GetData(fAsciiOutputFileName);
479  INFO("Ascii output to " + fAsciiOutputFileName);
480  }
481 
482  return true;
483  }
484 
485 
486  bool
488  {
489  const SaveCurrentTDirectory save;
490  if (!fRecEvent)
491  fRecEvent = new RecEvent();
492  else
493  *fRecEvent = RecEvent();
494 
495  if (fWriteROOT && !fRecEventFile) {
496  // ---- open the RecEventFile and link the buffers ------
498  if (!fRecEventFile)
499  return false;
500  fRecEventFile->SetBuffers(&fRecEvent);
501  }
502 
503  return true;
504  }
505 
506 
507  bool
509  {
510  const auto openMode = ios::out | (fAsciiOutputFileMode == RecEventFile::eAppend ? ios::app : ios::trunc);
511  const auto asciiOut = new ofstream(fAsciiOutputFileName, openMode);
512  if (!asciiOut->is_open()) {
513  ERROR("Could not open ascii output file");
514  return false;
515  }
516 
517  if (fAsciiDataMode == "SD") {
518  const auto cv = new ADST::AsciiSDConverter(asciiOut);
519  cv->SetMinSdRecLevel(fAsciiMinSdRecLevel);
520  fAsciiConverter = (ADST::AsciiConverter*)cv;
521  } else if (fAsciiDataMode == "Hybrid") {
522  const auto cv = new ADST::AsciiHybridConverter(asciiOut);
523  ((ADST::AsciiFDConverter*)cv)->SetMinFdRecLevel(fAsciiMinFdRecLevel);
524  fAsciiConverter = (ADST::AsciiConverter*)cv;
525  } else if (fAsciiDataMode == "HybridOnline") {
526  const auto cv = new ADST::AsciiHybridOnlineConverter(asciiOut);
527  ((ADST::AsciiFDConverter*)cv)->SetMinFdRecLevel(fAsciiMinFdRecLevel);
528  fAsciiConverter = (ADST::AsciiConverter*)cv;
529  }
530  // transfer ownership of output to the converter
531  fAsciiConverter->SetOwnershipOfStream(true);
532 
534  fAsciiConverter->WriteFileHeader();
535 
536  return true;
537  }
538 
539 }
RecEventFile::Mode fAsciiOutputFileMode
fwk::VModule::ResultFlag Finish() override
Finish: invoked at end of the run (NOT end of the event)
Report success to RunController.
Definition: VModule.h:62
void FinishDetectorAndFileInfo()
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
vector< t2list > out
output of the algorithm: a list of clusters
Definition: XbAlgo.cc:32
Base class for exceptions trying to access non-existing components.
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
Read Only access.
Definition: IoCodes.h:18
constexpr double nanometer
Definition: AugerUnits.h:102
otoa::Offline2ADST * fADSTConverter
T Get() const
Definition: Branch.h:271
const char * Plural(const T n)
Definition: String.h:104
Class representing a document branch.
Definition: Branch.h:107
void SetVerbosity(const int v)
Definition: Config.h:24
const double ns
const otoa::Config & Config() const
Fetch the converter configuration.
Definition: Offline2ADST.h:52
bool Convert(const evt::Event &event, RecEvent &recEvent)
Definition: Offline2ADST.cc:90
RecEventFile::Mode fRootOutputFileMode
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
ADST::AsciiConverter * fAsciiConverter
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
fwk::VModule::ResultFlag Run(evt::Event &event) override
Run: invoked once per event.
fwk::VModule::ResultFlag Init() override
Initialize: invoked at beginning of run (NOT beginning of event)
const DetectorGeometry & GetDetectorGeometry() const
Definition: Offline2ADST.h:43
Overwrite if exist and open for write.
Definition: IoCodes.h:20
Report failure to RunController, causing RunController to terminate execution.
Definition: VModule.h:64
bool ReadRootConfig(utl::Branch &topB)
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
constexpr double m
Definition: AugerUnits.h:121
bool ReadAsciiConfig(utl::Branch &topB)
const FileInfo & GetFileInfo() const
Definition: Offline2ADST.h:47
Converts an Offline event to ADST.
Definition: Offline2ADST.h:27

, generated on Tue Sep 26 2023.