file interface/ExSimpleCaloCWNtuple.h ===================================== #include "Utilities/Configuration/interface/Architecture.h" #ifndef ExSimpleCaloCWNtuple_h #define ExSimpleCaloCWNtuple_h /** \file Examples/Tutorial/interface/ExSimpleCaloCWNtuple.h * Tutorial class to demonstrate the use of full blast column-wise ntuples. * Used by ExSimpleCaloAnalysis */ // we need this because we inherit from it #include "Utilities/CHBook4/interface/HB4Histogrammer.h" #include "Utilities/CHBook4/interface/CHBookCWNtuple.h" // this will define auto_ptr #include /** Tutorial class to demonstrate the use of full blast column-wise ntuples. * It is used by ExSimpleCaloAnalysis. This column-wise Ntuple contains * simple quantities and 1-dim arrays of variable length. * \author Stephan Wynhoff, CERN */ class ExSimpleCaloCWNtuple : private HB4Histogrammer { public: /** The constructor with the filename as argument. We do here * our initialisation. */ ExSimpleCaloCWNtuple(const char * filename = "userntple.hbook", int lun=10) : HB4Histogrammer(filename, lun) { BaseInit(); } /** The destructor saves the ntuple to disk */ ~ExSimpleCaloCWNtuple() { BaseEnd();} // the public functions to access fill the class variables void FillGeneral(int ir, int iev); //!< Fill run (ir) and event (iev) number void FillEnergy(float e, float eecal, float ehcal); //!< Fill energies /** Add a cluster of energy (e), azimuthal angle (phi) and pseudorapidity * (eta) to the Ntuple. */ void AddTower(float e, float phi, float eta); void fill(); //!< copy the information from memory to Ntuple private: virtual void book(); //!< HBOOK user booking virtual void hend(); //!< HBOOK user ending private: // These are accessable only via public methods auto_ptr nUser; //!< the pointer to the Ntuple // Define a maximal size of the 1-dim arrays. Use enum and not #define! enum sizes{NTWMAX=5000}; // The class variables to cache the data for the Ntuple // GENERAL int irun,ievent; float totalEnergy, EcalEnergy, HcalEnergy; // CLUSTERS int ntw; float ETw[NTWMAX], PhiTw[NTWMAX], EtaTw[NTWMAX]; }; #endif file ExSimpleCaloCWNtuple.cc ============================ #include "Examples/Tutorial/interface/ExSimpleCaloCWNtuple.h" #include #include #include // Here the ntuple is booked void ExSimpleCaloCWNtuple::book() { cout << "=== booking user ntuple ===" << endl; // create the ntuple giving name and ID number nUser = auto_ptr(new CHBookCWNtuple("USERNTPL", 99)); /* define the blocks - always indicate the type (I or R). * Only scalars and 1-dim arrays are supported. * The blanks after each comma is necessary for internal decoding! */ nUser->book("GENERAL" ,"IRUN:I, EVNT:I, ECALO:R, EECAL:R, EHCAL:R"); char towerdetails[200]; bzero(towerdetails,200); sprintf(towerdetails, "ntwr[0,%d]:I, ETW(ntwr):R, PHITW(ntwr):R:15:[0.,6.5], ETATW(ntwr):R", NTWMAX); nUser->book("TOWERS",towerdetails); cout << "=== booking user ntuple done ===" << endl; } // Here one can print the histograms or // manipulate them before they are written to file void ExSimpleCaloCWNtuple::hend() { cout << "=== save user ntuples ===" << endl; } // The next three methods fill the quantities to internal class // variables. // (1) This method will also initialise the Ntuple. So it is mandatory // to call it first for each event. void ExSimpleCaloCWNtuple::FillGeneral(int ir, int iev) { irun = ir; ievent = iev; ntw=0; // This is the init part. We reset the number of towers. } // (2) Total calorimetric energy void ExSimpleCaloCWNtuple::FillEnergy(float e, float eecal, float ehcal) { totalEnergy=e; EcalEnergy=eecal; HcalEnergy=ehcal; } // (3) Calorimeter tower void ExSimpleCaloCWNtuple::AddTower(float e, float phi, float eta) { if (ntw < NTWMAX) { ETw[ntw]=e; PhiTw[ntw]= (phi < 0.) ? (2*M_PI+phi) : phi; EtaTw[ntw]=eta; ntw++; } } // This method copies the Ntuple from the class variables to Ntuple. // It is called only once per event. Each set call has to correspond // exactly to the definition of the Ntuple as defined in book(). void ExSimpleCaloCWNtuple::fill() { /* Copy from class variables to Ntuple memory */ nUser->set("GENERAL","IRUN",irun); nUser->set("GENERAL","EVNT",ievent); nUser->set("GENERAL","ECALO",totalEnergy); nUser->set("GENERAL","EECAL",EcalEnergy); nUser->set("GENERAL","EHCAL",HcalEnergy); nUser->set("TOWERS","ntwr",ntw); for(int i=0; iset("TOWERS","ETW",i, ETw[i]); nUser->set("TOWERS","PHITW",i, PhiTw[i]); nUser->set("TOWERS","ETATW",i, EtaTw[i]); } /* And store it */ nUser->fill(); } file interface/ExSimpleCaloAnalysis.h ===================================== #ifndef ExSimpleCaloAnalysis_h #define ExSimpleCaloAnalysis_h /** \file Examples/Tutorial/interface/ExSimpleCaloAnalysis.h * Tutorial class to demonstrate the use of full blast column-wise ntuples. */ // We need this because we inherit from it. The observer class implements // the notification when something happens. #include "Utilities/Notification/interface/Observer.h" // If we only have a pointer to objects of a class, we can forward // declare the class and have the #include in the .cc file. (Speed) // The something we want to know about is the arrival of a new event. class G3EventProxy; // To access our Ntuple class ExSimpleCaloCWNtuple; /** Tutorial class to demonstrate the use of full blast column-wise ntuples * from ExSimpleCaloCWNtuple. Informations from CaloTowers are used. * \author Stephan Wynhoff, CERN */ class ExSimpleCaloAnalysis : private ActiveObserver { public: /** The default constructor. * Here the Ntuples are created */ ExSimpleCaloAnalysis(); /** The default destructor. * Here the Ntuples are deleted and saved to file. */ ~ExSimpleCaloAnalysis(); /// this method will do the user analysis void analysis(G3EventProxy * ev) ; private: /// don't change the name "upDate" - this method is mandatory. void upDate(G3EventProxy * ev) { if (ev!=0) analysis(ev);} private: ExSimpleCaloCWNtuple *UserNtuples; //!< here is the Ntuple }; #endif file ExSimpleCaloAnalysis.cc ============================ #include "Utilities/Configuration/interface/Architecture.h" #include "CARF/G3Event/interface/G3EventProxy.h" #include "CARF/Reco/interface/RecItr.h" #include "Calorimetry/EcalPlusHcalTower/interface/EcalPlusHcalTower.h" #include "Examples/Tutorial/interface/ExSimpleCaloAnalysis.h" #include "Examples/Tutorial/interface/ExSimpleCaloCWNtuple.h" #include "CLHEP/Geometry/Point3D.h" #include // for any cout #include // to print nicely formatted // this is the constructor ExSimpleCaloAnalysis::ExSimpleCaloAnalysis() { cout << "Constructing SimpleCalo Observer" << endl; UserNtuples = new ExSimpleCaloCWNtuple("myntpl.hbook"); // instantiate the user ntuples }; // this is the destructor ExSimpleCaloAnalysis::~ExSimpleCaloAnalysis() { cout << "Deleting SimpleCalo Observer" << endl; delete UserNtuples; }; // this is our analysis method void ExSimpleCaloAnalysis::analysis(G3EventProxy * ev) { /* This iterator allows simple loops over all CaloCluster objects. We * ask for objects generated by EcalFixedWindowManager (which was * defined in Reconstructor::buildDict() */ RecItr MyCaloTower(ev->recEvent()); /* Print Run and Event number and fill them to our Ntuple */ cout << "Run #" << ev->simTrigger()->id().runNumber() << "; "; cout << "Event #" << ev->simTrigger()->id().eventInRun() << endl; UserNtuples->FillGeneral(ev->simTrigger()->id().runNumber(),ev->simTrigger()->id().eventInRun()); float Ecalo=0.0; // for the total calorimetric energy float Eecaltotal=0.0; float Ehcaltotal=0.0; HepPoint3D TowerPosition; /* Loop over all CaloCluster objects */ while (MyCaloTower.next()) { Ecalo += MyCaloTower->Energy(); // sum up the total energy Eecaltotal+=MyCaloTower->EnergyEcalTower(); // sum up the Ecal energy Ehcaltotal+=MyCaloTower->EnergyHcalTower(); // sum up the Hcal energy TowerPosition = MyCaloTower->Position(); /* Print energy, azimuth and pseudo-rapidity of a cluster and fill this * to our Ntuple */ cout.setf(ios::showpoint); cout << "New Tower E(tot/Ecal/Hcal)=" << setw(8) << setprecision(3) << MyCaloTower->Energy() << "/" << MyCaloTower->EnergyEcalTower() << "/" << MyCaloTower->EnergyHcalTower() << " GeV" << "; phi=" << setw(8) << setprecision(4) << TowerPosition.phi() << " rad" << "; eta=" << TowerPosition.pseudoRapidity() << endl; UserNtuples->AddTower(MyCaloTower->Energy(),TowerPosition.phi(), TowerPosition.pseudoRapidity()); } /* Also fill the total calorimetric energy to our Ntuple */ UserNtuples->FillEnergy(Ecalo, Eecaltotal, Ehcaltotal); cout << endl; /* Save the Ntuple from memory to file */ UserNtuples->fill(); } file ExTutNtuple.cpp ==================== // Every .cpp or .cc file has to start with this #include. // It removes differences between, e.g. sun and linux for portability. #include "Utilities/Configuration/interface/Architecture.h" // These #include for the mandatory methods used here: #include "Utilities/Notification/interface/PackageInitializer.h" // And our private analysis class #include "Examples/Tutorial/interface/ExSimpleCaloAnalysis.h" // the new (ORCA 4) generic way to register our analysis class to CARF PKBuilder mybuilder("ExSimpleCaloAnalysisBuilder");