10 #include <marlin/AIDAProcessor.h>
11 #include <AIDA/IHistogramFactory.h>
12 #include <AIDA/ICloud2D.h>
13 #include <AIDA/IHistogram2D.h>
16 #include <EVENT/LCCollection.h>
17 #include <EVENT/MCParticle.h>
18 #include <EVENT/ReconstructedParticle.h>
19 #include "IMPL/LCCollectionVec.h"
20 #include <IMPL/ReconstructedParticleImpl.h>
21 #include <IMPL/ClusterImpl.h>
22 #include <IMPL/LCRelationImpl.h>
23 #include <CLHEP/Vector/LorentzVector.h>
24 #include <EVENT/LCRelation.h>
25 #include <UTIL/LCRelationNavigator.h>
27 #include <marlin/Global.h>
28 #include <gear/GEAR.h>
29 #include <gear/GearParameters.h>
30 #include <gear/BField.h>
31 #include "gear/CalorimeterParameters.h"
40 #include "marlin/VerbosityLevels.h"
43 using namespace lcio ;
44 using namespace marlin ;
46 using namespace CLHEP ;
53 void bcalhit_(
float pin_[3],
float& q_,
float vin_[3] ,
54 float& B_,
float& eBeam_,
float& zbcal_,
float pout_[3],
float vout_[3]);
64 _description =
"ForwardVeto propagates electrons or photons from IP to the BeamCal, and it gives the Energy and Momentum of the detected ones to the output ReconstructedParticles collection" ;
70 registerInputCollection( LCIO::MCPARTICLE,
72 "Name of the MCParticle collection" ,
74 std::string(
"MCParticlesSkimmed") ) ;
76 registerInputCollection( LCIO::LCRELATION,
77 "BCALInputTruthLinkName" ,
78 "Name of the truth link input collection (from SGV or Mokka)" ,
80 std::string(
"BCALMCTruthLink") ) ;
82 registerOutputCollection( LCIO::RECONSTRUCTEDPARTICLE,
84 "Name of the tagged e/gamma collection" ,
86 std::string(
"BCALEffiParticles") ) ;
88 registerOutputCollection( LCIO::CLUSTER,
90 "Name of the collection of clusters of tagged e's/gammas" ,
92 std::string(
"BCALEffiClusters") ) ;
95 registerOutputCollection( LCIO::LCRELATION,
96 "BCALEffiMCTruthLinkName",
97 "Name of the tagged e/gamma to mc-particle relation collection" ,
99 std::string(
"BCALEffiMCTruthLink") ) ;
102 registerProcessorParameter(
"BackgroundFilename" ,
103 "Name of input file for background energy density" ,
105 std::string(
"bg_aver_LDC_4T_14mrad_AntiDID.root") ) ;
108 registerProcessorParameter(
"eBeam" ,
115 registerProcessorParameter(
"zbcal" ,
116 "position of the BeamCal" ,
120 registerProcessorParameter(
"thresholdmin",
121 "Minimum energy of detected particles",
126 registerProcessorParameter(
"thresholdmax",
127 "Maximum energy of detected particles" ,
132 registerProcessorParameter(
"smearEnergy",
133 "true: electrons/photons written to new collection with smeared energy (and momentum)",
137 registerProcessorParameter(
"detectAll",
138 "true: all electrons/photons in BCAL acceptance will be written to new collection",
142 registerProcessorParameter(
"densityScaling",
143 "Scaling of the energy density w.r.t default setup",
147 registerProcessorParameter(
"DBDsample",
148 "true: assume DBD-style event sample with MCParticles with crossing angle, false: LoI-Style, MCParticles head-on",
152 registerProcessorParameter(
"newMap",
153 "true: new map with bcal layers 1 - 30, pair mon layer 31; false: old map with pair monitor in layer1",
157 registerProcessorParameter(
"writeTree",
158 "true: write root tree with debug info",
162 registerProcessorParameter(
"writeSGVMap",
163 "true: write ascii map for SGV",
167 registerProcessorParameter(
"SGVMapFilename",
168 "name of file for SGV map",
170 std::string(
"SGVmap.root") );
172 registerProcessorParameter(
"useBCALInputTruthLink",
173 "true: read BCALMCTruthLink from SGV / Mokka to find correct MCParticles",
181 streamlog_out(DEBUG) <<
" init called "
187 streamlog_out(DEBUG) <<
" background initialized "
191 streamlog_out(MESSAGE) <<
"BCalTagEfficiency::init: B-FIELD = " <<
bField << std::endl;
194 const gear::CalorimeterParameters& bcparam = Global::GEAR->getBeamCalParameters();
195 xingangle = bcparam.getDoubleVal(
"beam_crossing_angle");
213 rootfile =
new TFile(
"BCalEffi.root",
"recreate");
214 tree =
new TTree(
"Treename",
"Tree for electrons");
216 tree->Branch(
"mcp", &
mcp,
"mcp/I");
217 tree->Branch(
"pdg",
pdg,
"pdg[mcp]/I");
218 tree->Branch(
"energy",
energy,
"energy[mcp]/F");
219 tree->Branch(
"ePrime",
ePrime,
"ePrime[mcp]/F");
221 tree->Branch(
"pxIP",
pxIP,
"pxIP[mcp]/F");
222 tree->Branch(
"pyIP",
pyIP,
"pyIP[mcp]/F");
223 tree->Branch(
"pzIP",
pzIP,
"pzIP[mcp]/F");
224 tree->Branch(
"scaleP",
scaleP,
"scaleP[mcp]/F");
225 tree->Branch(
"phiIP",
phiIP,
"phiIP[mcp]/F");
226 tree->Branch(
"theIP",
theIP,
"theIP[mcp]/F");
227 tree->Branch(
"lposx",
lposx,
"lposx[mcp]/F");
228 tree->Branch(
"lposy",
lposy,
"lposy[mcp]/F");
229 tree->Branch(
"lposz",
lposz,
"lposz[mcp]/F");
230 tree->Branch(
"gposx",
gposx,
"gposx[mcp]/F");
231 tree->Branch(
"gposy",
gposy,
"gposy[mcp]/F");
232 tree->Branch(
"gposz",
gposz,
"gposz[mcp]/F");
233 tree->Branch(
"radius",
radius,
"radius[mcp]/F");
234 tree->Branch(
"phi",
phi,
"phi[mcp]/F");
235 tree->Branch(
"ebkg",
ebkg,
"ebkg[mcp]/F");
238 tree->Branch(
"rand" ,
rand,
"rand[mcp]/F");
239 tree->Branch(
"tag" ,
tag,
"tag[mcp]/I");
249 TFile *SGVmaprootfile =
new TFile(
SGVmapfilename.c_str(),
"recreate");
257 for (
int iz = -1; iz < 2; iz += 2) {
258 float halfxingangle = iz *
alpha;
259 for (
int ix = 0; ix <
nbinx; ++ix) {
261 double x =
xmin + (ix+0.5)*wx;
264 vloc[0] = cos(-halfxingangle)* x + sin(-halfxingangle)* (iz*
zbcal);
265 vloc[2] = -sin(-halfxingangle)* x + cos(-halfxingangle)* (iz*
zbcal);
266 for (
int iy = 0; iy <
nbiny; ++iy) {
268 vloc[1] =
ymin + (iy+0.5)*wy;
270 Hep3Vector lvec (vloc[0], vloc[1], vloc[2]);
271 double rloc = lvec.perp();
272 double philoc = lvec.phi();
273 if (philoc < 0) philoc += 2*
PI;
276 double sumEDensErr = 0;
281 for (
int layer=1; layer<31; layer++) {
282 if (!
newMap && layer ==1)
continue;
286 sumEDensErr += EDensErr/55.*EDensErr/55.;
295 sumEDensErr = (sumEDensErr>=0) ? sqrt(sumEDensErr) : -1.;
303 if (iz > 0) SGVmapP->Fill(x,vloc[1],sumEDens);
304 else SGVmapN->Fill(x,vloc[1],sumEDens);
305 streamlog_out(MESSAGE) <<
"SGVmap " << x <<
" " << vloc[1] <<
" " << iz*
zbcal <<
" " << sumEDens <<
" " << sumEDensErr << std::endl;
312 SGVmaprootfile->Write();
313 SGVmaprootfile->Close();
329 streamlog_out(DEBUG) <<
"+++++++++++++++++ start processing event: " << evt->getEventNumber()
330 <<
" in run: " << evt->getRunNumber()
336 LCCollection* BCALEffiMCTruthLink = 0;
338 LCRelationNavigator bcalTruthRelNav(LCIO::RECONSTRUCTEDPARTICLE , LCIO::MCPARTICLE ) ;
340 LCCollection* col = 0;
343 streamlog_out(DEBUG) <<
"Using MCParticle collection!" << std::endl;
345 if (!col) streamlog_out(ERROR) <<
"MCParticle collection not found!!!" << std::endl;
349 streamlog_out(DEBUG) <<
"Using BCALTruthLink collection!" << std::endl;
351 if (!col) streamlog_out(ERROR) <<
"TruthLinker not found!!!" << std::endl;
356 int nMCP = col->getNumberOfElements() ;
360 float pin[3]= {0, 0, 0};
361 float vin[3]= {0, 0, 0};
362 float gvout[3]= {0, 0, 0};
363 float lvout[3]= {0, 0, 0};
364 float pout[3]= {0, 0, 0};
368 for(
int i=0; i < nMCP ; i++){
375 p =
dynamic_cast<MCParticle*
>( col->getElementAt( i ) ) ;
376 if ( p->getGeneratorStatus()!=1 )
continue;
378 if ( abs(
pdg[
mcp]) != 11 && abs(
pdg[mcp]) != 22 )
continue;
379 streamlog_out(DEBUG) <<
"found MCP..." << std::endl;
382 streamlog_out(DEBUG) <<
"looking for MCP..." << std::endl;
384 rp =
dynamic_cast<LCRelation*
>( col->getElementAt( i ) ) ;
386 streamlog_out(WARNING) <<
" entry in LCRelation not found! " << std::endl;
389 if (rp->getWeight()<0.5) {
390 streamlog_out(WARNING) <<
" relation weight low: " << rp->getWeight() << std::endl;
393 p =
dynamic_cast<MCParticle*
>(rp->getTo());
394 streamlog_out(DEBUG) <<
"found MCP with PDG = " << p->getPDG() ;
395 streamlog_out(DEBUG) <<
" and energy = " << p->getEnergy() << std::endl;
405 pin[0] = p->getMomentum()[0];
406 pin[1] = p->getMomentum()[1];
407 pin[2] = p->getMomentum()[2];
414 HepLorentzVector p4v(pin[0], pin[1], pin[2],
energy[
mcp]);
416 streamlog_out(DEBUG) <<
"phi of electron/photon before +=2PI " <<
phiIP[
mcp] << std::endl;
422 streamlog_out(DEBUG) <<
"energy of electron/photon = " <<
energy[
mcp] << std::endl;
423 streamlog_out(DEBUG) <<
"phi at IP of electron/photon = " <<
phiIP[
mcp] << std::endl;
424 streamlog_out(DEBUG) <<
"pt of electron/photon = " << p4v.perp() << std::endl;
432 if( abs(
pdg[mcp]) == 11) {
436 gvout[0]=(pin[0]/abs(pin[2]))*
zbcal;
437 gvout[1]=(pin[1]/abs(pin[2]))*
zbcal;
438 gvout[2]=(pin[2]/abs(pin[2]))*
zbcal;
445 float halfxingangle = pin[2]>0 ?
alpha : -
alpha;
451 lvout[0] = cos(-halfxingangle)* gvout[0] + sin(-halfxingangle)* gvout[2];
453 lvout[2] = -sin(-halfxingangle)* gvout[0] + cos(-halfxingangle)* gvout[2];
468 gvout[0] = cos(halfxingangle)* lvout[0] + sin(halfxingangle)* lvout[2];
470 gvout[2] = -sin(halfxingangle)* lvout[0] + cos(halfxingangle)* lvout[2];
474 streamlog_out(DEBUG) <<
"entry point on BeamCal surface, global ILD coordinates:" << std::endl;
475 streamlog_out(DEBUG) <<
"gvout[0] = " << gvout[0] <<
", gvout[1] = " << gvout[1] <<
", gvout[2] = " << gvout[2] << std::endl;
476 streamlog_out(DEBUG) <<
"entry point on BeamCal surface, local coordinates:" << std::endl;
477 streamlog_out(DEBUG) <<
"lvout[0] = " << lvout[0] <<
", lvout[1] = " << lvout[1] <<
", lvout[2] = " << lvout[2] << std::endl;
481 Hep3Vector lvvec (lvout[0], lvout[1], lvout[2]);
484 streamlog_out(DEBUG) <<
"radius on BeamCal surface in local coordinates = " <<
radius[
mcp] << std::endl;
487 streamlog_out(DEBUG) <<
"phi on BeamCal surface in local coordinates = " <<
phi[
mcp] << std::endl;
489 streamlog_out(DEBUG) <<
"phi after +2PI = " <<
phi[
mcp] << std::endl;
490 if (p4v.perp() < 1E-3)
phi[mcp] = 0;
494 Hep3Vector gvvec (gvout[0], gvout[1], gvout[2]);
495 float gphi = gvvec.phi();
496 streamlog_out(DEBUG) <<
"gphi on BeamCal surface in global coordinates = " << gphi << std::endl;
497 if (gphi < 0) gphi += 2*
PI;
498 streamlog_out(DEBUG) <<
"gphi after +2PI = " << gphi << std::endl;
499 float gtheta = gvvec.theta();
500 streamlog_out(DEBUG) <<
"gtheta on BeamCal surface in global coordinates = " << gtheta << std::endl;
501 streamlog_out(DEBUG) <<
"radius on BeamCal surface in global coordinates = " << gvvec.perp()*lvvec.mag()/gvvec.mag() << std::endl;
511 double en_dens_err = 0;
513 for (
int layer=1; layer<31; layer++) {
514 if (!
newMap && layer ==1)
continue;
517 if(lvout[2] < 0) sign = -1;
519 streamlog_out(DEBUG) <<
"energy density in layer " << layer * sign <<
" = " << en_dens << std::endl;
533 streamlog_out(DEBUG) <<
"background energy density sum = " <<
ebkg[
mcp] << std::endl;
540 streamlog_out(DEBUG) <<
"scaling background energy density sum with factor " <<
densityScaling
541 <<
", scaled density = " <<
ebkg[
mcp] <<std::endl;
555 streamlog_out(DEBUG) <<
"Particle made SGV cluster, but ebkg[mcp] = " <<
ebkg[
mcp]
556 <<
", so not in map: radius[mcp] = " <<
radius[
mcp]
557 <<
", phi[mcp] = " <<
phi[
mcp]*180/3.1415 << std::endl;
560 else if (
ebkg[mcp] > 0 ) {
568 streamlog_out(WARNING) <<
"not in original range of parametrisation , energy = " <<
energy[
mcp] << std::endl;
572 p1 = -8.936e-3 + 6.05e-4*energy[
mcp] -1.719e-6*energy[
mcp]*energy[
mcp];
573 p2 = 6.112e-2 + 2.84e+3/(energy[
mcp]*energy[
mcp]);
586 streamlog_out(ERROR) <<
"not in valid range of parametrisation , ebkg = "
595 char energystring [50];
600 sprintf(energystring,
"%f",
energy[mcp]);
602 charseed[0]=energystring[4];
603 charseed[1]=energystring[5];
604 charseed[2]=energystring[6];
605 charseed[3]=energystring[7];
606 charseed[4]=energystring[8];
608 seed = atoi(charseed);
610 TRandom3 *randGen =
new TRandom3(seed);
617 ReconstructedParticleImpl* particle =
new ReconstructedParticleImpl;
618 ClusterImpl* cluster =
new ClusterImpl;
619 streamlog_out(DEBUG) <<
"adding relation between particle " << particle <<
"and MCParticle " << p << endl;
620 bcalTruthRelNav.addRelation( particle , p , 1.0) ;
626 const double m = p->getMass() ;
627 particle->setMass(m);
628 particle->setCharge(q);
652 double deltaE = randGen->Gaus() * sigmaE;
658 particle->setMomentum(pnew);
664 cluster->setEnergy(particle->getEnergy());
665 cluster->setEnergyError(sigmaE);
666 cluster->setPosition(gvout);
667 cluster->setITheta(gtheta);
668 cluster->setIPhi(gphi);
669 cluster->subdetectorEnergies().resize(6); cluster->subdetectorEnergies()[5] = particle->getEnergy();
671 particle->addCluster(cluster);
673 BCALCol->addElement(particle);
675 BCALClusters->addElement(cluster);
690 streamlog_out(DEBUG) <<
"Detected particle with ID " <<
pdg[
mcp] << endl;
691 streamlog_out(DEBUG) <<
"Energy before smearing = " <<
energy[
mcp] << endl;
692 streamlog_out(DEBUG) <<
"Energy after smearing = " <<
ePrime[
mcp] << endl;
693 streamlog_out(DEBUG) <<
"Efficiency= " <<
efficiency[
mcp] << endl;
694 streamlog_out(DEBUG) <<
"E background= " <<
ebkg[
mcp] << endl;
695 streamlog_out(DEBUG) <<
"+++++++++++++++++++" << endl;
702 streamlog_out(DEBUG) <<
"filling tree, mcp = " << mcp << endl;
716 BCALEffiMCTruthLink = bcalTruthRelNav.createLCCollection() ;
717 streamlog_out(DEBUG) <<
"name of BCALEffiMCTruthLink: " <<
_BCALEffiMCTruthLinkName <<
", number of elements = " << BCALEffiMCTruthLink->getNumberOfElements() << endl;
718 streamlog_out(DEBUG) <<
"name of BCALCol: " <<
_BCALParticleName <<
", number of elements = " << BCALCol->getNumberOfElements() << endl;
731 streamlog_out(DEBUG) <<
"+++++++++++++++++ finished processing event: " << evt->getEventNumber()
732 <<
" in run: " << evt->getRunNumber()
std::string _BCALInputTruthLinkName
Bool_t GetEnergyDensity(const Int_t &rLayer, const Double_t &rRadius, const Double_t &rPhi, Double_t *pEnDens, Double_t *pEnDensError) const
virtual void end()
Called after data processing for clean up.
virtual void processEvent(LCEvent *evt)
Called for every event - the working horse.
BCalTagEfficiency aBCalTagEfficiency
std::string backgroundfilename
CLHEP::Hep3Vector Vector3D
std::string _BCALEffiMCTruthLinkName
std::string _BCALClusterName
virtual void check(LCEvent *evt)
Marlin processor to calculate BCAL tagging efficiency.
std::string _MCParticleName
Input collection name.
virtual void processRunHeader(LCRunHeader *run)
Called for every run.
std::vector< LCCollection * > LCCollectionVec
std::string _BCALParticleName
virtual void init()
Called at the begin of the job before anything is read.
std::string SGVmapfilename
void bcalhit_(float pin_[3], float &q_, float vin_[3], float &B_, float &eBeam_, float &zbcal_, float pout_[3], float vout_[3])