1 #include "EVENT/LCIO.h"
2 #include "EVENT/LCRunHeader.h"
3 #include "EVENT/LCCollection.h"
4 #include "EVENT/LCParameters.h"
5 #include "EVENT/ReconstructedParticle.h"
6 #include "IMPL/ReconstructedParticleImpl.h"
11 #include "CLHEP/Vector/LorentzVector.h"
12 #include "CLHEP/Vector/ThreeVector.h"
18 #include <marlin/Global.h>
29 registerProcessorParameter(
"Printing" ,
30 "Print certain messages" ,
35 std::string zdecay =
"ee";
36 registerProcessorParameter(
"ZDecay" ,
42 std::string inputParticleCollectionName =
"PandoraPFOs";
43 registerInputCollection( LCIO::RECONSTRUCTEDPARTICLE,
44 "InputParticleCollectionName" ,
45 "Input Particle Collection Name " ,
47 inputParticleCollectionName);
50 std::string outputParticleCollectionName =
"eeX";
51 registerOutputCollection( LCIO::RECONSTRUCTEDPARTICLE,
52 "OutputParticleCollectionName" ,
53 "Output Particle Collection Name " ,
55 outputParticleCollectionName);
58 registerProcessorParameter(
"AddPhotons" ,
59 "Include photons with reconstructed Z" ,
63 registerProcessorParameter(
"CanUseClusterEnergyForElectrons" ,
64 "Allow possibilit of cluster not track used for electrons",
69 registerProcessorParameter(
"FermionMomentumCut" ,
70 "Momentum Cut for fermion from Z decay" ,
74 registerProcessorParameter(
"CosTrackGammaCut" ,
75 "Minimum cosine of track-photon angle" ,
79 registerProcessorParameter(
"MaxDeltaMz" ,
80 "Maximum difference between candidate and Z mass" ,
84 registerProcessorParameter(
"MuonEcalEnergyCut" ,
85 "Cut on muon ECAL energy" ,
89 registerProcessorParameter(
"MuonHcalEnergyCut" ,
90 "Cut on Muon HCAL energy" ,
95 registerProcessorParameter(
"MuonHcalEnergyCut1" ,
96 "Cut on Muon HCAL energy (alt)" ,
100 registerProcessorParameter(
"ElectronEcalEnergyCut" ,
101 "Cut on electron ECAL energy" ,
105 registerProcessorParameter(
"ElectronHcalEnergyCut" ,
106 "Cut on Electron HCAL energy" ,
111 registerProcessorParameter(
"ElectronEoverPCutLow" ,
112 "Cut on Electron E/p cut" ,
116 registerProcessorParameter(
"ElectronEoverPCutHigh" ,
117 "Cut on Electron E/p cut" ,
149 if(
_zdecay.find(
"ee")!=std::string::npos)this->
FindZee(recparcol);
152 if(
_zdecay.find(
"tautau")!=std::string::npos)streamlog_out(ERROR) <<
"ZFinder tautau decay mode not implemented" << std::endl;
153 if(
_zdecay.find(
"qq")!=std::string::npos)streamlog_out(ERROR) <<
"ZFinder qq decay mode not implemented" << std::endl;
177 typedef const std::vector<std::string>
StringVec ;
178 StringVec* strVec = evt->getCollectionNames() ;
179 for(StringVec::const_iterator name=strVec->begin(); name!=strVec->end(); name++){
181 LCCollection* col = evt->getCollection(*name);
182 unsigned int nelem = col->getNumberOfElements();
184 for(
unsigned int i=0;i<nelem;i++){
185 ReconstructedParticle* recoPart =
dynamic_cast<ReconstructedParticle*
>(col->getElementAt(i));
191 if(
_printing>1)std::cout <<
"Find PFOs : " << tf << std::endl;
204 std::vector<LorentzVector>pmuplus;
205 std::vector<LorentzVector>pmuminus;
206 std::vector<ReconstructedParticle*>pMplusPfoVec;
207 std::vector<ReconstructedParticle*>pMminusPfoVec;
208 for(
unsigned int i=0;i<
_pfovec.size();i++){
209 if(
_pfovec[i]->getCharge()!=0){
210 ClusterVec c1 =
_pfovec[i]->getClusters();
215 ecal1 = c1[0]->getSubdetectorEnergies()[0] + c1[0]->getSubdetectorEnergies()[3];
216 hcal1 = c1[0]->getSubdetectorEnergies()[1] + c1[0]->getSubdetectorEnergies()[4];
217 muon1 = c1[0]->getSubdetectorEnergies()[2];
226 if(
_pfovec[i]->getCharge()>0.5){
227 pmuplus.push_back(pmu);
228 pMplusPfoVec.push_back(
_pfovec[i]);
230 if(
_pfovec[i]->getCharge()<-0.5){
231 pmuminus.push_back(pmu);
232 pMminusPfoVec.push_back(
_pfovec[i]);
240 ReconstructedParticle* pMplus = NULL;
241 ReconstructedParticle* pMminus = NULL;
242 float bestdmz = 999.;
243 unsigned int besti=0;
244 unsigned int bestj=0;
245 for(
unsigned int i=0;i<pmuplus.size();i++){
246 for(
unsigned int j=0;j<pmuminus.size();j++){
248 float massmumu = pmumu.m();
249 if( fabs(massmumu-91.2) < bestdmz){
250 bestdmz = fabs(massmumu-91.2);
252 pMplus = pMplusPfoVec[i];
253 pMminus = pMminusPfoVec[j];
260 float Mom[3] = {0.,0.,0.};
261 if(bestdmz<
_dmzcut && pMplus!=NULL && pMminus!=NULL){
262 ReconstructedParticleImpl * recoPart =
new ReconstructedParticleImpl();
263 recoPart->addParticle(pMplus);
264 recoPart->addParticle(pMminus);
265 float pxem = pMminus->getMomentum()[0];
266 float pyem = pMminus->getMomentum()[1];
267 float pzem = pMminus->getMomentum()[2];
268 float eem = pMminus->getEnergy();
269 float pxep = pMplus->getMomentum()[0];
270 float pyep = pMplus->getMomentum()[1];
271 float pzep = pMplus->getMomentum()[2];
272 float eep = pMplus->getEnergy();
274 Mom[0] = Mom[0] + pxem+pxep;
275 Mom[1] = Mom[1] + pyem+pyep;
276 Mom[2] = Mom[2] + pzem+pzep;
280 for(
unsigned int i=0;i<
_pfovec.size();i++){
282 float pxg =
_pfovec[i]->getMomentum()[0];
283 float pyg =
_pfovec[i]->getMomentum()[1];
284 float pzg =
_pfovec[i]->getMomentum()[2];
285 float eg =
_pfovec[i]->getEnergy();
287 if(eg>0&&eem>0)cosm=(pxg*pxem+pyg*pyem+pzg*pzem)/eg/eem;
289 if(eg>0&&eep>0)cosp=(pxg*pxep+pyg*pyep+pzg*pzep)/eg/eep;
291 recoPart->addParticle(
_pfovec[i]);
302 float Mass = (Energy*Energy-Mom[0]*Mom[0]-Mom[1]*Mom[1]-Mom[2]*Mom[2]);
303 if(Mass>0)Mass=sqrt(Mass);
304 recoPart->setMomentum( Mom );
305 recoPart->setEnergy( Energy );
306 recoPart->setMass( Mass );
307 recoPart->setCharge( 0. );
308 recoPart->setType( 94 );
309 if(
_printing>1)std::cout <<
"Found mmX : " << Mass << std::endl;
312 recparcol->addElement( recoPart );
325 std::vector<LorentzVector>peplus;
326 std::vector<LorentzVector>peminus;
327 std::vector<ReconstructedParticle*>pEplusPfoVec;
328 std::vector<ReconstructedParticle*>pEminusPfoVec;
329 for(
unsigned int i=0;i<
_pfovec.size();i++){
331 ClusterVec c1 =
_pfovec[i]->getClusters();
336 ecal1 = c1[0]->getSubdetectorEnergies()[0] + c1[0]->getSubdetectorEnergies()[3];
337 hcal1 = c1[0]->getSubdetectorEnergies()[1] + c1[0]->getSubdetectorEnergies()[4];
338 muon1 = c1[0]->getSubdetectorEnergies()[2];
344 float eop = ecal1/
_pfovec[i]->getEnergy();
347 if(muon1>0.01)electron=
false;
351 if(
_pfovec[i]->getCharge()>0.5){
352 peplus.push_back(pe);
353 pEplusPfoVec.push_back(
_pfovec[i]);
355 if(
_pfovec[i]->getCharge()<-0.5){
356 peminus.push_back(pe);
357 pEminusPfoVec.push_back(
_pfovec[i]);
365 ReconstructedParticle* pEplus = NULL;
366 ReconstructedParticle* pEminus = NULL;
367 float bestdmz = 999.;
368 unsigned int besti = 999;
369 unsigned int bestj = 999;
370 for(
unsigned int i=0;i<peplus.size();i++){
371 for(
unsigned int j=0;j<peminus.size();j++){
373 float massee = pee.m();
374 if( fabs(massee-91.2) < bestdmz){
375 bestdmz = fabs(massee-91.2);
377 pEplus = pEplusPfoVec[i];
378 pEminus = pEminusPfoVec[j];
385 float Mom[3] = {0.,0.,0.};
386 if(bestdmz<
_dmzcut && pEplus!=NULL && pEminus!=NULL){
387 ReconstructedParticleImpl * recoPart =
new ReconstructedParticleImpl();
388 recoPart->addParticle(pEplus);
389 recoPart->addParticle(pEminus);
390 float pxem = pEminus->getMomentum()[0];
391 float pyem = pEminus->getMomentum()[1];
392 float pzem = pEminus->getMomentum()[2];
393 float eem = pEminus->getEnergy();
394 float pxep = pEplus->getMomentum()[0];
395 float pyep = pEplus->getMomentum()[1];
396 float pzep = pEplus->getMomentum()[2];
397 float eep = pEplus->getEnergy();
400 std::vector<ReconstructedParticle*>photons;
401 float trackEPlus = 0;
402 float trackEMinus = 0;
403 float clusterEPlus = 0;
404 float clusterEMinus = 0;
405 float sigmaEPlus = 999.;
406 float sigmaEMinus = 999.;
407 float chiEPlus = 999.;
408 float chiEMinus = 999.;
410 float sigpMinus = 0.;
415 const EVENT::ClusterVec ci = pEplus->getClusters();
416 const EVENT::TrackVec ti = pEplus->getTracks();
417 trackEPlus = pEplus->getEnergy();
418 if(ti.size()==1)sigpPlus = trackEPlus*sqrt(ti[0]->getCovMatrix()[5])/fabs(ti[0]->getOmega());
420 clusterEPlus = ci[0]->getEnergy();
421 sigmaEPlus = 0.18*sqrt(clusterEPlus);
422 chiEPlus = (trackEPlus-clusterEPlus)/sqrt(sigmaEPlus*sigmaEPlus+sigpPlus*sigpPlus);
423 vecEPlus.set(ci[0]->getPosition()[0],ci[0]->getPosition()[1],ci[0]->getPosition()[2]);
425 const EVENT::ClusterVec cj = pEminus->getClusters();
426 const EVENT::TrackVec tj = pEminus->getTracks();
427 trackEMinus = pEminusPfoVec[bestj]->getEnergy();
428 if(tj.size()==1)sigpMinus = trackEMinus*sqrt(tj[0]->getCovMatrix()[5])/fabs(tj[0]->getOmega());
430 clusterEMinus = cj[0]->getEnergy();
431 sigmaEMinus = 0.18*sqrt(clusterEMinus);
432 chiEMinus = (trackEMinus-clusterEMinus)/sqrt(sigmaEMinus*sigmaEMinus+sigpMinus*sigpMinus);
433 vecEMinus.set(cj[0]->getPosition()[0],cj[0]->getPosition()[1],cj[0]->getPosition()[2]);
438 for(
unsigned int i=0;i<
_pfovec.size();i++){
440 float pxg =
_pfovec[i]->getMomentum()[0];
441 float pyg =
_pfovec[i]->getMomentum()[1];
442 float pzg =
_pfovec[i]->getMomentum()[2];
443 float eg =
_pfovec[i]->getEnergy();
445 if(eg>0&&eem>0)cosm=(pxg*pxem+pyg*pyem+pzg*pzem)/eg/eem;
447 if(eg>0&&eep>0)cosp=(pxg*pxep+pyg*pyep+pzg*pzep)/eg/eep;
454 const EVENT::ClusterVec c =
_pfovec[i]->getClusters();
457 Vector3D vecg(c[0]->getPosition()[0],c[0]->getPosition()[1],c[0]->getPosition()[2]);
459 float magg = vecg.mag();
460 if(magg>0)drp = v.mag()/magg;
461 v = vecg.cross(vecEMinus);
462 if(magg>0)drm = v.mag()/vecg.mag();
466 float chiNew = (trackEPlus-clusterEPlus-eg)/sigmaEPlus;
467 if(drp<20.0)merge =
true;
469 if(drp<30.0 && chiEPlus>4.0 && fabs(chiNew)<chiEPlus)merge =
true;
470 if(drp<40.0 && chiEPlus>5.0 && fabs(chiNew)<chiEPlus)merge =
true;
471 if(drp<50.0 && chiEPlus>7.0 && fabs(chiNew)<chiEPlus)merge =
true;
473 if( fabs(chiEPlus)<2.0 && chiNew*chiNew>chiEPlus*chiEPlus+5.0)merge =
false;
475 if(drp<10.0)merge =
true;
478 recoPart->addParticle(
_pfovec[i]);
480 sigmaEPlus = 0.18*sqrt(clusterEPlus);
481 chiEPlus = (trackEPlus-clusterEPlus)/sqrt(sigmaEPlus*sigmaEPlus+sigpPlus*sigpPlus);
485 recoPart->addParticle(
_pfovec[i]);
489 float chiNew = (trackEMinus-clusterEMinus-eg)/sigmaEMinus;
492 if(drm<20.0)merge =
true;
494 if(drm<30.0 && chiEMinus>4.0 && fabs(chiNew)<chiEMinus)merge =
true;
495 if(drm<40.0 && chiEMinus>5.0 && fabs(chiNew)<chiEMinus)merge =
true;
496 if(drm<50.0 && chiEMinus>7.0 && fabs(chiNew)<chiEMinus)merge =
true;
498 if( fabs(chiEMinus)<2.0 && chiNew*chiNew>chiEMinus*chiEMinus+5.0)merge =
false;
500 if(drm<10.0)merge =
true;
503 recoPart->addParticle(
_pfovec[i]);
505 sigmaEMinus = 0.18*sqrt(clusterEMinus);
506 chiEMinus = (trackEMinus-clusterEMinus)/sqrt(sigmaEMinus*sigmaEMinus+sigpMinus*sigpMinus);
510 recoPart->addParticle(
_pfovec[i]);
522 Mom[0] = Mom[0] + pxem+pxep;
523 Mom[1] = Mom[1] + pyem+pyep;
524 Mom[2] = Mom[2] + pzem+pzep;
526 for(
unsigned int i=0;i<photons.size();i++){
527 Energy += photons[i]->getEnergy();
528 Mom[0] += photons[i]->getMomentum()[0];
529 Mom[1] += photons[i]->getMomentum()[1];
530 Mom[2] += photons[i]->getMomentum()[2];
532 float Mass = sqrt(Energy*Energy-Mom[0]*Mom[0]-Mom[1]*Mom[1]-Mom[2]*Mom[2]);
538 float MomX[3]={0.,0.,0.};
541 if(chiEPlus<-3.5)scaleP = clusterEPlus/trackEPlus;
543 if(chiEMinus<-3.5)scaleM = clusterEMinus/trackEMinus;
544 EnergyX = Energy + eep*(scaleP-1.) +eem*(scaleM-1.);
545 MomX[0] = Mom[0] + pxem*(scaleM-1.)+pxep*(scaleP-1.);
546 MomX[1] = Mom[1] + pyem*(scaleM-1.)+pyep*(scaleP-1.);
547 MomX[2] = Mom[2] + pzem*(scaleM-1.)+pzep*(scaleP-1.);
548 float MassX = sqrt(EnergyX*EnergyX-MomX[0]*MomX[0]-MomX[1]*MomX[1]-MomX[2]*MomX[2]);
549 if(fabs(MassX-91.2)<fabs(Mass-91.2)){
554 Mass = sqrt(Energy*Energy-Mom[0]*Mom[0]-Mom[1]*Mom[1]-Mom[2]*Mom[2]);
559 if(Mass>0)Mass=sqrt(Mass);
560 recoPart->setMomentum( Mom );
561 recoPart->setEnergy( Energy );
562 recoPart->setMass( Mass );
563 recoPart->setCharge( 0. );
564 recoPart->setType( 94 );
565 if(
_printing>1)std::cout <<
"Found eeX : " << Mass << std::endl;
568 recparcol->addElement( recoPart );
std::vector< ReconstructedParticle * > _pfovec
void FindZee(LCCollectionVec *)
CLHEP::Hep3Vector Vector3D
virtual void end()
Called after data processing for clean up.
float _electronHcalEnergyCut
std::string _inputParticleCollectionName
virtual void init()
Called at the begin of the job before anything is read.
void FindZmumu(LCCollectionVec *)
virtual void processRunHeader(LCRunHeader *run)
Called for every run.
float _electronEcalEnergyCut
float _electronEoPCutHigh
int _canUseClusterEnergyForElectrons
CLHEP::HepLorentzVector LorentzVector
virtual void processEvent(LCEvent *evt)
Called for every event - the working horse.
std::vector< LCCollection * > LCCollectionVec
std::string _outputParticleCollectionName
float _muonHcalEnergyCut1
bool FindPFOs(LCEvent *evt)
ZFinder: Returns the best Z->ee/Z->mm candidate in the event.
std::vector< std::string > StringVec