ADST2CORSIKA.cc
Go to the documentation of this file.
1 #include <TROOT.h>
2 #include <TFile.h>
3 #include <TMath.h>
4 #include <TVector3.h>
5 #include <TSystem.h>
6 #include <TH1D.h>
7 #include <TH2D.h>
8 #include <TProfile.h>
9 
10 #include <iomanip>
11 #include <iostream>
12 #include <string>
13 #include <cmath>
14 #include <sstream>
15 #include <vector>
16 #include <algorithm>
17 #include <cmath>
18 #include <cstdio>
19 #include <iterator>
20 #include <fstream>
21 #include <algorithm>
22 #include <map>
23 
24 #include <RecEvent.h>
25 #include <RecEventFile.h>
26 #include <FileInfo.h>
27 #include <DetectorGeometry.h>
28 #include <EyeGeometry.h>
29 #include <FDEvent.h>
30 #include <EventInfo.h>
31 #include <Shower.h>
32 #include <GenShower.h>
33 #include <FdGenShower.h>
34 #include <TelescopeGeometry.h>
35 #include <FdTelescopeData.h>
36 #include <FdApertureLight.h>
37 #include <FdGeometry.h>
38 #include <FdApertureLight.h>
39 
40 #define BOOST_SYSTEM_NO_DEPRECATED
41 #include <boost/algorithm/string.hpp>
42 #include <boost/lexical_cast.hpp>
43 #include <boost/filesystem.hpp>
44 
45 #include <chrono>
46 #include <thread>
47 
48 using namespace std;
49 
50 
51 const bool uniqueFileNames = true; // discard path information
52 
53 
54 void
55 writeSteeringCard(boost::filesystem::path steerdir,
56  const int iRun,
57  const double energyGeV,
58  const double thetaDeg,
59  const double phiDeg,
60  const double arrangDeg,
61  const double obslevCM,
62  const double corexCM,
63  const double coreyCM)
64 {
65  map<string,string> mapping;
66  mapping["@RUNNR@"] = boost::lexical_cast<std::string>(iRun);
67  mapping["@ENERGY@"] = boost::lexical_cast<std::string>(energyGeV);
68  mapping["@THETA@"] = boost::lexical_cast<std::string>(thetaDeg);
69  mapping["@PHI@"] = boost::lexical_cast<std::string>(phiDeg);
70  mapping["@SEED1@"] = boost::lexical_cast<std::string>(iRun*3+1);
71  mapping["@SEED2@"] = boost::lexical_cast<std::string>(iRun*3+2);
72  mapping["@SEED3@"] = boost::lexical_cast<std::string>(iRun*3+3);
73  mapping["@ARRANG@"] = boost::lexical_cast<std::string>(arrangDeg);
74  mapping["@OBSLEV@"] = boost::lexical_cast<std::string>(obslevCM);
75  mapping["@COREX@"] = boost::lexical_cast<std::string>(corexCM);
76  mapping["@COREY@"] = boost::lexical_cast<std::string>(coreyCM);
77  ostringstream oname;
78  oname << "DAT" << setw(6) << setfill('0') << iRun << ".inp";
79  if (boost::filesystem::exists(steerdir / oname.str())) {
80  cout << "output steering card " << (steerdir / oname.str()).string() << " already exists!" << endl;
81  exit(1);
82  }
83  ifstream input("DATxxxxxx_inp.template");
84  ofstream output((steerdir / oname.str()).string().c_str());
85  while (input.good() && output.good()) {
86  string line;
87  getline(input, line);
88  for (const auto& replace : mapping)
89  boost::replace_all(line, replace.first, replace.second);
90  output << line << endl;
91  }
92  input.close();
93  output.close();
94 }
95 
96 
97 void
98 ADST2CORSIKA(boost::filesystem::path steerdir,
99  const vector<string>& inputs)
100 {
101  const double degree = 180 / M_PI;
102 
103  map<string,map<int,int>> mapADST;
104  map<int,pair<string,int>> mapCORS;
105  {
106  cout << "checking lock: " << (steerdir / "ShowerInfo2CORSIKA.txt-LOCK").string() << endl;
107  bool isLocked = true;
108  do {
109  while (boost::filesystem::exists(steerdir / "ShowerInfo2CORSIKA.txt-LOCK")) { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); /* wait */ }
110  std::ofstream lock ((steerdir / "ShowerInfo2CORSIKA.txt-LOCK").string());
111  isLocked &= lock.good();
112  lock << " ";
113  isLocked &= lock.good();
114  lock.close();
115  isLocked &= lock.good();
116  } while(!isLocked);
117  cout << "locked: " << (steerdir / "ShowerInfo2CORSIKA.txt-LOCK").string() << endl;
118 
119  ifstream infile;
120  infile.open ((steerdir / "ShowerInfo2CORSIKA.txt").string());
121  if (infile.good()) {
122  string line;
123  while(std::getline(infile, line)) {
124  string adst = line.substr(line.find(" file=")+6, line.find(" ", line.find(" file=")+6)-line.find(" file=")-6);
125  string evt_id = line.substr(line.find(" id=")+4, line.find(" ", line.find(" id=")+4)-line.find(" id=")-4);
126  int evt = atoi((evt_id.substr(evt_id.find(":Use_")+5, evt_id.length()-evt_id.find(":Use_")-5)).c_str());
127  int cors = atoi((line.substr(line.find(" corsikaID=")+11, line.find(" ", line.find(" corsikaID=")+11)-line.find(" corsikaID=")-11)).c_str());
128  if (uniqueFileNames)
129  adst = adst.substr(adst.rfind('/')+1, adst.length()-adst.rfind('/')-1);
130  mapADST[adst][evt] = cors;
131  mapCORS[cors] = std::make_pair(adst, evt);
132  // cout << line << " " << adst << " " << evt << " " << cors << endl;
133  }
134  infile.close();
135  }
136  }
137 
138  ofstream outfile;
139  outfile.open ((steerdir / "ShowerInfo2CORSIKA.txt").string(), std::ofstream::app);
140 
141  RecEvent* theRecEvent = new RecEvent();
142  DetectorGeometry* theGeometry = 0;
143  theGeometry = new DetectorGeometry();
144  FileInfo theInfo;
145 
146  unsigned int countFile = 0;
147  unsigned int countEvent = 0;
148  unsigned int countSelected = 0;
149  unsigned int countSelectedNew = 0;
150  unsigned int countSelectedAndReco = 0;
151  unsigned int countHeatFOV = 0;
152  unsigned int countMiss = 0; // count missing Cherenkov events
153 
154  for (const auto& input : inputs) {
155 
156  ++countFile;
157 
158  //if (countFile>100)
159  //break;
160 
161  RecEventFile dataFile(input.c_str());
162  dataFile.SetBuffers(&theRecEvent);
163  dataFile.ReadDetectorGeometry(*theGeometry);
164  dataFile.ReadFileInfo(theInfo);
165 
166  //const double HeightOfRefCSOriginMeter = 1400; // from Offline xml
167  double ObservationLevelMeter = 1300; // CORSIKA observation level [m]
168  double diffangleDeg = -85.767; // CORSIKA Array rotation ARRANG [degree]
169 
170  unsigned int countInFile = 0;
171 
172  while(dataFile.ReadNextEvent() == RecEventFile::eSuccess){
173 
174  const string EventID = theRecEvent->GetEventId();
175  const int EventID_int = atoi((EventID.substr(EventID.find(":Use_")+5, EventID.length()-EventID.find(":Use_")-5)).c_str());
176 
177  ++countEvent;
178  ++countInFile;
179 
180  TVector3 shower_axis = theRecEvent->GetGenShower().GetAxisSiteCS();
181 
182  // this return core at relative height in reference-CS (ePampaAmarilla)
183  //#warning there was a bug in corsika TELOUT. Check next time that this works:
184  TVector3 shower_core = theRecEvent->GetGenShower().GetCoreAtAltitudeSiteCS(ObservationLevelMeter);//-HeightOfRefCSOriginMeter);
185 
186  // find hottest Sim tel over all eyes
187 
188  int hottestEye = -1;
189  int hottestTel = -1;
190  double hottestTelPhotons = -1;
191  for (RecEvent::EyeIterator eyeIt= theRecEvent->EyesBegin();
192  eyeIt !=theRecEvent->EyesEnd();
193  ++eyeIt){
194  const int eyeId = eyeIt->GetEyeId();
195  //if (eyeId != 5) // only heat
196  //continue;
197  for (FDEvent::TelescopeDataConstIterator telIt = eyeIt->TelescopeDataBegin();
198  telIt != eyeIt->TelescopeDataEnd(); ++telIt) {
199  const FdTelescopeData& telData = telIt->second;
200  const FdApertureLight& theGenlight = telData.GetGenApertureLight();
201  const vector<double>& vecTotal = theGenlight.GetTotalLightAtAperture();
202  double totalPhotonsTel = 0;
203  for (const auto& itot : vecTotal) {totalPhotonsTel += itot;}
204  if (totalPhotonsTel > hottestTelPhotons) {
205  hottestEye = eyeId;
206  hottestTel = telIt->first;
207  hottestTelPhotons = totalPhotonsTel;
208  }
209  }
210  }
211 
212  int selectedEye = 0;
213  double genCherPhotons = 0;
214  double genTotalPhotons = 0;
215  double genMeanAngle = -1;
216 
217  if (hottestTelPhotons>0) { // no HEAT... ?
218 
219  const FDEvent& eye = theRecEvent->GetEye(hottestEye);
220  const FdTelescopeData& telData = eye.GetTelescopeData(hottestTel);
221 
222  const int eyeId = eye.GetEyeId();
223  selectedEye = eyeId;
224 
225  const FdApertureLight& theGenlight = telData.GetGenApertureLight();
226  const vector<double>& vecCher = theGenlight.GetCherLightAtAperture();
227  const vector<double>& vecTotal = theGenlight.GetTotalLightAtAperture();
228  for (const auto& icher : vecCher) {genCherPhotons += icher;}
229  for (const auto& itot : vecTotal) {genTotalPhotons += itot;}
230 
231  genMeanAngle = theGenlight.GetMeanAngle() * degree;
232 
233  /*
234  if (genTotalPhotons>100 && genMeanAngle<40 && eyeId==5) {
235  isHeatFOV = true;
236  }
237  */
238  }
239 
240  //fill a text file with shower info to fed to CORSIKA steering cards. For showers with cherenkov fraction more than 50%
241 
242  int Prim = theRecEvent->GetGenShower().GetPrimary();
243  double ZenithDeg = theRecEvent->GetGenShower().GetAxisSiteCS().Theta() * degree; //in degree
244  double EnergyGeV = (theRecEvent->GetGenShower().GetEnergy())/pow(10,9);//crosika use energy in Gev
245  double Azimuth_correctedDeg = theRecEvent->GetGenShower().GetAxisSiteCS().Phi() * degree; // in degree
246  Azimuth_correctedDeg += diffangleDeg + 180;
247  if (Azimuth_correctedDeg<0) Azimuth_correctedDeg += 360;
248  if (Azimuth_correctedDeg>360) Azimuth_correctedDeg -= 360;
249  double x_posCM =(shower_core.X()) * pow(10,2); //corsika use cm
250  double y_posCM =(shower_core.Y()) * pow(10,2);
251  //vdouble z_pos =(shower_core.Z()) * pow(10,2);
252 
253  // DATyyyxxx
254  // yyy: file ID
255  // xxx: event ID
256  int corsikaID = 1; //(countFile*1000 + countSelected%1000) % 1000000; // not above 999999
257  // ostringstream << setw(3) << setfill('0') << countFile << setw(3) << setfill('0') << countSelected;
258 
259  ++countSelected;
260 
261  // input file can be "presel_adst.root" or just "adst.root"
262  string input_test = input, input_test_alt;
263  if (input.find("presel") == string::npos) {
264  input_test_alt = input.substr(0, input.find("adst.root")) + "presel_adst.root";
265  } else {
266  input_test_alt = input.substr(0, input.rfind("presel_adst.root")) + "adst.root";
267  }
268 
269  if (uniqueFileNames) {
270  input_test = input_test.substr(input_test.rfind('/')+1, input_test.length()-input_test.rfind('/')-1);
271  input_test_alt = input_test_alt.substr(input_test_alt.rfind('/')+1, input_test_alt.length()-input_test_alt.rfind('/')-1);
272  }
273 
274  if (mapADST.count(input_test)>0 && mapADST[input_test].count(EventID_int)>0) {
275 
276  cout << input << " evt=" << EventID_int << " already converted to CORSIKA steering card (" << mapADST[input_test][EventID_int] << ")" << endl;
277 
278  } else if (mapADST.count(input_test_alt)>0 && mapADST[input_test_alt].count(EventID_int)>0) {
279 
280  cout << input << " evt=" << EventID_int << " already converted to CORSIKA steering card (" << mapADST[input_test_alt][EventID_int] << ")" << endl;
281 
282  } else {
283 
284  while(mapCORS.count(corsikaID)>0) {
285  // cout << "found duplicate CORSIKA ID=" << corsikaID << " already. Avoid. Try next. " << endl;
286  ++corsikaID;
287  }
288 
289  ++countSelectedNew;
290 
291  if (true) {
292  writeSteeringCard(steerdir,
293  corsikaID,
294  EnergyGeV,
295  ZenithDeg,
296  Azimuth_correctedDeg,
297  diffangleDeg,
298  ObservationLevelMeter*100,
299  x_posCM,
300  y_posCM);
301 
302  outfile << Prim << " " << EnergyGeV << " " << ZenithDeg <<" "<< Azimuth_correctedDeg << " "<< x_posCM << " " << y_posCM << " "<< " "<<ObservationLevelMeter*100. <<" "<< diffangleDeg << " file=" << input << " id="<<EventID << " eye=" << selectedEye << " tot=" << genTotalPhotons << " ch=" << genCherPhotons << " ViewAngle=" << genMeanAngle << " corsikaID=" << corsikaID << " EventID_int=" << EventID_int << endl;
303  }
304 
305  mapADST[input][EventID_int] = corsikaID;
306  mapCORS[corsikaID] = make_pair(input,EventID_int);
307  } // end new shower
308 
309  } // events loop
310 
311  } // file loop
312 
313  // ********************************************
314  outfile.close();
315 
316  cout << "Finished: countFile=" << countFile << " countEvent=" << countEvent
317  << " countSelected=" << countSelected << " countSelectedNew=" << countSelectedNew
318  << " countSelectedAndReco=" << countSelectedAndReco
319  << " countHeatFOV=" << countHeatFOV
320  << " countMiss=" << countMiss << " (w/ chFrac>0.5)"
321  << endl;
322 
323  boost::filesystem::remove( steerdir / "ShowerInfo2CORSIKA.txt-LOCK");
324  cout << "unlocked: " << (steerdir / "ShowerInfo2CORSIKA.txt-LOCK").string() << endl;
325 }
326 
327 
328 
329 
330 int
331 main(int argc, char** argv)
332 {
333  if (argc<3) {
334  cout << " specify steerdir AND input file" << endl;
335  return 1;
336  }
337  const string steerdir(argv[1]);
338  boost::filesystem::path dir(steerdir);
339  if (!boost::filesystem::is_directory(dir)) {
340  cout << " specify steerdir AND input file" << endl;
341  cout << dir << " is not a directory" << endl;
342  return 1;
343  }
344 
345  vector<string> inputs;
346  for (int i=1; i<argc-1; ++i)
347  inputs.push_back(string(argv[i+1]));
348  ADST2CORSIKA(steerdir, inputs);
349  return 0;
350 }
351 
const double degree
void writeSteeringCard(boost::filesystem::path steerdir, const int iRun, const double energyGeV, const double thetaDeg, const double phiDeg, const double arrangDeg, const double obslevCM, const double corexCM, const double coreyCM)
Definition: ADST2CORSIKA.cc:55
double pow(const double x, const unsigned int i)
int exit
Definition: dump1090.h:237
char * exists
Definition: XbArray.cc:12
int main(int argc, char *argv[])
Definition: DBSync.cc:58
void ADST2CORSIKA(boost::filesystem::path steerdir, const vector< string > &inputs)
Definition: ADST2CORSIKA.cc:98
const bool uniqueFileNames
Definition: ADST2CORSIKA.cc:51

, generated on Tue Sep 26 2023.