/* ======================================================================== *\ ! ! * ! * This file is part of MARS, the MAGIC Analysis and Reconstruction ! * Software. It is distributed to you in the hope that it can be a useful ! * and timesaving tool in analysing Data of imaging Cerenkov telescopes. ! * It is distributed WITHOUT ANY WARRANTY. ! * ! * Permission to use, copy, modify and distribute this software and its ! * documentation for any purpose is hereby granted without fee, ! * provided that the above copyright notice appear in all copies and ! * that both that copyright notice and this permission notice appear ! * in supporting documentation. It is provided "as is" without express ! * or implied warranty. ! * ! ! ! Author(s): Thomas Bretz 12/2000 ! Author(s): Harald Kornmayer 1/2001 ! ! Copyright: MAGIC Software Development, 2000-2002 ! ! \* ======================================================================== */ ////////////////////////////////////////////////////////////////////////////// // // MHMcCollectionAreaCalc // // Remark: The initialization is mainly done in the ReInit function. // Please make sure, that you don't use MReadTree when processing // a file. Use a 'ReInit'-calling task like MReadMarsFile // ////////////////////////////////////////////////////////////////////////////// #include "MMcCollectionAreaCalc.h" #include "MParList.h" #include "MLog.h" #include "MLogManip.h" #include "MMcEvt.hxx" #include "MMcTrig.hxx" #include "MMcRunHeader.hxx" #include "MMcCorsikaRunHeader.h" #include "MHMcCollectionArea.h" ClassImp(MMcCollectionAreaCalc); using namespace std; MMcCollectionAreaCalc::MMcCollectionAreaCalc(const char *input, const char *name, const char *title) { fName = name ? name : "MMcCollectionAreaCalc"; fTitle = title ? title : "Task to calculate the collection area"; fObjName = input ? input : "MMcTrig"; AddToBranchList(Form("%s.fNumFirstLevel", input)); AddToBranchList("MMcEvt.fEnergy"); AddToBranchList("MMcEvt.fImpact"); fCorsikaVersion = 0; fAllEvtsTriggered = kFALSE; fTotalNumSimulatedShowers = 0; fThetaMin = -1.; fThetaMax = -1.; } Int_t MMcCollectionAreaCalc::PreProcess (MParList *pList) { // connect the raw data with this task fMcEvt = (MMcEvt*)pList->FindObject("MMcEvt"); if (!fMcEvt) { *fLog << err << "MMcEvt not found... abort." << endl; return kFALSE; } return kTRUE; } Bool_t MMcCollectionAreaCalc::ReInit(MParList *plist) { fCollArea=0; MMcRunHeader *runheader = (MMcRunHeader*)plist->FindObject("MMcRunHeader"); if (!runheader) { *fLog << err << "Error - MMcRunHeader not found... abort." << endl; return kFALSE; } fTotalNumSimulatedShowers += runheader->GetNumSimulatedShowers(); *fLog << inf << "Total Number of Simulated showers: " << fTotalNumSimulatedShowers << endl; if ( (fThetaMin >= 0 && fThetaMin != runheader->GetShowerThetaMin()) || (fThetaMax >= 0 && fThetaMax != runheader->GetShowerThetaMax()) ) { *fLog << warn << "Warning - Read files have different Theta ranges ("; *fLog << "(" << fThetaMin << ", " << fThetaMax << ") vs (" << runheader->GetShowerThetaMin() << ", " << runheader->GetShowerThetaMax() << ")..." << endl; } fThetaMin = runheader->GetShowerThetaMin(); fThetaMax = runheader->GetShowerThetaMax(); if (fCorsikaVersion!=0 && fCorsikaVersion!=runheader->GetCorsikaVersion()) *fLog << warn << "Warning - Read files have different Corsika versions..." << endl; fCorsikaVersion = runheader->GetCorsikaVersion(); fAllEvtsTriggered |= runheader->GetAllEvtsTriggered(); *fLog << inf << "Only triggered events avail: " << (fAllEvtsTriggered?"yes":"no") << endl; fCollArea = (MHMcCollectionArea*)plist->FindCreateObj("MHMcCollectionArea"); if (!fCollArea) return kFALSE; if (!fAllEvtsTriggered) { fMcTrig = (MMcTrig*)plist->FindObject(fObjName); if (!fMcTrig) { *fLog << err << fObjName << " [MMcTrig] not found... anort." << endl; return kFALSE; } return kTRUE; } MMcCorsikaRunHeader *corrunheader = (MMcCorsikaRunHeader*)plist->FindObject("MMcCorsikaRunHeader"); if (!corrunheader) { *fLog << err << "MMcCorsikaRunHeader not found... abort." << endl; return kFALSE; } // // Calculate approximately the original number of events in each // energy bin: // const Float_t emin = corrunheader->GetELowLim(); const Float_t emax = corrunheader->GetEUppLim(); const Float_t expo = 1 + corrunheader->GetSlopeSpec(); const Float_t k = runheader->GetNumSimulatedShowers() / (pow(emax,expo) - pow(emin,expo)) ; TH2 &hall = *fCollArea->GetHistAll(); const Int_t nbinx = hall.GetNbinsX(); TAxis &axe = *hall.GetXaxis(); for (Int_t i = 1; i <= nbinx; i++) { const Float_t e1 = axe.GetBinLowEdge(i); const Float_t e2 = axe.GetBinLowEdge(i+1); if (e1 < emin || e2 > emax) continue; const Float_t events = k * (pow(e2, expo) - pow(e1, expo)); // // We fill the i-th energy bin, with the total number of events // Second argument of Fill would be impact parameter of each // event, but we don't really need it for the collection area, // so we just put a dummy value (1.) // const Float_t energy = (e1+e2)/2.; hall.Fill(energy, 1., events); } return kTRUE; } Int_t MMcCollectionAreaCalc::Process() { const Double_t energy = fMcEvt->GetEnergy(); const Double_t impact = fMcEvt->GetImpact()/100.; // // This happens for camera files created with Camera 0.5 // if (TMath::IsNaN(impact)) { *fLog << err << dbginf << "ERROR - Impact=NaN (Not a number)... abort." << endl; return kERROR; } if (!fAllEvtsTriggered) { fCollArea->FillAll(energy, impact); if (fMcTrig->GetFirstLevel() <= 0) return kTRUE; } fCollArea->FillSel(energy, impact); return kTRUE; } Int_t MMcCollectionAreaCalc::PostProcess() { if (!fCollArea) return kTRUE; // // do the calculation of the effectiv area // *fLog << inf << "Calculation Collection Area..." << endl; if (!fAllEvtsTriggered) fCollArea->CalcEfficiency(); else { *fLog << inf << "Total number of showers: " << fTotalNumSimulatedShowers << endl; fCollArea->CalcEfficiency2(); } return kTRUE; }