13 #include <utl/config.h>
14 #include <utl/Reader.h>
15 #include <utl/ErrorLogger.h>
16 #include <utl/AugerUnits.h>
17 #include <utl/MathConstants.h>
19 #include <utl/PhysicalConstants.h>
20 #include <utl/PhysicalFunctions.h>
21 #include <utl/Point.h>
22 #include <utl/TabulatedFunction.h>
23 #include <utl/TabulatedFunctionErrors.h>
24 #include <utl/Trace.h>
25 #include <utl/MultiTabulatedFunction.h>
26 #include <utl/Photon.h>
27 #include <utl/RandomEngine.h>
28 #include <utl/UTMPoint.h>
29 #include <utl/SaveCurrentTDirectory.h>
31 #include <fwk/CentralConfig.h>
32 #include <fwk/CoordinateSystemRegistry.h>
33 #include <fwk/RandomEngineRegistry.h>
34 #include <fwk/GITGlobalRevision.h>
36 #include <det/Detector.h>
38 #include <fdet/FDetector.h>
40 #include <fdet/Telescope.h>
41 #include <fdet/Camera.h>
42 #include <fdet/Pixel.h>
43 #include <fdet/Channel.h>
44 #include <fdet/Mirror.h>
45 #include <fdet/Filter.h>
46 #include <fdet/Corrector.h>
48 #include <evt/Event.h>
49 #include <evt/ShowerSimData.h>
50 #include <evt/LaserData.h>
52 #include <fevt/FEvent.h>
54 #include <fevt/TelescopeSimData.h>
55 #include <fevt/Telescope.h>
56 #include <fevt/PixelSimData.h>
57 #include <fevt/Pixel.h>
59 #include <atm/ProfileResult.h>
60 #include <atm/InclinedAtmosphericProfile.h>
62 #include <CLHEP/Random/Randomize.h>
64 #include <boost/tuple/tuple.hpp>
66 #include <TDirectory.h>
74 using namespace DrumPhotonGeneratorOG;
83 using CLHEP::RandFlat;
102 err <<
"Missing configuration file for DrumPhotonGenerator";
107 fRandomEngine = &RandomEngineRegistry::GetInstance().Get(RandomEngineRegistry::eDetector);
130 << GetVersionInfo(VModule::eRevisionNumber) <<
"\n"
132 " min accuracy: " << fMinAccuracy <<
"\n"
133 " number of photons: " << fNDrumPhotons <<
"\n"
134 " nCos: " << fDrumNCos;
136 info <<
" (isotropic)\n";
138 info <<
" (lambertian)\n";
139 info <<
" min theta: " << setw(3) << fThetaMinDrumPhotons/
deg <<
"deg\n"
140 " max theta: " << setw(3) << fThetaMaxDrumPhotons/
deg <<
"deg\n"
141 " min phi: " << setw(3) << fPhiMinDrumPhotons/
deg <<
"deg\n"
142 " max phi: " << setw(3) << fPhiMaxDrumPhotons/
deg <<
"deg\n"
143 " min radius: " << setw(3) << fRDiaMin/
m <<
"m\n"
144 " min bin: " << fMinBin <<
"\n"
145 " max bin: " << fMaxBin <<
"\n"
146 " drum-data output: " << fDrumDataOutName;
150 fStatus = eGeneratePhotons;
159 Detector& detector = Detector::GetInstance();
163 ERROR(
"No FEvent. Check your ModuleSequence.");
170 INFO(
"Creating FEvent");
177 event.GetHeader().SetTime(simTime);
180 event.GetHeader().SetId(idStr.str());
183 iEye != detFD.
EyesEnd() ; ++iEye) {
184 const unsigned int eyeId = iEye->GetId();
190 iTel != iEye->TelescopesEnd(); ++iTel) {
191 const unsigned int telId = iTel->
GetId();
194 ERROR(
"Telescope already there");
197 const int index = Index(eyeId, telId);
198 fTotalGeneratedPhotonsPerTelescope[index] = 0;
212 if (CalculateCalibrationConstants(event))
214 else if (DoDrum(event))
226 bool accuracyNotYetReached =
false;
230 const int eyeId = iEye->GetId();
234 const int telId = iTel->GetId();
235 const int index = Index(eyeId, telId);
241 info1 <<
"calibrating eye: " << eyeId <<
", telescope: " << telId
242 <<
", nTotalPhotons: " << fTotalGeneratedPhotonsPerTelescope[index] ;
248 double meanAccuracy = 100.;
249 double minAccuracy = 100.;
250 double maxAccuracy = 100.;
251 double meanCal = 100.;
252 double minCal = 100.;
253 double maxCal = 100.;
254 bool firstAccuracy =
true;
257 for (map<int, CalibResult>::const_iterator iCal = constants.begin();
258 iCal != constants.end(); ++iCal) {
260 if (iCal->second.calib <= 0)
264 const double accuracy = iCal->second.calibErr / iCal->second.calib;
267 firstAccuracy =
false;
268 meanAccuracy = accuracy;
269 minAccuracy = accuracy;
270 maxAccuracy = accuracy;
271 meanCal = iCal->second.calib;
272 minCal = iCal->second.calib;
273 maxCal = iCal->second.calib;
275 meanAccuracy += accuracy;
276 if (accuracy < minAccuracy)
277 minAccuracy = accuracy;
278 if (accuracy > maxAccuracy)
279 maxAccuracy = accuracy;
280 meanCal += iCal->second.calib;
281 if (iCal->second.calib < minCal)
282 minCal = iCal->second.calib;
283 if (iCal->second.calib > maxCal)
284 maxCal = iCal->second.calib;
289 meanAccuracy /= countPixels;
290 meanCal /= countPixels;
292 ostringstream info2, info3;
293 info2 <<
"-> accuracy (min/max/mean): " << minAccuracy <<
" / " << maxAccuracy <<
" / " << meanAccuracy;
294 info3 <<
"-> calib (min/max/mean): " << minCal <<
" / " << maxCal <<
" / " << meanCal;
299 if (maxAccuracy > fMinAccuracy) {
301 GenerateDrumPhotons(*iTel);
302 accuracyNotYetReached =
true;
305 info2 <<
"===> Accuracy in this telescope is reached. Switching it off now. ";
316 if (accuracyNotYetReached)
319 INFO(
"Drum photon precision achieved.");
320 fStatus = eCalibrate;
330 info <<
"Generating " << fNDrumPhotons <<
" photons from drum";
333 const unsigned int telId = tel.
GetId();
334 const int index = Index(tel.
GetEyeId(), telId);
336 Detector& detector = Detector::GetInstance();
337 const FDetector& detFD = detector.GetFDetector();
348 fTotalGeneratedPhotonsPerTelescope[index] += fNDrumPhotons;
350 map<int, TraceD*> traces;
351 for (
int i = 0; i < fNDrumPhotons; i++) {
353 double diaPh = RandFlat::shoot(&fRandomEngine->GetEngine(), 0.0, 2*
kPi);
354 double diaR =
sqrt(RandFlat::shoot(&fRandomEngine->GetEngine(),
355 fRDiaMin*fRDiaMin, rDia*rDia));
357 double xDia = diaR*cos(diaPh);
358 double yDia = diaR*sin(diaPh);
359 Point pIn(xDia, yDia, 0.0, telCS);
362 double phi = RandFlat::shoot(&fRandomEngine->GetEngine(),
363 fPhiMinDrumPhotons, fPhiMaxDrumPhotons);
364 double ncos = fDrumNCos;
365 double theta_1 =
std::pow(cos(fThetaMinDrumPhotons), ncos+1);
366 double theta_2 =
std::pow(cos(fThetaMaxDrumPhotons), ncos+1);
368 double tmp = (theta_2-theta_1) * RandFlat::shoot(&fRandomEngine->GetEngine(),
372 if (ncos == 0) theta = acos(tmp);
373 else if (ncos == 1) theta = acos(
sqrt(tmp));
374 else theta = acos(exp(log(tmp) / (1.+ncos) ) );
376 Vector nIn (1., theta, phi, telCS, Vector::kSpherical);
379 double time = binWidth * RandFlat::shoot(&fRandomEngine->GetEngine(), fMinBin, fMaxBin);
380 const double weight = 1.0;
381 utl::Photon photonIn(pIn, nIn, normWavelength, weight);
392 if (fStatus == eGeneratePhotons)
394 if (fStatus == eCalibrated) {
395 ERROR(
" CANNOT RE-CALIBRATE CALIBRATED TELESCOPE !!!!!!!!!!!!!!!!!!!!! ");
398 fStatus = eCalibrated;
400 INFO(
"Calibrate telescopes ....");
404 Detector& detector = Detector::GetInstance();
407 ofstream calibXml(
"FSimulationCalibConfig.generated.xml.in");
408 calibXml <<
"<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n\n"
409 "<FSimulationCalibConfig\n"
410 " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
411 " xsi:noNamespaceSchemaLocation='@XMLSCHEMALOCATION@/FSimulationCalibConfig.xsd'>\n\n"
412 " <!-- these are used for the flatfielding -->\n\n";
415 TFile*
const drumDataFile = TFile::Open(fDrumDataOutName.c_str(),
"UPDATE");
417 TTree*
const runInfo =
new TTree(
"runInfo",
"runInfo");
421 const int eyeId = iEye->GetId();
425 const int telId = iTel->GetId();
426 const int index = Index(eyeId, telId);
432 calibXml <<
" <!-- \n"
433 " This set of calibration constants was generated using Offline revision "
434 << fwk::GITGlobalRevision::GetInstance().GetId() <<
"\n"
435 " with the following set of configuration parameters:\n"
436 "\"" << configList <<
"\"\n"
437 " The following Md5-hex-digest encodes this list:\n"
439 " <EndToEnd signature=\"" << md5 <<
"\"> \n"
440 " <calibration>" << endl;
443 ostringstream treeName;
444 treeName <<
"drumData_" << index;
445 TTree*
const drumData =
new TTree(treeName.str().c_str(), treeName.str().c_str());
447 double drumData_nGen, drumData_nPix, drumData_calib, drumData_calibErr, drumData_elecFact;
448 drumData->Branch(
"id", &drumData_id,
"id/I");
449 drumData->Branch(
"nGen", &drumData_nGen,
"nGen/D");
450 drumData->Branch(
"nPix", &drumData_nPix,
"nPix/D");
451 drumData->Branch(
"calib", &drumData_calib,
"calib/D");
452 drumData->Branch(
"calibErr", &drumData_calibErr,
"calibErr/D");
453 drumData->Branch(
"electronicsFactor", &drumData_elecFact,
"electronicsFactor/D");
461 const double meanPixelSolid = 5.94e-4 *
sr;
464 const double flux_drum_perp =
465 fTotalGeneratedPhotonsPerTelescope[index] / (diaArea * M_PI * (1 -
pow(cos(fThetaMaxDrumPhotons), 2)));
467 ostringstream info1, info2;
468 info1 <<
" Eye: " << eyeId <<
", Telescope: " << telId
470 <<
", Signature: " << md5 <<
"\n"
471 "total number of ph.: " << fTotalGeneratedPhotonsPerTelescope[index] <<
" photons\n"
472 " perp. drum flux: " << flux_drum_perp *
cm2 *
sr <<
"1/(cm^2 deg^2)" <<
"\n"
473 " mean pixel photons: " << flux_drum_perp * diaArea * meanPixelSolid <<
" photons ";
478 const string tree_rev = fwk::GITGlobalRevision::GetInstance().GetId();
479 if (!runInfo->GetBranch(
"index")) {
480 runInfo->Branch(
"index", const_cast<int*>(&index),
"index/I");
481 runInfo->Branch(
"nPhotonsTot", &fTotalGeneratedPhotonsPerTelescope[index],
"nPhotonsTot/i");
482 runInfo->Branch(
"md5", const_cast<char*>(md5.c_str()),
"md5/C");
483 runInfo->Branch(
"offline_rev", const_cast<char*>(tree_rev.c_str()),
"offline_rev/C");
484 runInfo->Branch(
"config", const_cast<char*>(configList.c_str()),
"config/C");
486 runInfo->SetBranchAddress(
"index", const_cast<int*>(&index));
487 runInfo->SetBranchAddress(
"nPhotonsTot", &fTotalGeneratedPhotonsPerTelescope[index]);
488 runInfo->SetBranchAddress(
"md5", const_cast<char*>(md5.c_str()));
489 runInfo->SetBranchAddress(
"offline_rev", const_cast<char*>(tree_rev.c_str()));
490 runInfo->SetBranchAddress(
"config", const_cast<char*>(configList.c_str()));
497 const int pixelId = iPix;
499 const double calib = constants[pixelId].calib;
500 const double calibErr = constants[pixelId].calibErr;
502 info2 <<
" pixel id=" << setw(4) << pixelId
503 <<
" s=" << setw(10) << fixed << calib
504 <<
" +- " << setw(10) << calibErr <<
" [ph/ADC]"
507 calibXml <<
" " << setprecision(16) << setw(18) << calib
508 <<
" <!-- +- " << setw(18) << calibErr <<
" -->\n";
510 drumData_id = pixelId;
511 drumData_nGen = constants[pixelId].nPhotGen;
512 drumData_nPix = constants[pixelId].nPhotPixel;
513 drumData_calib = constants[pixelId].calib;
514 drumData_calibErr = constants[pixelId].calibErr;
515 drumData_elecFact = constants[pixelId].electronicsFactor;
522 calibXml <<
" </calibration>\n"
530 calibXml <<
"</FSimulationCalibConfig>\n";
534 drumDataFile->Write();
535 drumDataFile->Close();
537 INFO(
"Telescope(s) calibrated! Output in file \"FSimulationCalibConfig.generated.xml.in\".");
543 map<int, DrumPhotonGenerator::CalibResult>
546 const int telId = tel.
GetId();
548 const int index = Index(eyeId, telId);
550 Detector& detector = Detector::GetInstance();
558 const double flux_drum_perp = fTotalGeneratedPhotonsPerTelescope[index] /
559 (diaArea * M_PI * (1 -
pow(cos(fThetaMaxDrumPhotons), 2)));
561 map<int, CalibResult> constants;
562 if (fTotalGeneratedPhotonsPerTelescope[index] == 0)
579 double pixelPhotons = 0;
580 for (
unsigned int i = 0; i < photonTrace.
GetSize(); ++i)
581 pixelPhotons += photonTrace[i];
584 const double nGenPhotons = flux_drum_perp * diaArea * pixelSolid;
586 const double epsilon = pixelPhotons / nGenPhotons;
587 const double epsilonErr =
sqrt((epsilon - epsilon*epsilon) / nGenPhotons);
592 const double calib = 1 / (epsilon * qEff *
gain);
593 const double calibErr = epsilonErr / (epsilon * epsilon * qEff *
gain);
595 constants[iPix].calib = calib;
596 constants[iPix].calibErr = calibErr;
597 constants[iPix].nPhotGen = nGenPhotons;
598 constants[iPix].nPhotPixel = pixelPhotons;
599 constants[iPix].electronicsFactor = qEff *
gain;
Telescope & GetTelescope(const unsigned int telescopeId, const ComponentSelector::Status status=ComponentSelector::eHasData)
Retrieve Telescope by Id, throw exception if not existent.
unsigned int GetId() const
double GetFADCBinSize() const
Description of the electronic channel for the 480 channels of the crate.
Fluorescence Detector Eye Event.
unsigned int GetFirstPixelId() const
const Pixel & GetPixel(const fevt::Pixel &eventPixel) const
Get fdet::Pixel from fevt::Channel.
utl::TimeStamp GetTime() const
Get time pertaining to the detector description.
const std::string & GetConfigSignatureStr() const
EyeIterator EyesEnd(const ComponentSelector::Status status)
double GetDiaphragmRadius() const
unsigned int GetEyeId() const
std::map< int, CalibResult > CalibrateTelescope(fevt::Telescope &tel)
#define INFO(message)
Macro for logging informational messages.
fwk::VModule::ResultFlag Run(evt::Event &event)
Run: invoked once per event.
PixelSimData & GetSimData()
void AddPhoton(const utl::Photon &p)
void MakeEye(const unsigned int eyeId, const ComponentSelector::Status status=ComponentSelector::eHasData)
EyeIterator EyesBegin(const FDetComponentSelector::Type type=FDetComponentSelector::ePhysical) const
iterator pointing to first eye of given type (ePhysical, eVirtual, eAll)
boost::filter_iterator< ComponentSelector, AllEyeIterator > EyeIterator
selective Eye iterators
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
double pow(const double x, const unsigned int i)
void MakeTelescope(const unsigned int telescopeId, const ComponentSelector::Status status=ComponentSelector::eHasData)
Make Telescope telescopeId.
double GetElectronicsGain() const
const Camera & GetCamera() const
Get the Camera object that belongs to the telescope.
Detector description interface for FDetector-related data.
A TimeStamp holds GPS second and nanosecond for some event.
bool HasCorrectorRing() const
flag for corrector ring presence
void SetPhotonsStartTime(const utl::TimeStamp &ts)
double GetSolidAngle() const
The solid angle viewed by this pixel.
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
fevt::TelescopeSimData & GetSimData()
Description of simulated data for one Telescope.
Class representing a document branch.
unsigned int GetLastPixelId() const
utl::CoordinateSystemPtr GetTelescopeCoordinateSystem() const
boost::filter_iterator< FDetComponentSelector, AllEyeIterator > EyeIterator
Fluorescence Detector Pixel event.
void GenerateDrumPhotons(fevt::Telescope &tel)
const utl::TabulatedFunction & GetQEfficiency() const
Average quantum efficiency as a function of the wavelength.
Top of the hierarchy of the detector description interface.
EyeIterator EyesBegin(const ComponentSelector::Status status)
const Channel & GetChannel(const fevt::Channel &eventChannel) const
Get fdet::Channel from fevt::Channel.
const fdet::FDetector & GetFDetector() const
const std::string & GetConfigSignature() const
boost::filter_iterator< ComponentSelector, AllTelescopeIterator > TelescopeIterator
selective Telescope iterators
fwk::VModule::ResultFlag Finish()
Finish: invoked at end of the run (NOT end of the event)
void GetData(bool &b) const
Overloads of the GetData member template function.
Top of Fluorescence Detector event hierarchy.
Eye & GetEye(const unsigned int eyeId, const ComponentSelector::Status status=ComponentSelector::eHasData)
return Eye by id
double GetReferenceLambda() const
boost::filter_iterator< TelIsCommissioned, InternalConstTelescopeIterator > TelescopeIterator
An iterator over telescopes.
Pixel & GetPixel(const unsigned int pixelId, const ComponentSelector::Status status=ComponentSelector::eHasData)
Retrieve Pixel by Id, throw exception if not existent.
bool DoDrum(evt::Event &event)
bool CalculateCalibrationConstants(evt::Event &event)
Detector description interface for Telescope-related data.
A TimeInterval is used to represent time elapsed between two events.
ResultFlag
Flag returned by module methods to the RunController.
const Telescope & GetTelescope(const fevt::Telescope &eventTel) const
Get fdet::Telescope from fevt::Telescope.
unsigned int GetId() const
double GetDiaphragmArea() const
bool HasTelescope(const unsigned int telescopeId, const ComponentSelector::Status status=ComponentSelector::eHasData) const
Check if the telescope is in the event.
utl::TraceD & GetPhotonTrace(const FdConstants::LightSource source=FdConstants::eTotal)
Simulated Photon Trace.
Main configuration utility.
void ClearConfigSignature()
Fluorescence Detector Telescope Event.
double Y(const double x) const
Get or interpolate the Y value that corresponds to parameter x.
void SetTime(const utl::TimeInterval &t)
void SetNumberOfPhotonBins(const int n)
#define ERROR(message)
Macro for logging error messages.
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
fwk::VModule::ResultFlag Init()
Initialize: invoked at beginning of run (NOT beginning of event)
map< int, CalibResult > CalibrateTelescope(TChain *data)
Fluorescence Detector Pixel Simulated Data.
EyeIterator EyesEnd(const FDetComponentSelector::Type type=FDetComponentSelector::ePhysical) const
iterator pointing to end of available eyes of given type (ePhysical, eVirtual, eAll) ...