RdREASSimPreparator.cc
Go to the documentation of this file.
1 #include "RdREASSimPreparator.h"
2 
3 //OffLine
4 #include <fwk/CentralConfig.h>
5 #include <fwk/LocalCoordinateSystem.h>
6 #include <fwk/CoordinateSystemRegistry.h>
7 #include <fwk/MagneticFieldModel.h>
8 
9 #include <det/Detector.h>
10 #include <rdet/RDetector.h>
11 #include <sdet/SDetector.h>
12 #include <sdet/SDetectorConstants.h>
13 
14 #include <evt/Event.h>
15 #include <evt/ShowerRecData.h>
16 #include <evt/ShowerSRecData.h>
17 #include <evt/ShowerRRecData.h>
18 #include <evt/Header.h>
19 #include <revt/REvent.h>
20 #include <revt/Header.h>
21 
22 #include <utl/Point.h>
23 #include <utl/UTMPoint.h>
24 #include <utl/ReferenceEllipsoid.h>
25 #include <utl/AugerUnits.h>
26 #include <utl/Reader.h>
27 #include <utl/TimeStamp.h>
28 #include <utl/UTCDateTime.h>
29 #include <utl/Line.h>
30 #include <utl/GeometryUtilities.h>
31 #include <utl/RadioGeometryUtilities.h>
32 #include <utl/System.h>
33 
34 //Root
35 #include <TFile.h>
36 #include <TTree.h>
37 
38 //C++
39 #include <boost/algorithm/string.hpp>
40 #include <boost/tokenizer.hpp>
41 #include <fstream>
42 #include <sstream>
43 #include <ios>
44 #include <cmath>
45 #include <vector>
46 #include <iomanip>
47 
48 //#include <utl/Config.h>
49 
50 using namespace evt;
51 using namespace fwk;
52 using namespace utl;
53 using namespace det;
54 using std::string;
55 using std::vector;
56 using std::stringstream;
57 using std::ostringstream;
58 using std::ofstream;
59 using std::cout;
60 using std::setw;
61 using std::endl;
62 using std::ios_base;
63 
64 
65 typedef boost::tokenizer<boost::char_separator<char>> mytok;
66 
67 
69 
72  {
73  Branch topBranch = CentralConfig::GetInstance()->GetTopBranch("RdREASSimPreparator");
74  topBranch.GetChild("WorkingDir").GetData(fWorkingDir);
75  topBranch.GetChild("UserName").GetData(fUserName);
76  topBranch.GetChild("CorsikaPath").GetData(fCorsikapath);
77  topBranch.GetChild("CorsikaBin").GetData(fCorsikaBin);
78  topBranch.GetChild("FluPro").GetData(fFLUPRO);
79  topBranch.GetChild("CoastDir").GetData(fCOAST_DIR);
80  topBranch.GetChild("CoastBase").GetData(fCOAST_BASE_DIR);
81  topBranch.GetChild("ROOTSYS_Corsika").GetData(fROOTSYS_Corsika);
82  topBranch.GetChild("ROOTSYS_Reas").GetData(fROOTSYS_Reas);
83  topBranch.GetChild("CoastLib").GetData(fCOAST_USER_LIB);
84  topBranch.GetChild("MonthlyAtmosphericModel").GetData(fMonthlyAtmosphericModel);
85  topBranch.GetChild("ElectricField").GetData(fElectricField);
86  topBranch.GetChild("RandomSeed").GetData(fSeed);
87  topBranch.GetChild("SimNumber").GetData(fRunNumber);
88  topBranch.GetChild("AntennaPerJob").GetData(fAntennaPerJob);
89  topBranch.GetChild("GetMagneticFieldFromModel").GetData(fGetMagneticFieldFromModel);
90  topBranch.GetChild("MagneticFieldDeclination").GetData(fMagneticFieldDeclination);
91  topBranch.GetChild("MaxAntennaDistance").GetData(fMaxAntennaDistanceFromCore);
92  topBranch.GetChild("SeaLevelRefractivity").GetData(fSeaLevelRefractivity);
93  topBranch.GetChild("Stepfc").GetData(fStepfc);
94  topBranch.GetChild("ThinningLevel").GetData(fThinningLevel);
95  topBranch.GetChild("MagneticFieldX").GetData(fMagneticFieldX);
96  topBranch.GetChild("MagneticFieldY").GetData(fMagneticFieldY);
97  topBranch.GetChild("ObserverLevelOffset").GetData(fObserverLevelOffset);
98  fUseCoreDistance = (topBranch.GetChild("DistanceTo").Get<string>() == "core");
99  topBranch.GetChild("UseConex").GetData(fUseConex); // Does not work,, need to be corrected
100  topBranch.GetChild("UseGeometry").GetData(fUseGeometry);
101  topBranch.GetChild("UseEnergy").GetData(fUseEnergy);
102  topBranch.GetChild("Primary").GetData(fprim);
103  topBranch.GetChild("WriteAERAlist").GetData(fWriteAERAlist);
104  topBranch.GetChild("MaxAxisDistance").GetData(fMaxAxisDistance);
105  if (fUseConex) {
106  topBranch.GetChild("ConexDir").GetData(fConexDir);
107  topBranch.GetChild("ConexBin").GetData(fConexBin);
108  topBranch.GetChild("ConexModel").GetData(fModel);
109  topBranch.GetChild("NumberOfConexShower").GetData(fNConexShower);
110  }
111 
112  ostringstream info;
113  info << "\n-------RdReasSimPreparator::Init\n"
114  " WorkingDir : "<< fWorkingDir << "\n"
115  " Corsika : " << fCorsikapath << '/' << fCorsikaBin << "\n"
116  " SEED : " << fSeed << " RUNNumber " << fRunNumber << '\n';
117 
118  if (!fUseConex)
119  info << "Conex is not activated\n";
120  else
121  info << "Conex is active\n Conex : " << fConexDir<<"/"<<fConexBin<<"\n";
122 
123  // We want to start to count from the RunNumber
124  --fRunNumber;
125 
126  return VModule::eSuccess;
127  }
128 
129 
131  RdREASSimPreparator::Run(Event& event)
132  {
133  revt::REvent& rEvent = event.GetREvent();
134  const revt::Header& rHead = rEvent.GetHeader();
135  const Header& head = event.GetHeader();
136  eventHeader = head.GetId();
137 
138  // Increasing Run Number (has been decreased in init to start from config)
139  ++fRunNumber;
140 
141  const evt::ShowerRecData& zeShower = event.GetRecShower();
142  utl::Point zeCore;
143  utl::Vector zeaxis;
144  if (fUseGeometry == "SD") {
145  zeCore = zeShower.GetSRecShower().GetCorePosition();
146  zeaxis = zeShower.GetSRecShower().GetAxis();
147  }
148  if (fUseGeometry == "RD") {
149  zeCore = zeShower.GetRRecShower().GetCorePosition();
150  zeaxis = zeShower.GetRRecShower().GetAxis();
151  }
152 
153  // Get the time stamp from the SdEvent to get the Magnetic Field Declination at the Event time
154  const TimeStamp theTime = TimeStamp(head.GetTime().GetGPSSecond(), head.GetTime().GetGPSNanoSecond());
155 
156  // Get the Magnetic Field from the model
157  fMagneticFieldDeclinationFromModel = fwk::MagneticFieldModel::instance().GetDeclination(zeCore, theTime);
158  const Vector theMagneticFieldVector = fwk::MagneticFieldModel::instance().GetMagneticFieldVector(zeCore, theTime);
159 
160  // Get the components in the Core System
162 
163  fBFieldHorizontal =
164  sqrt(pow(theMagneticFieldVector.GetX(zeCoreCS), 2) + pow(theMagneticFieldVector.GetY(zeCoreCS), 2));
165  fBFieldVertical = theMagneticFieldVector.GetZ(zeCoreCS);
166 
167  // Choose atmospheric model
168  unsigned int fmodatm = fMonthlyAtmosphericModel;
169  if (fMonthlyAtmosphericModel < 0 || fMonthlyAtmosphericModel > 29) {
170  const UTCDateTime& d = head.GetTime();
171  unsigned int month = d.GetMonth();
172  fmodatm = month + 17;
173  }
174 
175  // Write files
176  const vector<string> v_detectorfiles = WriteDetectorFile(zeCore, zeaxis);
177  const string corsikainp = CorsikaInpFileWriter(zeShower, zeCore, fmodatm);
178  const string corsikascript = LaunchCorsikaSim(corsikainp);
179  const string reassim = REASFileWriter(zeCore, zeShower, corsikainp, head, rHead);
180 
181  return VModule::eSuccess;
182  }
183 
184 
186  RdREASSimPreparator::Finish()
187  {
188  INFO("RdREASSimPreparator::Finish()");
189  return VModule::eSuccess;
190  }
191 
192 
194  string
195  RdREASSimPreparator::CorsikaInpFileWriter(const evt::ShowerRecData& show, const Point& core, unsigned int modatm)
196  {
197  {
198  // a text file which shows the relation between Sd id and Sim id:
199  ofstream out(fWorkingDir + "SdId-SimId_relation.txt", std::ios::app);
200  out << eventHeader << " --> " << AddZero(fRunNumber, 6) << endl;
201  }
202 
203  ostringstream filename;
204  filename << "RUN" << AddZero(fRunNumber, 6) << ".inp";
205  ofstream inpfile(fWorkingDir + filename.str());
206 
207  // get direction
209  float az = 0;
210  float zen = 0;
211  if (fUseGeometry == "SD") {
212  az = atan2(show.GetSRecShower().GetAxis().GetY(coreCS), show.GetSRecShower().GetAxis().GetX(coreCS));
213  zen = acos(show.GetSRecShower().GetAxis().GetZ(coreCS)) / degree;
214  }
215  if (fUseGeometry == "RD") {
216  az = atan2(show.GetRRecShower().GetAxis().GetY(coreCS), show.GetRRecShower().GetAxis().GetX(coreCS));
217  zen = acos(show.GetRRecShower().GetAxis().GetZ(coreCS)) / degree;
218  }
219 
220  // conversion in corsika coordinate system
221  az += fGetMagneticFieldFromModel ? fMagneticFieldDeclinationFromModel : fMagneticFieldDeclination;
222  az /= degree;
223  az += 90;
224  if (az > 360)
225  az -= 360;
226 
227  // get energy
228  float energy = 0;
229  if (fUseEnergy == "SD")
230  energy = show.GetSRecShower().GetEnergy();
231  if (fUseEnergy == "RD")
232  energy = show.GetRRecShower().GetParameter(revt::eCosmicRayEnergy); // note: Why has show.GetRRecShower() no member GetEnergy() like SRecShower?
233 
234  // get core in absolut coordinates
235  UTMPoint utmcore(core, ReferenceEllipsoid::GetWGS84());
236 
237  // start writing
238  inpfile << "RUNNR\t" << AddZero(fRunNumber, 6) << "\n"
239  "EVTNR\t1\n"
240  "SEED\t" << fSeed << "\t0\t0\n";
241  ++fSeed;
242  inpfile << "SEED\t" << (fSeed + fSeed*2) << "\t0\t0\n";
243  ++fSeed;
244  inpfile << "SEED\t" << (fSeed + fSeed/3) << "\t0\t0\n";
245  ++fSeed;
246  inpfile << "NSHOW\t1\n";
247 
248  if (fUseConex) {
249  const string cnxfile = LaunchConexSim(show, core);
250  double firstintheight = 0;
251  long firstinttarget = 0;
252  string showername;
253  ExtractTypicalShower(fWorkingDir, cnxfile, firstintheight, firstinttarget, showername, "00000");
254  cout << " MM : After Conex\n"
255  " First interactrion " << firstintheight << "\n"
256  " First interaction target " << firstinttarget << "\n"
257  " Shower Name " << showername << endl;
258  inpfile << "INFILE\t" << fWorkingDir << '/' <<cnxfile << showername
259  << " first interaction secondaries\n"
260  "FIXHEI\t" << firstintheight << " " << firstinttarget << " height and target\n";
261  } else {
262  inpfile << "ERANGE\t" << energy/GeV << '\t' << energy/GeV << endl;
263 
264  if (fprim == "Proton")
265  inpfile << "PRMPAR\t14\n";
266  else if (fprim == "Iron")
267  inpfile << "PRMPAR\t5626\n";
268  }
269 
270  inpfile << "THETAP\t" << zen << "\t" << zen << "\n"
271  "PHIP\t" << az << "\t" << az << "\n"
272  "ECUTS\t0.3\t1.000E-02\t2.500E-04\t2.500E-04\n"
273  "ELMFLG\tT\tT\n"
274  "THIN\t" << fThinningLevel << "\t" << (energy / GeV * fThinningLevel) << "\t100E+02\n"
275  "THINH\t1.000E+00\t1.000E+02\n"
276  "OBSLEV\t" << (utmcore.GetHeight()/cm - fObserverLevelOffset/cm) << "\n" // simulate shower a bit further than the core altitude
277  "ECTMAP\t1.E5\n"
278  "STEPFC\t" << fStepfc << "\n"
279  "MUADDI\tT\n"
280  "MUMULT\tT\n"
281  "HILOW\t100\n"
282  "MAXPRT\t1\n";
283 
284  if (fGetMagneticFieldFromModel)
285  inpfile << "MAGNET\t" << fBFieldHorizontal/micro/tesla << "\t\t" << -1*fBFieldVertical/micro/tesla << '\n';
286  else
287  inpfile << "MAGNET\t"<< fMagneticFieldX/micro/tesla << "\t" << fMagneticFieldY/micro/tesla << "\n";
288 
289  inpfile << "ATMOD\t" << modatm << "\n"
290  "PAROUT\tT\tF\n"
291  "LONGI\tT\t5.\tT\tT\n"
292  "RADNKG\t5.e5\n"
293  "DIRECT\t" << fWorkingDir<< "/\n"
294  "DATBAS\tF\n"
295  "USER\t"<< fUserName << "\n"
296  "EXIT\n";
297 
298  return filename.str();
299  }
300 
301 
303  string
304  RdREASSimPreparator::LaunchCorsikaSim(const string& corsikaparameterfile)
305  {
306  ostringstream filename;
307  filename << "RUN" << AddZero(fRunNumber, 6) << ".sh";
308  ofstream scriptfile(fWorkingDir + filename.str());
309  scriptfile << "#!/bin/bash\n"
310  "#$ -S /bin/bash\n"
311  "ulimit -Sc 0\n"
312  "cd " << fCorsikapath << "\n"
313  "#set environment\n"
314  "export FLUPRO=" << fFLUPRO << "\n"
315  "./" << fCorsikaBin << " < " << fWorkingDir << '/' << corsikaparameterfile
316  << " > " << fWorkingDir << "/RUN" << AddZero(fRunNumber, 6) << ".log 2>&1\n";
317  return filename.str();
318  }
319 
320 
322  string
323  RdREASSimPreparator::LaunchConexSim(const evt::ShowerRecData& show, const Point& core)
324  {
325  //INFO("RdREASSimPreparator::LaunchConexSim");
326  // Here ConexSimulation will be launched, might be long
327  ostringstream filename;
329  float az = 0;
330  float zen = 0;
331  if (fUseGeometry == "SD") {
332  az = atan2(show.GetSRecShower().GetAxis().GetY(coreCS), show.GetSRecShower().GetAxis().GetX(coreCS));
333  zen = show.GetSRecShower().GetAxis().GetTheta(coreCS) / degree;
334  }
335  if (fUseGeometry == "RD") {
336  az = atan2(show.GetRRecShower().GetAxis().GetY(coreCS), show.GetRRecShower().GetAxis().GetX(coreCS));
337  zen = show.GetRRecShower().GetAxis().GetTheta(coreCS) / degree;
338  }
339  az += fGetMagneticFieldFromModel ? fMagneticFieldDeclinationFromModel : fMagneticFieldDeclination;
340  az /= degree;
341  az += 90;
342  if (az > 360)
343  az -= 360;
344  filename << "Conex" << AddZero(fRunNumber, 6) << ".sh";
345  ostringstream conexout;
346  string conexModel;
347  if (fModel == 6)
348  conexModel = "qgsjetII";
349  else if (fModel == 2)
350  conexModel = "qgsjet";
351  else
352  conexModel = "wtf";
353 
354  conexout << "conex_" << conexModel << '_' << AddZero(fSeed, 9) << '_';
355  //<<fRunNumber;
356  ofstream conexfile(filename.str());
357  float energy = 0;
358  if (fUseEnergy == "SD")
359  energy = show.GetSRecShower().GetEnergy();
360  if (fUseEnergy == "RD")
361  energy = show.GetRRecShower().GetParameter(revt::eCosmicRayEnergy);
362  conexfile << "#!/bin/sh\n"
363  "cd "<< fConexDir << '\n'
364  << fConexDir << '/' << fConexBin
365  << " -K 1"
366  " -s " << (fSeed++)
367  << " -e " << log10(energy/eV)
368  << " -E " << log10(energy/eV)
369  << " -z " << zen
370  << " -Z " << zen
371  << " -i " << az
372  << " -m " << fModel
373  << " -n " << fNConexShower; // Need to add a variable
374 
375  if (fprim == "Proton")
376  conexfile << " -p 100"; // proton (Need to do something for that)
377  else if (fprim == "Iron")
378  conexfile << " -p 5626";
379 
380  conexfile << " > "<< fWorkingDir << conexout.str() << fRunNumber << ".log\n"
381  "mv " << conexout.str() << "100.root " << fWorkingDir << '\n';
382  conexfile.close();
383  ostringstream cmd;
384  cmd << "chmod +x " << filename.str();
385  System(cmd);
386  cmd.str("");
387  //INFO("Please wait while Running Conex");
388  cmd << "./" << filename.str();
389  cout << " MM " << cmd.str() << endl;
390  System(cmd);
391  //INFO("DONE");
392 
393  return conexout.str() + "100.root";
394  }
395 
396 
398  string
399  RdREASSimPreparator::REASFileWriter(const utl::Point& zeCore, const evt::ShowerRecData& show, const string& corsikaparameterfile,
400  const evt::Header& head, const revt::Header& rHead)
401  {
402  ostringstream filename;
403  const CoordinateSystemPtr PampaAmarillaCS = CoordinateSystemRegistry::Get("PampaAmarilla");
405  float az = 0;
406  float zen = 0;
407  if (fUseGeometry == "SD") {
408  az = atan2(show.GetSRecShower().GetAxis().GetY(coreCS),show.GetSRecShower().GetAxis().GetX(coreCS));
409  zen = show.GetSRecShower().GetAxis().GetTheta(coreCS) / degree;
410  }
411  if (fUseGeometry == "RD") {
412  az = atan2(show.GetRRecShower().GetAxis().GetY(coreCS),show.GetRRecShower().GetAxis().GetX(coreCS));
413  zen = show.GetRRecShower().GetAxis().GetTheta(coreCS) / degree;
414  }
415  az += fGetMagneticFieldFromModel ? fMagneticFieldDeclinationFromModel : fMagneticFieldDeclination;
416  az /= degree;
417  az += 90;
418  //ReferenceEllipsoid Ellipsoid = ReferenceEllipsoid::GetEllipsoidIDFromString(ellipsoid)i;
419  UTMPoint utmcore(zeCore, ReferenceEllipsoid::GetWGS84());
420  filename << "SIM" << AddZero(fRunNumber, 6) << ".reas";
421  ofstream reasfile(fWorkingDir + filename.str());
422 
423  float energy = 0;
424  if (fUseEnergy == "SD")
425  energy = show.GetSRecShower().GetEnergy();
426  if (fUseEnergy == "RD")
427  energy = show.GetRRecShower().GetParameter(revt::eCosmicRayEnergy);
428  //----------------------------------------------------------------------------------------------
429  reasfile << "# CoREAS V1 parameter file\n"
430  "\n"
431  "\n"
432  "# parameters setting up the spatial observer configuration:\n"
433  "\n"
434  "CoreCoordinateNorth = 0 ; in cm\n"
435  "CoreCoordinateWest = 0 ; in cm\n"
436  "CoreCoordinateVertical = " << utmcore.GetHeight()/cm<< " ; in cm\n"
437  "\n"
438  "# parameters setting up the temporal observer configuration:\n"
439  "\n"
440  "AutomaticTimeBoundaries = 4e-07 ; 0: off, x: automatic boundaries with width x in s\n"
441  "TimeLowerBoundary = -1 ; in s, only if AutomaticTimeBoundaries set to 0\n"
442  "TimeUpperBoundary = 1 ; in s, only if AutomaticTimeBoundaries set to 0\n"
443  "TimeResolution = 5e-10 ; in s\n"
444  "ResolutionReductionScale = 0 ; 0: off, x: decrease time resolution linearly every x cm in radius\n"
445  "GroundLevelRefractiveIndex = " << std::setprecision(7) << fSeaLevelRefractivity << std::setprecision(6) << " ; specify refractive index at 0 m asl\n"
446  "\n"
447  "# parameters read from CORSIKA files, these are not interpreted by CoREAS but stated here for your convenience\n"
448  "\n"
449  "PrimaryParticleEnergy = " << energy/electronvolt << " ; in eV\n"
450  "ShowerZenithAngle = " << zen << " ; in degrees\n"
451  "ShowerAzimuthAngle = " << az << " ; in degrees, 0: shower propagates to north, 90: to west\n"
452  "\n"
453  "# book-keeping parameters needed for read-in to Offline\n"
454  "\n"
455  "CorsikaFilePath = ./ ; path to the CORSIKA files (cannot include space characters!)\n"
456  "CorsikaParameterFile = " << corsikaparameterfile << "; specify CORSIKA card file\n"
457  "EventNumber = " << rHead.GetId() << "\n"
458  "RunNumber = " << rHead.GetRunNumber() << "\n"
459  "GPSSecs = " << head.GetTime().GetGPSSecond() << "\n"
460  "GPSNanoSecs = " << long(head.GetTime().GetGPSNanoSecond()+0.5) << "\n" // print it out as a long because CoREAS expects it to be integer
461  "CoreEastingOffline = " << zeCore.GetX(PampaAmarillaCS)/meter << "; in meters\n"
462  "CoreNorthingOffline = " << zeCore.GetY(PampaAmarillaCS)/meter << "; in meters\n"
463  "CoreVerticalOffline = " << zeCore.GetZ(PampaAmarillaCS)/meter << "; in meters\n";
464 
465  if (fGetMagneticFieldFromModel)
466  reasfile << "RotationAngleForMagfieldDeclination = " << fMagneticFieldDeclinationFromModel/degree << "; in degrees\n";
467  else
468  reasfile << "RotationAngleForMagfieldDeclination = " << fMagneticFieldDeclination/degree << "; in degrees\n";
469 
470  // fixme TH: it would be good to propagate a user-defined comment from the XML file here, for example the RdObserver version number
471  reasfile << "Comment = Event " << GetEventNumber(head.GetId()) << " at "
472  << UTCDateTime(head.GetTime()).GetInXMLFormat() << "; "
473  "created by RdREASSimPreparator, Offline coordinates are in PampaAmarilla coordinate system\n";
474  //--------------------------------------------------------------------------
475  return filename.str();
476  }
477 
478 
481  vector<std::string>
482  RdREASSimPreparator::WriteDetectorFile(const Point& core, const Vector& axis)
483  {
484  cout << " RdREASSimPreparator::WriteDetectorFile" << endl;
485  //INFO("RdREASSimPreparator::WriteDetectorFile");
486  int AntennaInFile = -1;
488  UTMPoint utmcore(core, ReferenceEllipsoid::GetWGS84());
489  Detector& Det = Detector::GetInstance();
490  //utl::TimeStamp now(1008712640,0);
491  //Det.Update(now);
492 
493  vector<Point> antenna_positions;
494  vector<string> antenna_names;
495 
496  if (fWriteAERAlist) {
497  const rdet::RDetector& RadioDet = Det.GetRDetector();
498 
499  for (rdet::RDetector::StationIterator rdIt = RadioDet.StationsBegin(); rdIt != RadioDet.StationsEnd(); ++rdIt) {
500  if (AntennaInFile >= fAntennaPerJob)
501  break;
502  if (!rdIt->IsInGrid())
503  continue;
504  Point Position = rdIt->GetPosition();
505  Vector VecAntenna = Position-core;
506  if (fUseCoreDistance) {
507  if (VecAntenna.GetR(coreCS) > fMaxAntennaDistanceFromCore) // does the chosen coordinate system influence the result?
508  continue;
509  } else {
510  Line axisline(core, axis);
511  if (Distance(axisline, Position) > fMaxAntennaDistanceFromCore)
512  continue;
513  }
514 
515  antenna_names.push_back(rdIt->GetName());
516  antenna_positions.push_back(rdIt->GetPosition());
517  ++AntennaInFile;
518  }
519  } else {
520  // RdUpgrade
521  const sdet::SDetector& sdetector = Det.GetSDetector();
522 
523  /*
524  only iterate over regular 1500 m grid array. Use sdetector.StationsBegin()
525  and sdetector.StationsEnd() for all stations or set gridtype:
526  eAny, eStandard, eInfill750, eInfill433
527  */
528 
530  for (const auto& station : sdetector.GridStationsRange(gridtype)) {
531  const double axisDistance = RadioGeometryUtilities::GetDistanceToAxis(axis, core, station.GetPosition());
532  if (axisDistance < fMaxAxisDistance) {
533  string station_name = station.GetName();
534  replace(station_name.begin(), station_name.end(), ' ', '_');
535  antenna_names.push_back(station_name);
536  antenna_positions.push_back(station.GetPosition());
537  }
538  }
539  }
540 
541  ostringstream filename;
542  filename << "SIM" << AddZero(fRunNumber, 6) << ".list"; //COREAS
543 
544  vector<string> v_filelist;
545  v_filelist.push_back(filename.str());
546 
547  ofstream aeralist(fWorkingDir + filename.str());
548 
549  for (unsigned int i = 0; i < antenna_positions.size(); ++i) {
550  double antX = antenna_positions[i].GetX(coreCS);
551  double antY = antenna_positions[i].GetY(coreCS);
552  double antZ = utmcore.GetHeight() + antenna_positions[i].GetZ(coreCS);
553 
554  // rotate antenna coordinates according to magnetic field declination
555  double rotX;
556  double rotY;
557  if (fGetMagneticFieldFromModel) {
558  rotX = cos(fMagneticFieldDeclinationFromModel)*antX - sin(fMagneticFieldDeclinationFromModel)*antY;
559  rotY = sin(fMagneticFieldDeclinationFromModel)*antX + cos(fMagneticFieldDeclinationFromModel)*antY;
560  } else {
561  rotX = cos(fMagneticFieldDeclination)*antX - sin(fMagneticFieldDeclination)*antY;
562  rotY = sin(fMagneticFieldDeclination)*antX + cos(fMagneticFieldDeclination)*antY;
563  }
564 
565  aeralist << "AntennaPosition = " << rotY/cm << " " << -rotX/cm << " " << antZ/cm
566  << ' ' << antenna_names[i] << endl;
567  }
568 
569  return v_filelist;
570  }
571 
572 
574  std::string
575  RdREASSimPreparator::GetEventNumber(const std::string& eventId)
576  {
577  vector<string> zetokens;
578  string zestring;
579  boost::char_separator<char> sep("_");
580  zetokens.clear();
581  mytok tok(eventId, sep);
582  zetokens.clear();
583  for (mytok::const_iterator titer = tok.begin(); titer != tok.end(); ++titer)
584  zetokens.push_back(*titer);
585  if (zetokens.size() >= 4)
586  return zetokens[3];
587  else
588  return eventId;
589  }
590 
591 
593  std::string
594  RdREASSimPreparator::AddZero(const int RunID, const int numberofdigit)
595  {
596  ostringstream runnumb;
597  for (int i = 0; i < numberofdigit - 1 - floor(log10(float(RunID))); ++i)
598  runnumb << "0";
599  runnumb << RunID;
600  return runnumb.str();
601  }
602 
603 
605  bool
606  RdREASSimPreparator::ExtractTypicalShower(const string& workdir, const string& filename,
607  double& firstintheight, long& firstinttarget,
608  string& selshowstring, const string& runnrstring)
609  {
610  const float maximumenergyfractioninfirstparticle = 0.10; // set maximum energy fraction that may be contained in first particle
611  //gROOT->Reset();
612 
613  // open file
614  TFile* const f = new TFile((workdir + filename).c_str());
615  if (f->IsZombie())
616  return false; // error
617 
618  // set and read tree
619 
620  TTree* const Shower = (TTree*)(f->Get("Shower"));
621  TTree* const Header = (TTree*)(f->Get("Header"));
622  TTree* const FirstInteraction = (TTree*)(f->Get("FirstInteraction"));
623  int nevent = static_cast<int>(Shower->GetEntries());
624 
625  const int maxX = 4000;
626  float X[maxX], H[maxX], D[maxX], N[maxX],dEdX[maxX], Mu[maxX], dMu[maxX];
627  float fitpars[11], EGround[3], muThr, hadThr, emThr;
628  int nX, iPart, iseed1, iseed2, iseed3, HEModel;
629  const int maxNInt = 100;
630  int gMult1[maxNInt]; // multiplicity
631  int nParticles;
632  int gnInt1; // number of interactions
633  double gkinel1[maxNInt]; // inelasticity
634  int gpId1[maxNInt]; // parent id
635  double gpEnergy1[maxNInt]; // parent energy
636  int gMatg1[maxNInt]; // target nucleus mass
637  double gDepth1[maxNInt]; // depth
638  double gHeight1[maxNInt]; // height
639 
640  int gNParticles1;
641  const int maxNPart = 100000;
642  double gEnergy1[maxNPart]; // size = 75000 from conex.incnex
643  double gpx1[maxNPart];
644  double gpy1[maxNPart];
645  double gpz1[maxNPart];
646  int gType1[maxNPart];
647  int gIdInt1[maxNPart];
648 
649  Shower->SetBranchAddress("lgE", &fitpars[0]);
650  Shower->SetBranchAddress("zenith", &fitpars[1]);
651  Shower->SetBranchAddress("azimuth", &fitpars[10]);
652  Shower->SetBranchAddress("Xfirst", &fitpars[2]);
653  Shower->SetBranchAddress("X0", &fitpars[4]);
654  Shower->SetBranchAddress("Xmax", &fitpars[9]);
655  Shower->SetBranchAddress("Nmax", &fitpars[3]);
656  Shower->SetBranchAddress("p1", &fitpars[5]);
657  Shower->SetBranchAddress("p2", &fitpars[6]);
658  Shower->SetBranchAddress("p3", &fitpars[7]);
659  Shower->SetBranchAddress("chi2", &fitpars[8]);
660  Shower->SetBranchAddress("nX", &nX); // number of points in slant depth
661  Shower->SetBranchAddress("N", N); // particles(X)
662  Shower->SetBranchAddress("dEdX", dEdX); // Energy deposit(X)
663  Shower->SetBranchAddress("Mu", Mu); // muons(X)
664  Shower->SetBranchAddress("dMu", dMu); // muon production(X)
665  Shower->SetBranchAddress("EGround", EGround);
666  Header->SetBranchAddress("muThr", &muThr);
667  Header->SetBranchAddress("emThr", &emThr);
668  Header->SetBranchAddress("hadThr", &hadThr);
669  Header->SetBranchAddress("HEModel", &HEModel); // high energy model
670  Shower->SetBranchAddress("X", X); // slant depth
671  Shower->SetBranchAddress("H", H); // height above see level
672  Shower->SetBranchAddress("D", D); // distance to obs. point
673  Header->SetBranchAddress("Particle", &iPart);
674  Header->SetBranchAddress("Seed1", &iseed1);
675  Shower->SetBranchAddress("Seed2", &iseed2);
676  Shower->SetBranchAddress("Seed3", &iseed3);
677  FirstInteraction->SetBranchAddress("nPart", &nParticles); // number of particles
678  FirstInteraction->SetBranchAddress("mult", gMult1); // multiplicity
679  FirstInteraction->SetBranchAddress("nInt", &gnInt1); // number of interatctions
680  FirstInteraction->SetBranchAddress("kinel", gkinel1); // inelasticity
681  FirstInteraction->SetBranchAddress("pId", gpId1); // parent id
682  FirstInteraction->SetBranchAddress("pEnergy", gpEnergy1);// parent energy
683  FirstInteraction->SetBranchAddress("mult", gMult1); // multiplicity
684  FirstInteraction->SetBranchAddress("matg", gMatg1); // mass of target nucleus
685  FirstInteraction->SetBranchAddress("depth", gDepth1); // slant depth
686  FirstInteraction->SetBranchAddress("height", gHeight1); // height
687 
688  FirstInteraction->SetBranchAddress("nPart", &gNParticles1); // number of particles
689  FirstInteraction->SetBranchAddress("Energy", gEnergy1);// energy
690  FirstInteraction->SetBranchAddress("px", gpx1);// Momentum px
691  FirstInteraction->SetBranchAddress("py", gpy1);// Momentum py
692  FirstInteraction->SetBranchAddress("pz", gpz1);// Momentum pz
693  FirstInteraction->SetBranchAddress("Type", gType1); // type
694  FirstInteraction->SetBranchAddress("idInt", gIdInt1); // interaction number
695 
696  ofstream fout(workdir + filename + ".longprofiles");
697  if (!fout) {
698  cout << "Error writing to file " << workdir+filename << ".longprofiles. Aborting ... \n" << endl;
699  return false;
700  }
701 
702  ofstream gout(workdir + filename + ".xmaxs");
703  if (!gout) {
704  cout << "Error writing to file " << workdir+filename << ".xmaxs. Aborting ... \n" << endl;
705  return false;
706  }
707 
708  vector<tupel> showers;
709 
710  for (int i = 0; i < nevent; ++i) {
711  fout << "\n\n#shower number " << i << '\n';
712  Shower->GetEntry(i);
713  Header->GetEntry(i);
714  FirstInteraction->GetEntry(i);
715 
716  for (long n = 0; n < nX; ++n) {
717  fout << X[n] << '\t' << N[n] << '\n';
718  }
719  showers.push_back(tupel(i, fitpars[9], gMult1[0], gpEnergy1[0], gEnergy1[0], gEnergy1[1], gEnergy1[2], gEnergy1[3])); // register shower
720  }
721 
722  sort(showers.begin(), showers.end()); // sort showers by xmax
723 
724  double averageXmax = 0;
725  for (vector<tupel>::const_iterator j = showers.begin(); j != showers.end(); ++j) {
726  gout << "Shower\t" << j->num << "\thas Xmax at:\t" << j->xmax << "\tg/cm^2 and of\t" << j->eg << "\tGeV first parts. have:\t" << j->e1 << ", " << j->e2 << ", " << j->e3 << ", " << j->e4 << '\n';
727  averageXmax += j->xmax/static_cast<double>(nevent);
728  }
729 
730  gout << "\nAverage Xmax is:\t" << averageXmax << " g/cm^2\n" << endl;
731 
732  fout.close();
733  gout.close();
734 
735  for (vector<tupel>::iterator j=showers.begin(); j!=showers.end(); ++j) {
736  j->avgxmax = averageXmax; // needed for sorting by quality - yes I know it's quick'n'dirty
737  }
738 
739  sort(showers.begin(), showers.end(), showers.front()); // sort by quality defined in tupel::operator()
740 
741  /*for (vector<tupel>::const_iterator j=showers.begin(); j!=showers.begin()+15; ++j)
742  {
743  cout << setprecision(5) << "Shower\t" << j->num << "\t" << j->xmax << "\t" << pow((1.f-fabs(j->xmax-j->avgxmax)/j->avgxmax),1.f) << "\t" << (1.-j->e1/j->eg) << "\t" << ((j->e1+j->e2+j->e3+j->e4)/(4.*j->e1)) << "\t" << j->quality() << "\n";
744  } */
745 
746  // loop through showers and sort out those with too high e1/eg
747  vector<tupel>::const_iterator selshower = showers.begin();
748  while ((selshower != showers.end()-1) && (selshower->e1/selshower->eg > maximumenergyfractioninfirstparticle)) {
749  ++selshower;
750  }
751 
752  cout << std::setprecision(5) << "Shower " << selshower->num << " has xmax of " << selshower->xmax
753  << " (avg: " << averageXmax << ") and of " << selshower->eg << " GeV "
754  "first parts. have: " << selshower->e1 << ", " << selshower->e2 << ", "
755  << selshower->e3 << ", " << selshower->e4 << std::setprecision(12) << '\n';
756 
757  ofstream hout(workdir + filename + ".gnu");
758  if (!hout) {
759  cout << "Error writing to file " << workdir+filename << ".gnu. Aborting ... \n" << endl;
760  return false;
761  }
762 
763  hout << "set term post enh col\nset outp \"" << filename << ".eps\"\n"
764  "set xlabel \"atmospheric depth [g cm^{-2}]\"\n"
765  "set ylabel \"num elec + posi\"\n"
766  "plot \"" << filename << ".longprofiles\" notitle, \"" << filename
767  << ".longprofiles\" index " << selshower->num << " lt 3, \"DAT"
768  << runnrstring << ".long\" using 1:($3+$4) lt 4\n";
769  // Caution: plot command is dependent on SLANT option!
770  hout.close();
771 
772  // now extract the particle stack
773  FirstInteraction->GetEntry(selshower->num); // select shower
774  stringstream selshowstringstream;
775  selshowstringstream << ".sh" << selshower->num;
776  selshowstring = selshowstringstream.str();
777 
778  ofstream sout(workdir + filename+selshowstring);
779  if (!sout) {
780  cout << "Error writing to file " << workdir+filename+selshowstring << ". Aborting ... \n" << endl;
781  return false;
782  }
783 
784  sout << " " << gMult1[0] << " " <<gpEnergy1[0] << endl;
785  //int oldFormat = sout.flags(ios::scientific);
786  //int oldPrecision = sout.precision(7);
787  for (int i = 0; i < gNParticles1; ++i) {
788  // Particles from the first interaction
789  if (gIdInt1[i] == 1)
790  sout << setw(5) << i+1 << setw(5) << gType1[i]
791  << setw(16) << gEnergy1[i]
792  << setw(16) << gpz1[i]
793  << setw(16) << gpx1[i]
794  << setw(16) << gpy1[i] << '\n';
795  }
796  sout << " Height (cm) : " << gHeight1[0]*100 << "\n"
797  " Target : " << gMatg1[0] << endl;
798 
799  firstintheight = gHeight1[0]*100;
800  firstinttarget = 1; // standard target is nitrogen
801  if (gMatg1[0] == 16) {
802  firstinttarget = 2;
803  } // if not nitrogen, it's oxygen
804 
805  delete f; // close root file
806  return true; // success
807  }
808 
809 }
Branch GetTopBranch() const
Definition: Branch.cc:63
boost::transform_iterator< InternalStationFunctor, InternalStationIterator, const Station & > StationIterator
StationIterator returns a pointer to a station.
Definition: RDetector.h:61
const double eV
Definition: GalacticUnits.h:35
utl::Vector GetAxis() const
Returns vector of the shower axis.
const double degree
Point object.
Definition: Point.h:32
const double tesla
Definition: GalacticUnits.h:40
void System(const char *const command, const bool throwOnError, const bool notify)
Definition: System.cc:10
Interface class to access Shower Reconstructed parameters.
Definition: ShowerRecData.h:33
Interface class to access to the Radio part of an event.
Definition: REvent.h:42
double GetR(const CoordinateSystemPtr &coordinateSystem) const
radius r in spherical coordinates coordinates (distance to origin)
Definition: BasicVector.h:257
double GetTheta(const CoordinateSystemPtr &coordinateSystem) const
zenith (theta) angle in spherical coordinates
Definition: BasicVector.h:248
Class to hold and convert a point in geodetic coordinates.
Definition: UTMPoint.h:40
StationIterator StationsEnd() const
End of the collection of pointers to commissioned stations.
Definition: RDetector.h:68
StationIterator StationsBegin() const
Beginning of the collection of pointers to commissioned stations.
Definition: RDetector.h:64
const double meter
Definition: GalacticUnits.h:29
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
static double GetDeclination(const utl::Point &position, const utl::TimeStamp &time)
returns declination in radians
void Init()
Initialise the registry.
vector< t2list > out
output of the algorithm: a list of clusters
Definition: XbAlgo.cc:32
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
double pow(const double x, const unsigned int i)
ShowerRRecData & GetRRecShower()
ShowerSRecData & GetSRecShower()
A TimeStamp holds GPS second and nanosecond for some event.
Definition: TimeStamp.h:110
const utl::TimeStamp & GetTime() const
Definition: Event/Header.h:33
Detector description interface for RDetector-related data.
Definition: RDetector.h:46
T Get() const
Definition: Branch.h:271
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
Class representing a document branch.
Definition: Branch.h:107
double GetHeight() const
Get the height.
Definition: UTMPoint.h:212
double GetX(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:206
static MagneticFieldModel & instance()
Header & GetHeader()
access to REvent Header
Definition: REvent.h:239
Top of the hierarchy of the detector description interface.
Definition: Detector.h:81
const sdet::SDetector & GetSDetector() const
Definition: Detector.cc:119
static utl::Vector GetMagneticFieldVector(const utl::Point &position, const utl::TimeStamp &time)
returns the magnetic field at a specific place at a specific time
const utl::Vector & GetAxis() const
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
double GetEnergy() const
int GetMonth() const
Definition: UTCDate.h:46
const std::string & GetId() const
Get the event identifier.
Definition: Event/Header.h:31
double GetY(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:209
double Distance(const Point &p, const sdet::Station &s)
constexpr double GeV
Definition: AugerUnits.h:187
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
boost::tokenizer< boost::char_separator< char > > mytok
int GetRunNumber() const
Event id in the run (Start at zero at the beginning of each run) /provided by the daq...
Definition: REvent/Header.h:22
unsigned long GetGPSSecond() const
GPS second.
Definition: TimeStamp.h:124
double GetGPSNanoSecond() const
GPS nanosecond.
Definition: TimeStamp.h:127
Header file holding the RD Event Trigger class definition (based on SD)
Definition: REvent/Header.h:14
constexpr double cm
Definition: AugerUnits.h:117
Vector object.
Definition: Vector.h:30
Detector description interface for SDetector-related data.
Definition: SDetector.h:42
const utl::Point & GetCorePosition() const
utl::Point GetCorePosition() const
returns pointer of the position vector of the core in the reference coor system
constexpr double micro
Definition: AugerUnits.h:65
const rdet::RDetector & GetRDetector() const
Definition: Detector.cc:143
utl::CoordinateSystemPtr Get(const std::string &id)
Get a well-known Coordinate System.
double GetParameter(const Parameter i) const
char * filename
Definition: dump1090.h:266
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:212
static Policy::type Create(const utl::Point &theOrigin)
Create the standard local coordinate system for a Point.
double Mu(const double energy, const double massNumber, const HadronicInteractionModel hadModel)
int GetId() const
Definition: REvent/Header.h:21
Definition: Line.h:17
Global event header.
Definition: Event/Header.h:27
constexpr double electronvolt
Definition: AugerUnits.h:172

, generated on Tue Sep 26 2023.