00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00015 #include "FWCore/Utilities/interface/EDMException.h"
00016 #include "FWCore/Utilities/interface/Exception.h"
00017 #include "SimG4Core/Notification/interface/SimG4Exception.h"
00018 #include "SimG4CMS/Calo/interface/CaloG4Hit.h"
00019 #include "SimG4CMS/Calo/interface/CaloG4HitCollection.h"
00020 #include "DataFormats/Math/interface/Point3D.h"
00021
00022 #include "SimG4CMS/ShowerLibraryProducer/interface/CastorShowerLibraryMaker.h"
00023 #include "SimG4CMS/Forward/interface/CastorNumberingScheme.h"
00024
00025 #include "SimDataFormats/CaloHit/interface/CastorShowerEvent.h"
00026
00027 #include "TFile.h"
00028 #include <cmath>
00029 #include <iostream>
00030 #include <sstream>
00031 #include <iomanip>
00032 #include <stdlib.h>
00033
00034 CastorShowerLibraryMaker::CastorShowerLibraryMaker(const edm::ParameterSet &p) :
00035 NPGParticle(0),DoHadSL(false),DoEmSL(false),DeActivatePhysicsProcess(false),
00036 emShower(NULL) , hadShower(NULL) {
00037
00038 MapOfSecondaries.clear();
00039 hadInfo = NULL;
00040 emInfo = NULL;
00041 edm::ParameterSet p_SLM = p.getParameter<edm::ParameterSet>("CastorShowerLibraryMaker");
00042 verbosity = p_SLM.getParameter<int>("Verbosity");
00043 eventNtFileName = p_SLM.getParameter<std::string>("EventNtupleFileName");
00044 hadSLHolder.nEvtPerBinPhi = p_SLM.getParameter<int>("nhadEvents");
00045 emSLHolder.nEvtPerBinPhi = p_SLM.getParameter<int>("nemEvents");
00046 hadSLHolder.SLEnergyBins = p_SLM.getParameter<std::vector<double> >("SLhadEnergyBins");
00047 hadSLHolder.SLEtaBins = p_SLM.getParameter<std::vector<double> >("SLhadEtaBins");
00048 hadSLHolder.SLPhiBins = p_SLM.getParameter<std::vector<double> >("SLhadPhiBins");
00049 emSLHolder.SLEnergyBins = p_SLM.getParameter<std::vector<double> >("SLemEnergyBins");
00050 emSLHolder.SLEtaBins = p_SLM.getParameter<std::vector<double> >("SLemEtaBins");
00051 emSLHolder.SLPhiBins = p_SLM.getParameter<std::vector<double> >("SLemPhiBins");
00052 PGParticleIDs = p_SLM.getParameter<std::vector<int> >("PartID");
00053 DeActivatePhysicsProcess = p_SLM.getParameter<bool>("DeActivatePhysicsProcess");
00054 MaxPhi = p_SLM.getParameter<double>("SLMaxPhi");
00055 MaxEta = p_SLM.getParameter<double>("SLMaxEta");
00056
00057 NPGParticle = PGParticleIDs.size();
00058 for(unsigned int i=0;i<PGParticleIDs.size();i++) {
00059 switch (int(fabs(PGParticleIDs.at(i)))) {
00060 case 11:
00061 case 22:
00062 DoEmSL = true;
00063 break;
00064 default:
00065 DoHadSL = true;
00066 }
00067 }
00068 hadSLHolder.nEvtPerBinEta = (hadSLHolder.nEvtPerBinPhi)*(hadSLHolder.SLPhiBins.size());
00069 hadSLHolder.nEvtPerBinE = (hadSLHolder.nEvtPerBinEta)*(hadSLHolder.SLEtaBins.size());
00070 emSLHolder.nEvtPerBinEta = (emSLHolder.nEvtPerBinPhi)*(emSLHolder.SLPhiBins.size());
00071 emSLHolder.nEvtPerBinE = (emSLHolder.nEvtPerBinEta)*(emSLHolder.SLEtaBins.size());
00072
00073 std::cout << "============================================================================"<<std::endl;
00074 std::cout << "CastorShowerLibraryMaker:: Initialized as observer" << std::endl;
00075 std::cout << " Event Ntuple will be created" << std::endl;
00076 std::cout << " Event Ntuple file: " << eventNtFileName << std::endl;
00077 std::cout << " Number of Hadronic events in E bins: " << hadSLHolder.nEvtPerBinE << std::endl;
00078 std::cout << " Number of Hadronic events in Eta bins: " << hadSLHolder.nEvtPerBinEta << std::endl;
00079 std::cout << " Number of Hadronic events in Phi bins: " << hadSLHolder.nEvtPerBinPhi << std::endl;
00080 std::cout << " Number of Electromag. events in E bins: " << emSLHolder.nEvtPerBinE << std::endl;
00081 std::cout << " Number of Electromag. events in Eta bins: " << emSLHolder.nEvtPerBinEta << std::endl;
00082 std::cout << " Number of Electromag. events in Phi bins: " << emSLHolder.nEvtPerBinPhi << std::endl;
00083 std::cout << "============================================================================"<<std::endl;
00084 std::cout << std::endl;
00085
00086
00087 InitSLHolder(hadSLHolder);
00088 InitSLHolder(emSLHolder);
00089 }
00090 void CastorShowerLibraryMaker::InitSLHolder(ShowerLib& showerholder)
00091 {
00092 int nBinsE,nBinsEta,nBinsPhi,nEvtPerBinPhi;
00093 nBinsE = showerholder.SLEnergyBins.size();
00094 nBinsEta = showerholder.SLEtaBins.size();
00095 nBinsPhi = showerholder.SLPhiBins.size();
00096 nEvtPerBinPhi=showerholder.nEvtPerBinPhi;
00097
00098
00099
00100 showerholder.SLInfo.Energy.setNEvts(nEvtPerBinPhi*nBinsPhi*nBinsEta*nBinsE);
00101 showerholder.SLInfo.Energy.setNEvtPerBin(nEvtPerBinPhi*nBinsPhi*nBinsEta);
00102 showerholder.SLInfo.Energy.setNBins(nBinsE);
00103 showerholder.SLInfo.Energy.setBin(showerholder.SLEnergyBins);
00104
00105 showerholder.SLInfo.Eta.setNEvts(nEvtPerBinPhi*nBinsPhi*nBinsEta);
00106 showerholder.SLInfo.Eta.setNEvtPerBin(nEvtPerBinPhi*nBinsPhi);
00107 showerholder.SLInfo.Eta.setNBins(nBinsEta);
00108 showerholder.SLInfo.Eta.setBin(showerholder.SLEtaBins);
00109
00110 showerholder.SLInfo.Phi.setNEvts(nEvtPerBinPhi*nBinsPhi);
00111 showerholder.SLInfo.Phi.setNEvtPerBin(nEvtPerBinPhi);
00112 showerholder.SLInfo.Phi.setNBins(nBinsPhi);
00113 showerholder.SLInfo.Phi.setBin(showerholder.SLPhiBins);
00114
00115
00116 showerholder.SLCollection.assign(nBinsE,std::vector<std::vector<std::vector<CastorShowerEvent> > >());
00117 showerholder.nEvtInBinE.assign(nBinsE,0);
00118 showerholder.nEvtInBinEta.assign(nBinsE,std::vector<int>(0));
00119 showerholder.nEvtInBinPhi.assign(nBinsE,std::vector<std::vector<int> >());
00120 for(int i=0;i<nBinsE;i++) {
00121 showerholder.SLCollection.at(i).assign(nBinsEta,std::vector<std::vector<CastorShowerEvent> >());
00122 showerholder.nEvtInBinEta.at(i).assign(nBinsEta,0);
00123 showerholder.nEvtInBinPhi.at(i).assign(nBinsEta,std::vector<int>(0));
00124 for(int j=0;j<nBinsEta;j++) {
00125 showerholder.SLCollection.at(i).at(j).assign(nBinsPhi,std::vector<CastorShowerEvent>());
00126 showerholder.nEvtInBinPhi.at(i).at(j).assign(nBinsPhi,0);
00127 for(int k=0;k<nBinsPhi;k++)
00128 showerholder.SLCollection.at(i).at(j).at(k).assign(nEvtPerBinPhi,CastorShowerEvent());
00129 }
00130 }
00131 }
00132
00133
00134
00135 CastorShowerLibraryMaker::~CastorShowerLibraryMaker() {
00136
00137 Finish();
00138
00139 std::cout << "CastorShowerLibraryMaker: End of process" << std::endl;
00140
00141 }
00142
00143
00144 void CastorShowerLibraryMaker::update(const BeginOfJob * job) {
00145
00146 std::cout << " CastorShowerLibraryMaker::Starting new job " << std::endl;
00147 }
00148
00149
00150 void CastorShowerLibraryMaker::update(const BeginOfRun * run) {
00151
00152 std::cout << std::endl << "CastorShowerLibraryMaker: Starting Run"<< std::endl;
00153
00154 std::cout << "CastorShowerLibraryMaker: output event root file created" << std::endl;
00155
00156 TString eventfilename = eventNtFileName;
00157 theFile = new TFile(eventfilename,"RECREATE");
00158 theTree = new TTree("CastorCherenkovPhotons", "Cherenkov Photons");
00159
00160 Int_t split = 1;
00161 Int_t bsize = 64000;
00162 emInfo = new CastorShowerLibraryInfo();
00163 emShower = new CastorShowerEvent();
00164 hadInfo = new CastorShowerLibraryInfo();
00165 hadShower = new CastorShowerEvent();
00166
00167 theTree->Branch("emShowerLibInfo.", "CastorShowerLibraryInfo", &emInfo, bsize, split);
00168 theTree->Branch("emParticles.", "CastorShowerEvent", &emShower, bsize, split);
00169 theTree->Branch("hadShowerLibInfo.", "CastorShowerLibraryInfo", &hadInfo, bsize, split);
00170 theTree->Branch("hadParticles.", "CastorShowerEvent", &hadShower, bsize, split);
00171
00172
00173
00174 emInfo->Energy.setNEvts(emSLHolder.nEvtPerBinE*emSLHolder.SLEnergyBins.size());
00175 emInfo->Energy.setNBins(emSLHolder.SLEnergyBins.size());
00176 emInfo->Energy.setNEvtPerBin(emSLHolder.nEvtPerBinE);
00177 emInfo->Energy.setBin(emSLHolder.SLEnergyBins);
00178
00179 emInfo->Eta.setNEvts(emSLHolder.nEvtPerBinEta*emSLHolder.SLEtaBins.size());
00180 emInfo->Eta.setNBins(emSLHolder.SLEtaBins.size());
00181 emInfo->Eta.setNEvtPerBin(emSLHolder.nEvtPerBinEta);
00182 emInfo->Eta.setBin(emSLHolder.SLEtaBins);
00183
00184 emInfo->Phi.setNEvts(emSLHolder.nEvtPerBinPhi*emSLHolder.SLPhiBins.size());
00185 emInfo->Phi.setNBins(emSLHolder.SLPhiBins.size());
00186 emInfo->Phi.setNEvtPerBin(emSLHolder.nEvtPerBinPhi);
00187 emInfo->Phi.setBin(emSLHolder.SLPhiBins);
00188
00189
00190 hadInfo->Energy.setNEvts(hadSLHolder.nEvtPerBinE*hadSLHolder.SLEnergyBins.size());
00191 hadInfo->Energy.setNBins(hadSLHolder.SLEnergyBins.size());
00192 hadInfo->Energy.setNEvtPerBin(hadSLHolder.nEvtPerBinE);
00193 hadInfo->Energy.setBin(hadSLHolder.SLEnergyBins);
00194
00195 hadInfo->Eta.setNEvts(hadSLHolder.nEvtPerBinEta*hadSLHolder.SLEtaBins.size());
00196 hadInfo->Eta.setNBins(hadSLHolder.SLEtaBins.size());
00197 hadInfo->Eta.setNEvtPerBin(hadSLHolder.nEvtPerBinEta);
00198 hadInfo->Eta.setBin(hadSLHolder.SLEtaBins);
00199
00200 hadInfo->Phi.setNEvts(hadSLHolder.nEvtPerBinPhi*hadSLHolder.SLPhiBins.size());
00201 hadInfo->Phi.setNBins(hadSLHolder.SLPhiBins.size());
00202 hadInfo->Phi.setNEvtPerBin(hadSLHolder.nEvtPerBinPhi);
00203 hadInfo->Phi.setBin(hadSLHolder.SLPhiBins);
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 eventIndex = 0;
00220
00221 }
00222
00223
00224 void CastorShowerLibraryMaker::update(const BeginOfEvent * evt) {
00225
00226 eventIndex++;
00227 stepIndex = 0;
00228 InsideCastor = false;
00229 PrimaryMomentum.clear();
00230 PrimaryPosition.clear();
00231 int NAccepted =0;
00232
00233 SLShowerptr = NULL;
00234 MapOfSecondaries.clear();
00235 thePrims.clear();
00236 G4EventManager *e_mgr = G4EventManager::GetEventManager();
00237 if (IsSLReady()) {
00238 printSLstatus(-1,-1,-1);
00239 update((EndOfRun*)NULL);
00240 return;
00241 }
00242
00243 thePrims = GetPrimary((*evt)());
00244 for(unsigned int i=0;i<thePrims.size();i++) {
00245 G4PrimaryParticle* thePrim = thePrims.at(i);
00246 int particleType = thePrim->GetPDGcode();
00247
00248 std::string SLType("");
00249 if (particleType==11) {
00250 SLShowerptr = &emSLHolder;
00251 SLType = "Electromagnetic";
00252 }
00253 else {
00254 SLShowerptr = &hadSLHolder;
00255 SLType = "Hadronic";
00256 }
00257 double px=0., py=0., pz=0., pInit = 0., eta = 0., phi = 0.;
00258 GetKinematics(thePrim,px,py,pz,pInit,eta,phi);
00259 int ebin = FindEnergyBin(pInit);
00260 int etabin= FindEtaBin(eta);
00261 int phibin = FindPhiBin(phi);
00262 if (verbosity)
00263 std::cout << "\n========================================================================"
00264 << "\nBeginOfEvent: E : " << pInit <<"\t bin : " << ebin
00265 << "\n Eta : " << eta <<"\t bin : " << etabin
00266 << "\n Phi : " << phi <<"\t bin : " << phibin
00267 << "\n========================================================================"
00268 << std::endl;
00269
00270 if (ebin<0||etabin<0||phibin<0) continue;
00271 bool accept=false;
00272 if (!(SLacceptEvent(ebin,etabin,phibin))) {
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 if (!accept) edm::LogInfo("CastorShowerLibraryMaker") << "Event not accepted for ebin="
00292 << ebin<<",etabin="<<etabin<<",phibin="<<phibin<<std::endl;
00293 }
00294 else {
00295 accept=true;
00296 }
00297 if (accept) NAccepted++;
00298 }
00299
00300 if (NAccepted==0) {
00301 const_cast<G4Event*>((*evt)())->SetEventAborted();
00302 const_cast<G4Event*>((*evt)())->KeepTheEvent((G4bool)false);
00303 e_mgr->AbortCurrentEvent();
00304 }
00305 SLShowerptr=NULL;
00306
00307 std::cout << "CastorShowerLibraryMaker: Processing Event Number: " << eventIndex << std::endl;
00308 }
00309
00310
00311 void CastorShowerLibraryMaker::update(const G4Step * aStep) {
00312 static int CurrentPrimary = 0;
00313 G4Track *trk = aStep->GetTrack();
00314 if (trk->GetCurrentStepNumber()==1) {
00315 if (trk->GetParentID()==0) {
00316 CurrentPrimary = (int)trk->GetDynamicParticle()->GetPDGcode();
00317 if (CurrentPrimary==0)
00318 SimG4Exception("CastorShowerLibraryMaker::update(G4Step) -> Primary particle undefined");
00319 InsideCastor=false;
00320
00321 if (DeActivatePhysicsProcess) {
00322 G4ProcessManager *p_mgr = trk->GetDefinition()->GetProcessManager();
00323 G4ProcessVector *pvec = p_mgr->GetProcessList();
00324 for (int i = 0;i<pvec->size();i++) {
00325 G4VProcess *proc = (*pvec)(i);
00326 if (proc->GetProcessName()!="Transportation"&&
00327 proc->GetProcessName()!="Decay") {
00328 std::cout << "DeActivating process: " << proc->GetProcessName() << std::endl;
00329 p_mgr->SetProcessActivation(proc,false);
00330 }
00331 }
00332 }
00333
00334 G4ThreeVector pos;
00335 pos.setZ(-14390);
00336 double t = abs((pos.z()-trk->GetPosition().z()))/trk->GetVelocity();
00337 double r = (pos.z()-trk->GetPosition().z())/trk->GetMomentum().cosTheta();
00338 pos.setX(r*sin(trk->GetMomentum().theta())*cos(trk->GetMomentum().phi())+trk->GetPosition().x());
00339 pos.setY(r*sin(trk->GetMomentum().theta())*sin(trk->GetMomentum().phi())+trk->GetPosition().y());
00340 trk->SetPosition(pos);
00341 trk->SetGlobalTime(trk->GetGlobalTime()+t);
00342 trk->AddTrackLength(r);
00343 }
00344 else if (!InsideCastor) {
00345 std::cout<<"CastorShowerLibraryMaker::update(G4Step) -> Killing spurious track" << std::endl;
00346 trk->SetTrackStatus(fKillTrackAndSecondaries);
00347 return;
00348 }
00349 MapOfSecondaries[CurrentPrimary].insert((int)trk->GetTrackID());
00350 }
00351
00352 std::string CurVolume = trk->GetVolume()->GetName();
00353 if (!InsideCastor&&(
00354
00355
00356
00357 CurVolume=="CAST")) {
00358
00359 InsideCastor=true;
00360
00361 if (trk->GetParentID()==0&&DeActivatePhysicsProcess) {
00362 G4ProcessManager *p_mgr = trk->GetDefinition()->GetProcessManager();
00363 G4ProcessVector *pvec = p_mgr->GetProcessList();
00364 for (int i = 0;i<pvec->size();i++) {
00365 G4VProcess *proc = (*pvec)(i);
00366 if (proc->GetProcessName()!="Transportation"&&
00367 proc->GetProcessName()!="Decay") {
00368 std::cout << " Activating process: " << proc->GetProcessName() << std::endl;
00369 p_mgr->SetProcessActivation(proc,true);
00370 }
00371 }
00372 }
00373
00374
00375 if (trk->GetMomentum().phi()>MaxPhi||trk->GetMomentum().eta()>MaxEta) {
00376 trk->SetTrackStatus(fKillTrackAndSecondaries);
00377 InsideCastor=false;
00378 return;
00379 }
00380 PrimaryMomentum[CurrentPrimary]=trk->GetMomentum();
00381 PrimaryPosition[CurrentPrimary]=trk->GetPosition();
00382 KillSecondaries(aStep);
00383 return;
00384 }
00385
00386 if (CurrentPrimary!=0&&trk->GetParentID()==0&&!InsideCastor) {
00387 KillSecondaries(aStep);
00388 if (verbosity) {
00389 double pre_phi = aStep->GetPreStepPoint()->GetMomentum().phi();
00390 double cur_phi = trk->GetMomentum().phi();
00391 if (pre_phi!=cur_phi) {
00392 std::cout << "Primary track phi : " << pre_phi << " changed in current step: "
00393 << cur_phi << " by processes:" << std::endl;
00394 const G4VProcess *proc = aStep->GetPreStepPoint()->GetProcessDefinedStep();
00395 std::cout << " " << proc->GetProcessName()
00396 << " In volume " << CurVolume << std::endl;
00397 }
00398 }
00399 }
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412 }
00413
00414
00415 void CastorShowerLibraryMaker::update(const EndOfEvent * evt) {
00416
00417
00418 if ((*evt)()->IsAborted()) {
00419 std::cout << "\n========================================================================"
00420 << "\nEndOfEvent: EVENT ABORTED"
00421 << "\n========================================================================"
00422 << std::endl;
00423 return;
00424 }
00425
00426
00427
00428
00429
00430
00431 if (verbosity)
00432 std::cout << "CastorShowerLibraryMaker: End of Event: " << eventIndex << std::endl;
00433
00434 if (thePrims.size() == 0) {
00435 edm::LogInfo("CastorShowerLibraryMaker") << "No valid primary particle found. Skipping event" << std::endl;
00436 return;
00437 }
00438
00439 G4HCofThisEvent* allHC = (*evt)()->GetHCofThisEvent();
00440 int CAFIid = G4SDManager::GetSDMpointer()->GetCollectionID("CastorFI");
00441 CaloG4HitCollection* theCAFI = (CaloG4HitCollection*) allHC->GetHC(CAFIid);
00442 if (verbosity) edm::LogInfo("CastorShowerLibraryMaker") << " update(*evt) --> accessed all HC ";
00443 edm::LogInfo("CastorShowerLibraryMaker") << "Found "<<theCAFI->entries() << " hits in G4HitCollection";
00444 if (theCAFI->entries()== 0) {
00445 edm::LogInfo("CastorShowerLibraryMaker") << "\n Empty G4HitCollection";
00446 return;
00447 }
00448
00449
00450 int NEvtAccepted = 0;
00451 int NHitInEvent = 0;
00452 for(unsigned int i=0;i<thePrims.size();i++) {
00453 G4PrimaryParticle* thePrim = thePrims.at(i);
00454 if (!thePrim) {
00455 edm::LogInfo("CastorShowerLibraryMaker") << "NULL Pointer to the primary" << std::endl;
00456 continue;
00457 }
00458
00459 int particleType = thePrim->GetPDGcode();
00460
00461
00462 std::string SLType("");
00463 if (particleType==11) {
00464 SLShowerptr = &emSLHolder;
00465 SLType = "Electromagnetic";
00466 }
00467 else {
00468 SLShowerptr = &hadSLHolder;
00469 SLType = "Hadronic";
00470 }
00471 edm::LogInfo("CastorShowerLibraryMaker") << "\n Primary (thePrim) trackID is " << thePrim->GetTrackID() << "\n" ;
00472
00473
00474 double px=0., py=0., pz=0., pInit = 0., eta = 0., phi = 0.;
00475 GetKinematics(particleType,px,py,pz,pInit,eta,phi);
00476
00477
00478 if (pInit==0) {
00479 edm::LogInfo("CastorShowerLibraryMaker") << "Primary did not hit CASTOR" << std::endl;
00480 continue;
00481 }
00482 int ebin = FindEnergyBin(pInit);
00483 int etabin= FindEtaBin(eta);
00484 int phibin = FindPhiBin(phi);
00485 std::cout << SLType << std::endl;
00486 printSLstatus(ebin,etabin,phibin);
00487 if (!SLacceptEvent(ebin,etabin,phibin)) {
00488 edm::LogInfo("CastorShowerLibraryMaker") << "Event not accepted for ebin="
00489 << ebin<<",etabin="<<etabin<<",phibin="<<phibin
00490 <<"("<< pInit <<","<<eta<<","<<phi<<")" <<std::endl;
00491 continue;
00492 }
00493
00494
00495
00496
00497 edm::LogInfo("CastorShowerLibraryMaker")
00498 << "\n CastorShowerLibraryMaker::update(EndOfEvent * evt) - event #"
00499 << (*evt)()->GetEventID() ;
00500
00501
00502
00503
00504
00505
00506
00507 CastorShowerEvent* shower=NULL;
00508 int cur_evt_idx = SLShowerptr->nEvtInBinPhi.at(ebin).at(etabin).at(phibin);
00509 shower = &(SLShowerptr->SLCollection.at(ebin).at(etabin).at(phibin).at(cur_evt_idx));
00510
00511
00512 if (FillShowerEvent(theCAFI,shower,particleType)) {
00513
00514
00515
00516
00517
00518
00519 shower->setPrimE(pInit);
00520 shower->setPrimEta(eta);
00521 shower->setPrimPhi(phi);
00522 shower->setPrimX(PrimaryPosition[particleType].x());
00523 shower->setPrimY(PrimaryPosition[particleType].y());
00524 shower->setPrimZ(PrimaryPosition[particleType].z());
00525 SLnEvtInBinE(ebin)++;
00526 SLnEvtInBinEta(ebin,etabin)++;
00527 SLnEvtInBinPhi(ebin,etabin,phibin)++;
00528 NHitInEvent+=shower->getNhit();
00529 NEvtAccepted++;
00530 }
00531 else {shower->Clear();}
00532 }
00533
00534
00535 if (NEvtAccepted==int(thePrims.size())&&theCAFI->entries()!=NHitInEvent){
00536 std::cout << "WARNING: Inconsistent Number of Hits -> Hits in collection: "<< theCAFI->entries()
00537 << " Hits in the showers: " << NHitInEvent << std::endl;
00538 double miss_energy=0;
00539 double tot_energy=0;
00540 GetMissingEnergy(theCAFI,miss_energy,tot_energy);
00541 if (miss_energy>0) {
00542 std::cout << "Total missing energy: " << miss_energy
00543 << " for an incident energy: " << tot_energy
00544 << std::endl;
00545 }
00546 }
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566 }
00567
00568
00569 void CastorShowerLibraryMaker::update(const EndOfRun * run)
00570 {
00571
00572 if (!IsSLReady()) SimG4Exception("\n\nShower Library NOT READY.\n\n");
00573
00574 unsigned int ibine,ibineta,ibinphi,ievt;
00575 unsigned int jbine,jbineta,jbinphi,jevt;
00576
00577 ibine=ibineta=ibinphi=ievt=jbine=jbineta=jbinphi=jevt=0;
00578
00579 int nEvtInTree = 0;
00580 int nEMevt = emSLHolder.nEvtPerBinE*emSLHolder.SLEnergyBins.size();
00581 int nHadevt = hadSLHolder.nEvtPerBinE*hadSLHolder.SLEnergyBins.size();
00582 int maxEvtInTree=std::max(nEMevt,nHadevt);
00583
00584 emInfo = &emSLHolder.SLInfo;
00585 hadInfo= &hadSLHolder.SLInfo;
00586
00587 while(nEvtInTree<maxEvtInTree) {
00588 if (emShower) emShower->Clear();
00589 if (hadShower) hadShower->Clear();
00590 while(ibine<emSLHolder.SLEnergyBins.size()&&nEMevt>0){
00591 emShower = &(emSLHolder.SLCollection.at(ibine).at(ibineta).at(ibinphi).at(ievt));
00592 ievt++;
00593 if (ievt==emSLHolder.nEvtPerBinPhi) {ievt=0;ibinphi++;}
00594 if (ibinphi==emSLHolder.SLPhiBins.size()) {ibinphi=0;ibineta++;}
00595 if (ibineta==emSLHolder.SLEtaBins.size()) {ibineta=0;ibine++;}
00596 break;
00597 }
00598 while(jbine<hadSLHolder.SLEnergyBins.size()&&nHadevt>0){
00599 hadShower = &(hadSLHolder.SLCollection.at(jbine).at(jbineta).at(jbinphi).at(jevt));
00600 jevt++;
00601 if (jevt==hadSLHolder.nEvtPerBinPhi) {jevt=0;jbinphi++;}
00602 if (jbinphi==hadSLHolder.SLPhiBins.size()) {jbinphi=0;jbineta++;}
00603 if (jbineta==hadSLHolder.SLEtaBins.size()) {jbineta=0;jbine++;}
00604 break;
00605 }
00606 theTree->Fill();
00607 nEvtInTree++;
00608 if (nEvtInTree==1) {
00609 theTree->SetBranchStatus("emShowerLibInfo.",0);
00610 theTree->SetBranchStatus("hadShowerLibInfo.",0);
00611 }
00612 }
00613
00614 if (run==NULL) throw SimG4Exception("\n\nNumber of needed trigger events reached in CastorShowerLibraryMaker\n\n");
00615 }
00616
00617
00618 void CastorShowerLibraryMaker::Finish() {
00619
00620
00621
00622 theFile->cd();
00623 theTree->Write("",TObject::kOverwrite);
00624 std::cout << "CastorShowerLibraryMaker: Ntuple event written" << std::endl;
00625 theFile->Close();
00626 std::cout << "CastorShowerLibraryMaker: Event file closed" << std::endl;
00627
00628
00629
00630
00631
00632
00633 }
00634 int CastorShowerLibraryMaker::FindEnergyBin(double energy) {
00635
00636
00637
00638
00639 if (!SLShowerptr) {
00640 edm::LogInfo("CastorShowerLibraryMaker") << "\n\nFindEnergyBin can be called only after BeginOfEvent\n\n";
00641 throw SimG4Exception("\n\nNULL Pointer to the shower library.\n\n");
00642 }
00643 const std::vector<double>& SLenergies = SLShowerptr->SLEnergyBins;
00644 if (energy >= SLenergies.back()) return SLenergies.size()-1;
00645
00646 unsigned int i = 0;
00647 for(;i<SLenergies.size()-1;i++)
00648 if (energy >= SLenergies.at(i) && energy < SLenergies.at(i+1)) return (int)i;
00649
00650
00651 if (energy>=SLenergies.at(i)) return (int)i;
00652
00653 return -1;
00654 }
00655 int CastorShowerLibraryMaker::FindEtaBin(double eta) {
00656
00657
00658
00659
00660 if (!SLShowerptr) {
00661 edm::LogInfo("CastorShowerLibraryMaker") << "\n\nFindEtaBin can be called only after BeginOfEvent\n\n";
00662 throw SimG4Exception("\n\nNULL Pointer to the shower library.\n\n");
00663 }
00664 const std::vector<double>& SLetas = SLShowerptr->SLEtaBins;
00665 if (eta>=SLetas.back()) return SLetas.size()-1;
00666 unsigned int i = 0;
00667 for(;i<SLetas.size()-1;i++)
00668 if (eta >= SLetas.at(i) && eta < SLetas.at(i+1)) return (int)i;
00669
00670 if (eta>=SLetas.at(i)) return (int)i;
00671
00672 return -1;
00673 }
00674 int CastorShowerLibraryMaker::FindPhiBin(double phi) {
00675
00676
00677
00678
00679
00680
00681 if (!SLShowerptr) {
00682 edm::LogInfo("CastorShowerLibraryMaker") << "\n\nFindPhiBin can be called only after BeginOfEvent\n\n";
00683 throw SimG4Exception("\n\nNULL Pointer to the shower library.\n\n");
00684 }
00685 const std::vector<double>& SLphis = SLShowerptr->SLPhiBins;
00686 if (phi>=SLphis.back()) return SLphis.size()-1;
00687 unsigned int i = 0;
00688 for(;i<SLphis.size()-1;i++)
00689 if (phi >= SLphis.at(i) && phi < SLphis.at(i+1)) return (int)i;
00690
00691 if (phi>=SLphis.at(i)) return (int)i;
00692
00693 return -1;
00694 }
00695 bool CastorShowerLibraryMaker::IsSLReady()
00696 {
00697
00698 if (SLShowerptr) {
00699 edm::LogInfo("CastorShowerLibraryMaker") << "\n\nIsSLReady must be called when a new event starts.\n\n";
00700 throw SimG4Exception("\n\nNOT NULL Pointer to the shower library.\n\n");
00701 }
00702
00703 if (DoEmSL) {
00704 SLShowerptr = &emSLHolder;
00705 for(unsigned int i=0;i<SLShowerptr->SLEnergyBins.size();i++) {
00706 if (!SLisEBinFilled(i)) {
00707 SLShowerptr=NULL;
00708 return false;
00709 }
00710 }
00711 }
00712 if (DoHadSL) {
00713 SLShowerptr = &hadSLHolder;
00714 for(unsigned int i=0;i<SLShowerptr->SLEnergyBins.size();i++) {
00715 if (!SLisEBinFilled(i)) {
00716 SLShowerptr=NULL;
00717 return false;
00718 }
00719 }
00720 }
00721 SLShowerptr=NULL;
00722 return true;
00723 }
00724 void CastorShowerLibraryMaker::GetKinematics(int thePrim,double& px, double& py, double& pz, double& pInit, double& eta, double& phi)
00725 {
00726 if (thePrim==0) return;
00727 if (PrimaryMomentum.find(thePrim)==PrimaryMomentum.end()) return;
00728 px = PrimaryMomentum[thePrim].x()/GeV;
00729 py = PrimaryMomentum[thePrim].y()/GeV;
00730 pz = PrimaryMomentum[thePrim].z()/GeV;
00731 pInit=PrimaryMomentum[thePrim].mag()/GeV;
00732 if (pInit==0) return;
00733 double costheta = pz/pInit;
00734 double theta = acos(std::min(std::max(costheta,double(-1.)),double(1.)));
00735 eta = -log(tan(theta/2.0));
00736 phi = (px==0 && py==0) ? 0 : atan2(py,px);
00737 phi = PrimaryMomentum[thePrim].phi();
00738 }
00739 void CastorShowerLibraryMaker::GetKinematics(G4PrimaryParticle* thePrim,double& px, double& py, double& pz, double& pInit, double& eta, double& phi)
00740 {
00741 px=py=pz=phi=eta=0.0;
00742 if (thePrim==0) return;
00743 px = thePrim->GetMomentum().x()/GeV;
00744 py = thePrim->GetMomentum().y()/GeV;
00745 pz = thePrim->GetMomentum().z()/GeV;
00746 pInit = thePrim->GetMomentum().mag()/GeV;
00747
00748 if (pInit==0) return;
00749 double costheta = pz/pInit;
00750 double theta = acos(std::min(std::max(costheta,double(-1.)),double(1.)));
00751 eta = -log(tan(theta/2.0));
00752 phi = (px==0 && py==0) ? 0 : atan2(py,px);
00753 phi = thePrim->GetMomentum().phi();
00754
00755 }
00756 std::vector<G4PrimaryParticle*> CastorShowerLibraryMaker::GetPrimary(const G4Event * evt)
00757 {
00758
00759 int trackID = 0;
00760 std::vector<G4PrimaryParticle*> thePrims;
00761 G4PrimaryParticle* thePrim = 0;
00762 G4int nvertex = evt->GetNumberOfPrimaryVertex();
00763 edm::LogInfo("CastorShowerLibraryMaker") << "Event has " << nvertex << " vertex";
00764 if (nvertex!=1) {
00765 edm::LogInfo("CastorShowerLibraryMaker") << "CastorShowerLibraryMaker::GetPrimary ERROR: no vertex";
00766 return thePrims;
00767 }
00768
00769 for (int i = 0 ; i<nvertex; i++) {
00770 G4PrimaryVertex* avertex = evt->GetPrimaryVertex(i);
00771 if (avertex == 0) {
00772 edm::LogInfo("CastorShowerLibraryMaker")
00773 << "CastorShowerLibraryMaker::GetPrimary ERROR: pointer to vertex = 0";
00774 continue;
00775 }
00776 unsigned int npart = avertex->GetNumberOfParticle();
00777 if (npart!=NPGParticle) continue;
00778 for (unsigned int j=0;j<npart;j++) {
00779 unsigned int k = 0;
00780
00781 trackID = j;
00782 thePrim=avertex->GetPrimary(trackID);
00783 while(k<NPGParticle&&PGParticleIDs.at(k++)!=thePrim->GetPDGcode()){;};
00784 if (k>NPGParticle) continue;
00785 thePrims.push_back(thePrim);
00786 }
00787 }
00788 return thePrims;
00789 }
00790 void CastorShowerLibraryMaker::printSLstatus(int ebin,int etabin,int phibin)
00791 {
00792 if (!SLShowerptr) {
00793 edm::LogInfo("CastorShowerLibraryInfo") << "NULL shower pointer. Printing both";
00794 std::cout << "Electromagnetic" << std::endl;
00795 SLShowerptr = &emSLHolder;
00796 this->printSLstatus(ebin,etabin,phibin);
00797 std::cout << "Hadronic" << std::endl;
00798 SLShowerptr = &hadSLHolder;
00799 this->printSLstatus(ebin,etabin,phibin);
00800 SLShowerptr = NULL;
00801 return;
00802 }
00803 int nBinsE =SLShowerptr->SLEnergyBins.size();
00804 int nBinsEta=SLShowerptr->SLEtaBins.size();
00805 int nBinsPhi=SLShowerptr->SLPhiBins.size();
00806 std::vector<double> SLenergies = SLShowerptr->SLEnergyBins;
00807 for(int n=0;n<11+(nBinsEta*nBinsPhi);n++) std::cout << "=";
00808 std::cout << std::endl;
00809 for(int i=0;i<nBinsE;i++) {
00810 std::cout << "E bin " << std::setw(6) << SLenergies.at(i) << " : ";
00811 for(int j=0;j<nBinsEta;j++) {
00812 for(int k=0;k<nBinsPhi;k++) {
00813 (SLisPhiBinFilled(i,j,k))?std::cout << "1":std::cout << "-";
00814 }
00815 if (j<nBinsEta-1) std::cout << "|";
00816 }
00817 std::cout << " (" << SLnEvtInBinE(i) << " events)";
00818 std::cout << std::endl;
00819 if (ebin!=i) continue;
00820 std::cout << " ";
00821 for(int j=0;j<nBinsEta;j++) {
00822 for(int k=0;k<nBinsPhi;k++) {
00823 (ebin==i&&etabin==j&&phibin==k)?std::cout << "^":std::cout << " ";
00824 }
00825 if (j<nBinsEta-1) std::cout << " ";
00826 }
00827 std::cout << std::endl;
00828 }
00829 for(int n=0;n<11+(nBinsEta*nBinsPhi);n++) std::cout << "=";
00830 std::cout << std::endl;
00831 }
00832 bool CastorShowerLibraryMaker::SLacceptEvent(int ebin, int etabin, int phibin)
00833 {
00834 if (SLShowerptr==NULL) {
00835 edm::LogInfo("CastorShowerLibraryMaker::SLacceptEvent:") << "Error. NULL pointer to CastorShowerEvent";
00836 return false;
00837 }
00838 if (ebin<0||ebin>=int(SLShowerptr->SLEnergyBins.size())) return false;
00839 if (SLisEBinFilled(ebin)) return false;
00840
00841 if (etabin<0||etabin>=int(SLShowerptr->SLEtaBins.size())) return false;
00842 if (SLisEtaBinFilled(ebin,etabin)) return false;
00843
00844 if (phibin<0||phibin>=int(SLShowerptr->SLPhiBins.size())) return false;
00845 if (SLisPhiBinFilled(ebin,etabin,phibin)) return false;
00846 return true;
00847 }
00848 bool CastorShowerLibraryMaker::FillShowerEvent(CaloG4HitCollection* theCAFI, CastorShowerEvent* shower,int ipart)
00849 {
00850 unsigned int volumeID=0;
00851 double en_in_fi = 0.;
00852
00853
00854 int nentries = theCAFI->entries();
00855
00856
00857
00858
00859
00860
00861
00862
00863 if (!shower) {
00864 edm::LogInfo("CastorShowerLibraryMaker") << "Error. NULL pointer to CastorShowerEvent";
00865 return false;
00866 }
00867
00868 CastorNumberingScheme *theCastorNumScheme = new CastorNumberingScheme();
00869
00870 math::XYZPoint entry;
00871 math::XYZPoint position;
00872 int nHits;
00873 nHits=0;
00874 for (int ihit = 0; ihit < nentries; ihit++) {
00875 CaloG4Hit* aHit = (*theCAFI)[ihit];
00876 int hit_particleID = aHit->getTrackID();
00877 if (MapOfSecondaries[ipart].find(hit_particleID)==MapOfSecondaries[ipart].end()) {
00878 if (verbosity) edm::LogInfo("CastorShowerLibraryMaker")
00879 << "Skipping hit from trackID " << hit_particleID;
00880 continue;
00881 }
00882 volumeID = aHit->getUnitID();
00883 double hitEnergy = aHit->getEnergyDeposit();
00884 en_in_fi += aHit->getEnergyDeposit();
00885 float time = aHit->getTimeSlice();
00886 int zside, sector, zmodule;
00887 theCastorNumScheme->unpackIndex(volumeID, zside, sector,zmodule);
00888 entry = aHit->getEntry();
00889 position = aHit->getPosition();
00890 if (verbosity) edm::LogInfo("CastorShowerLibraryMaker")
00891 << "\n side , sector , module = " << zside << " , "
00892 << sector << " , " << zmodule
00893 << "\n nphotons = " << hitEnergy ;
00894
00895 if (verbosity) edm::LogInfo("CastorShowerLibraryMaker")
00896 << "\n packIndex = "
00897 << theCastorNumScheme->packIndex(zside, sector,zmodule);
00898
00899 if(verbosity&&time>100.) {
00900 edm::LogInfo("CastorShowerLibraryMaker")
00901 << "\n nentries = " << nentries
00902 << "\n time[" << ihit << "] = " << time
00903 << "\n trackID[" << ihit << "] = " << aHit->getTrackID()
00904 << "\n volumeID[" << ihit << "] = " << volumeID
00905 << "\n nphotons[" << ihit << "] = " << hitEnergy
00906 << "\n side, sector, module = " << zside <<", " << sector<<", " << zmodule
00907 << "\n packIndex " << theCastorNumScheme->packIndex(zside,sector,zmodule)
00908 << "\n X,Y,Z = " << entry.x() << ","<< entry.y() << "," << entry.z();
00909 }
00910 if (verbosity) edm::LogInfo("CastorShowerLibraryMaker") << "\n Incident Energy = "
00911 << aHit->getIncidentEnergy() << " \n" ;
00912
00913
00914 shower->setDetID(volumeID);
00915 shower->setHitPosition(position);
00916 shower->setNphotons(hitEnergy);
00917 shower->setTime(time);
00918 nHits++;
00919 }
00920
00921 if (nHits==0) {
00922 edm::LogInfo("CastorShowerLibraryMaker") << "No hits found for this track (trackID=" << ipart << ")." << std::endl;
00923 if (theCastorNumScheme) delete theCastorNumScheme;
00924 return false;
00925 }
00926 shower->setNhit(nHits);
00927
00928
00929 if (theCastorNumScheme) delete theCastorNumScheme;
00930 return true;
00931 }
00932 int& CastorShowerLibraryMaker::SLnEvtInBinE(int ebin)
00933 {
00934 if (!SLShowerptr) {
00935 edm::LogInfo("CastorShowerLibraryMaker") << "\n\nSLnEvtInBinE can be called only after BeginOfEvent\n\n";
00936 throw SimG4Exception("\n\nNULL Pointer to the shower library.");
00937 }
00938 return SLShowerptr->nEvtInBinE.at(ebin);
00939 }
00940
00941 int& CastorShowerLibraryMaker::SLnEvtInBinEta(int ebin, int etabin)
00942 {
00943 if (!SLShowerptr) {
00944 edm::LogInfo("CastorShowerLibraryMaker") << "\n\nSLnEvtInBinEta can be called only after BeginOfEvent\n\n";
00945 throw SimG4Exception("\n\nNULL Pointer to the shower library.");
00946 }
00947 return SLShowerptr->nEvtInBinEta.at(ebin).at(etabin);
00948 }
00949
00950 int& CastorShowerLibraryMaker::SLnEvtInBinPhi(int ebin, int etabin, int phibin)
00951 {
00952 if (!SLShowerptr) {
00953 edm::LogInfo("CastorShowerLibraryMaker") << "\n\nSLnEvtInBinPhi can be called only after BeginOfEvent\n\n";
00954 throw SimG4Exception("\n\nNULL Pointer to the shower library.");
00955 }
00956 return SLShowerptr->nEvtInBinPhi.at(ebin).at(etabin).at(phibin);
00957 }
00958 bool CastorShowerLibraryMaker::SLisEBinFilled(int ebin)
00959 {
00960 if (!SLShowerptr) {
00961 edm::LogInfo("CastorShowerLibraryMaker") << "\n\nSLisEBinFilled can be called only after BeginOfEvent\n\n";
00962 throw SimG4Exception("\n\nNULL Pointer to the shower library.");
00963 }
00964 if (SLShowerptr->nEvtInBinE.at(ebin)<(int)SLShowerptr->nEvtPerBinE) return false;
00965 return true;
00966 }
00967 bool CastorShowerLibraryMaker::SLisEtaBinFilled(int ebin,int etabin)
00968 {
00969 if (!SLShowerptr) {
00970 edm::LogInfo("CastorShowerLibraryMaker") << "\n\nSLisEtaBinFilled can be called only after BeginOfEvent\n\n";
00971 throw SimG4Exception("\n\nNULL Pointer to the shower library.");
00972 }
00973 if (SLShowerptr->nEvtInBinEta.at(ebin).at(etabin)<(int)SLShowerptr->nEvtPerBinEta) return false;
00974 return true;
00975 }
00976 bool CastorShowerLibraryMaker::SLisPhiBinFilled(int ebin,int etabin,int phibin)
00977 {
00978 if (!SLShowerptr) {
00979 edm::LogInfo("CastorShowerLibraryMaker") << "\n\nSLisPhiBinFilled can be called only after BeginOfEvent\n\n";
00980 throw SimG4Exception("\n\nNULL Pointer to the shower library.");
00981 }
00982 if (SLShowerptr->nEvtInBinPhi.at(ebin).at(etabin).at(phibin)<(int)SLShowerptr->nEvtPerBinPhi) return false;
00983 return true;
00984 }
00985 void CastorShowerLibraryMaker::KillSecondaries(const G4Step * aStep) {
00986 G4TrackVector *p_sec = const_cast<G4TrackVector*>(aStep->GetSecondary());
00987 for(int i=0;i<int(p_sec->size());i++) {
00988 std::cout << "Killing track ID " << p_sec->at(i)->GetTrackID() << " and its secondaries"
00989 << " Produced by Process " << p_sec->at(i)->GetCreatorProcess()->GetProcessName()
00990 << " in the volume " << aStep->GetTrack()->GetVolume()->GetName()
00991 << std::endl;
00992 p_sec->at(i)->SetTrackStatus(fKillTrackAndSecondaries);
00993 }
00994 }
00995
00996 void CastorShowerLibraryMaker::GetMissingEnergy(CaloG4HitCollection* theCAFI,double& miss_energy,double& tot_energy){
00997
00998 miss_energy = 0;
00999 tot_energy = 0;
01000 for (int ihit = 0; ihit < theCAFI->entries(); ihit++) {
01001 int id = (*theCAFI)[ihit]->getTrackID();
01002 tot_energy+=(*theCAFI)[ihit]->getEnergyDeposit();
01003 int hit_prim = 0;
01004 for(unsigned int i=0;i<thePrims.size();i++) {
01005 int particleType = thePrims.at(i)->GetPDGcode();
01006 if (MapOfSecondaries[particleType].find(id)!=MapOfSecondaries[particleType].end())
01007 hit_prim = particleType;
01008 }
01009 if (hit_prim==0) {
01010 std::cout << "Track ID " << id << " produced a hit which is not associated with a primary."
01011 << std::endl;
01012 miss_energy+=(*theCAFI)[ihit]->getEnergyDeposit();
01013 }
01014 }
01015 }