CMS 3D CMS Logo

PiZeroAnalyzer.cc
Go to the documentation of this file.
1 #include <iostream>
2 
4 
5 //#define TWOPI 6.283185308
6 //
7 
18 using namespace std;
19 
21 {
22  fName_ = pset.getUntrackedParameter<std::string>("Name");
23  prescaleFactor_ = pset.getUntrackedParameter<int>("prescaleFactor",1);
24 
25  barrelEcalHits_token_ = consumes<edm::SortedCollection<EcalRecHit,edm::StrictWeakOrdering<EcalRecHit> > >(pset.getParameter<edm::InputTag>("barrelEcalHits"));
26  endcapEcalHits_token_ = consumes<edm::SortedCollection<EcalRecHit,edm::StrictWeakOrdering<EcalRecHit> > >(pset.getParameter<edm::InputTag>("endcapEcalHits"));
27 
28  nEvt_=0;
29 
30  // parameters for Pizero finding
31  seleXtalMinEnergy_ = pset.getParameter<double> ("seleXtalMinEnergy");
32  clusSeedThr_ = pset.getParameter<double> ("clusSeedThr");
33  clusEtaSize_ = pset.getParameter<int> ("clusEtaSize");
34  clusPhiSize_ = pset.getParameter<int> ("clusPhiSize");
35  ParameterLogWeighted_ = pset.getParameter<bool> ("ParameterLogWeighted");
36  ParameterX0_ = pset.getParameter<double> ("ParameterX0");
37  ParameterT0_barl_ = pset.getParameter<double> ("ParameterT0_barl");
38  ParameterW0_ = pset.getParameter<double> ("ParameterW0");
39 
40  selePtGammaOne_ = pset.getParameter<double> ("selePtGammaOne");
41  selePtGammaTwo_ = pset.getParameter<double> ("selePtGammaTwo");
42  seleS4S9GammaOne_ = pset.getParameter<double> ("seleS4S9GammaOne");
43  seleS4S9GammaTwo_ = pset.getParameter<double> ("seleS4S9GammaTwo");
44  selePtPi0_ = pset.getParameter<double> ("selePtPi0");
45  selePi0Iso_ = pset.getParameter<double> ("selePi0Iso");
46  selePi0BeltDR_ = pset.getParameter<double> ("selePi0BeltDR");
47  selePi0BeltDeta_ = pset.getParameter<double> ("selePi0BeltDeta");
48  seleMinvMaxPi0_ = pset.getParameter<double> ("seleMinvMaxPi0");
49  seleMinvMinPi0_ = pset.getParameter<double> ("seleMinvMinPi0");
50 
51  posCalcParameters_ = pset.getParameter<edm::ParameterSet>("posCalcParameters");
52 }
53 
55 }
56 
58  edm::Run const & /* iRun */,
59  edm::EventSetup const & /* iSetup */)
60 {
61  currentFolder_.str("");
62  currentFolder_ << "Egamma/PiZeroAnalyzer/";
63  ibooker.setCurrentFolder(currentFolder_.str());
64 
65  hMinvPi0EB_ = ibooker.book1D("Pi0InvmassEB","Pi0 Invariant Mass in EB",100,0.,0.5);
66  hMinvPi0EB_->setAxisTitle("Inv Mass [GeV] ",1);
67 
68  hPt1Pi0EB_ = ibooker.book1D("Pt1Pi0EB","Pt 1st most energetic Pi0 photon in EB",100,0.,20.);
69  hPt1Pi0EB_->setAxisTitle("1st photon Pt [GeV] ",1);
70 
71  hPt2Pi0EB_ = ibooker.book1D("Pt2Pi0EB","Pt 2nd most energetic Pi0 photon in EB",100,0.,20.);
72  hPt2Pi0EB_->setAxisTitle("2nd photon Pt [GeV] ",1);
73 
74  hPtPi0EB_ = ibooker.book1D("PtPi0EB","Pi0 Pt in EB",100,0.,20.);
75  hPtPi0EB_->setAxisTitle("Pi0 Pt [GeV] ",1);
76 
77  hIsoPi0EB_ = ibooker.book1D("IsoPi0EB","Pi0 Iso in EB",50,0.,1.);
78  hIsoPi0EB_->setAxisTitle("Pi0 Iso",1);
79 }
80 
82 {
83  using namespace edm;
84 
85  if (nEvt_% prescaleFactor_ ) return;
86  nEvt_++;
87  LogInfo("PiZeroAnalyzer") << "PiZeroAnalyzer Analyzing event number: " << e.id() << " Global Counter " << nEvt_ <<"\n";
88 
89  // Get EcalRecHits
90  bool validEcalRecHits=true;
91  Handle<EcalRecHitCollection> barrelHitHandle;
93  e.getByToken(barrelEcalHits_token_, barrelHitHandle);
94  if (!barrelHitHandle.isValid()) {
95  edm::LogError("PhotonProducer") << "Error! Can't get the product: barrelEcalHits_token_";
96  validEcalRecHits=false;
97  }
98 
99  Handle<EcalRecHitCollection> endcapHitHandle;
100  e.getByToken(endcapEcalHits_token_, endcapHitHandle);
102  if (!endcapHitHandle.isValid()) {
103  edm::LogError("PhotonProducer") << "Error! Can't get the product: endcapEcalHits_token_";
104  validEcalRecHits=false;
105  }
106 
107  if (validEcalRecHits) makePizero(esup, barrelHitHandle, endcapHitHandle);
108 }
109 
111  const EcalRecHitCollection *hitCollection_p = rhEB.product();
112 
113  edm::ESHandle<CaloGeometry> geoHandle;
114  es.get<CaloGeometryRecord>().get(geoHandle);
115 
116  edm::ESHandle<CaloTopology> theCaloTopology;
117  es.get<CaloTopologyRecord>().get(theCaloTopology);
118 
119  const CaloSubdetectorGeometry *geometry_p;
120  const CaloSubdetectorTopology *topology_p;
121  const CaloSubdetectorGeometry *geometryES_p;
122  geometry_p = geoHandle->getSubdetectorGeometry(DetId::Ecal,EcalBarrel);
123  geometryES_p = geoHandle->getSubdetectorGeometry(DetId::Ecal, EcalPreshower);
124 
125  // Parameters for the position calculation:
126  PositionCalc posCalculator_ = PositionCalc(posCalcParameters_);
127  //
128  std::map<DetId, EcalRecHit> recHitsEB_map;
129  //
130  std::vector<EcalRecHit> seeds;
131 
132  seeds.clear();
133  //
134  vector<EBDetId> usedXtals;
135  usedXtals.clear();
136  //
138  //
139  static const int MAXCLUS = 2000;
140  int nClus=0;
141  vector<float> eClus;
142  vector<float> etClus;
143  vector<float> etaClus;
144  vector<float> phiClus;
145  vector<EBDetId> max_hit;
146  vector< vector<EcalRecHit> > RecHitsCluster;
147  vector<float> s4s9Clus;
148 
149  // find cluster seeds in EB
150  for(itb=rhEB->begin(); itb!=rhEB->end(); ++itb){
151  EBDetId id(itb->id());
152  double energy = itb->energy();
153  if (energy > seleXtalMinEnergy_) {
154  std::pair<DetId, EcalRecHit> map_entry(itb->id(), *itb);
155  recHitsEB_map.insert(map_entry);
156  }
157  if (energy > clusSeedThr_) seeds.push_back(*itb);
158  } // Eb rechits
159 
160  sort(seeds.begin(), seeds.end(), ecalRecHitLess());
161  for (std::vector<EcalRecHit>::iterator itseed=seeds.begin(); itseed!=seeds.end(); itseed++) {
162  EBDetId seed_id = itseed->id();
163  std::vector<EBDetId>::const_iterator usedIds;
164 
165  bool seedAlreadyUsed=false;
166  for(usedIds=usedXtals.begin(); usedIds!=usedXtals.end(); usedIds++){
167  if(*usedIds==seed_id){
168  seedAlreadyUsed=true;
169  //cout<< " Seed with energy "<<itseed->energy()<<" was used !"<<endl;
170  break;
171  }
172  }
173  if(seedAlreadyUsed)continue;
174  topology_p = theCaloTopology->getSubdetectorTopology(DetId::Ecal,EcalBarrel);
175  std::vector<DetId> clus_v = topology_p->getWindow(seed_id,clusEtaSize_,clusPhiSize_);
176  //std::vector<DetId> clus_used;
177  std::vector<std::pair<DetId, float> > clus_used;
178 
179  vector<EcalRecHit> RecHitsInWindow;
180 
181  double simple_energy = 0;
182 
183  for (std::vector<DetId>::iterator det=clus_v.begin(); det!=clus_v.end(); det++) {
184  // EBDetId EBdet = *det;
185  // cout<<" det "<< EBdet<<" ieta "<<EBdet.ieta()<<" iphi "<<EBdet.iphi()<<endl;
186  bool HitAlreadyUsed=false;
187  for(usedIds=usedXtals.begin(); usedIds!=usedXtals.end(); usedIds++){
188  if(*usedIds==*det){
189  HitAlreadyUsed=true;
190  break;
191  }
192  }
193  if(HitAlreadyUsed)continue;
194  if (recHitsEB_map.find(*det) != recHitsEB_map.end()){
195  // cout<<" Used det "<< EBdet<<endl;
196  std::map<DetId, EcalRecHit>::iterator aHit;
197  aHit = recHitsEB_map.find(*det);
198  usedXtals.push_back(*det);
199  RecHitsInWindow.push_back(aHit->second);
200  clus_used.push_back( std::pair<DetId, float>(*det, 1.) );
201  simple_energy = simple_energy + aHit->second.energy();
202  }
203  }
204 
205  math::XYZPoint clus_pos = posCalculator_.Calculate_Location(clus_used,hitCollection_p,geometry_p,geometryES_p);
206  float theta_s = 2. * atan(exp(-clus_pos.eta()));
207  float p0x_s = simple_energy * sin(theta_s) * cos(clus_pos.phi());
208  float p0y_s = simple_energy * sin(theta_s) * sin(clus_pos.phi());
209  // float p0z_s = simple_energy * cos(theta_s);
210  float et_s = sqrt( p0x_s*p0x_s + p0y_s*p0y_s);
211 
212  //cout << " Simple Clustering: E,Et,px,py,pz: "<<simple_energy<<" "<<et_s<<" "<<p0x_s<<" "<<p0y_s<<" "<<endl;
213 
214  eClus.push_back(simple_energy);
215  etClus.push_back(et_s);
216  etaClus.push_back(clus_pos.eta());
217  phiClus.push_back(clus_pos.phi());
218  max_hit.push_back(seed_id);
219  RecHitsCluster.push_back(RecHitsInWindow);
220  //Compute S4/S9 variable
221  //We are not sure to have 9 RecHits so need to check eta and phi:
222  float s4s9_[4];
223  for(int i=0;i<4;i++)s4s9_[i]= itseed->energy();
224  for(unsigned int j=0; j<RecHitsInWindow.size();j++){
225  //cout << " Simple cluster rh, ieta, iphi : "<<((EBDetId)RecHitsInWindow[j].id()).ieta()<<" "<<((EBDetId)RecHitsInWindow[j].id()).iphi()<<endl;
226  if((((EBDetId)RecHitsInWindow[j].id()).ieta() == seed_id.ieta()-1 && seed_id.ieta()!=1 ) || ( seed_id.ieta()==1 && (((EBDetId)RecHitsInWindow[j].id()).ieta() == seed_id.ieta()-2))){
227  if(((EBDetId)RecHitsInWindow[j].id()).iphi() == seed_id.iphi()-1 ||((EBDetId)RecHitsInWindow[j].id()).iphi()-360 == seed_id.iphi()-1 ){
228  s4s9_[0]+=RecHitsInWindow[j].energy();
229  }else{
230  if(((EBDetId)RecHitsInWindow[j].id()).iphi() == seed_id.iphi()){
231  s4s9_[0]+=RecHitsInWindow[j].energy();
232  s4s9_[1]+=RecHitsInWindow[j].energy();
233  }else{
234  if(((EBDetId)RecHitsInWindow[j].id()).iphi() == seed_id.iphi()+1 ||((EBDetId)RecHitsInWindow[j].id()).iphi()-360 == seed_id.iphi()+1 ){
235  s4s9_[1]+=RecHitsInWindow[j].energy();
236  }
237  }
238  }
239  }else{
240  if(((EBDetId)RecHitsInWindow[j].id()).ieta() == seed_id.ieta()){
241  if(((EBDetId)RecHitsInWindow[j].id()).iphi() == seed_id.iphi()-1 ||((EBDetId)RecHitsInWindow[j].id()).iphi()-360 == seed_id.iphi()-1 ){
242  s4s9_[0]+=RecHitsInWindow[j].energy();
243  s4s9_[3]+=RecHitsInWindow[j].energy();
244  }else{
245  if(((EBDetId)RecHitsInWindow[j].id()).iphi() == seed_id.iphi()+1 ||((EBDetId)RecHitsInWindow[j].id()).iphi()-360 == seed_id.iphi()+1 ){
246  s4s9_[1]+=RecHitsInWindow[j].energy();
247  s4s9_[2]+=RecHitsInWindow[j].energy();
248  }
249  }
250  }else{
251  if((((EBDetId)RecHitsInWindow[j].id()).ieta() == seed_id.ieta()+1 && seed_id.ieta()!=-1 ) || ( seed_id.ieta()==-1 && (((EBDetId)RecHitsInWindow[j].id()).ieta() == seed_id.ieta()+2))){
252  if(((EBDetId)RecHitsInWindow[j].id()).iphi() == seed_id.iphi()-1 ||((EBDetId)RecHitsInWindow[j].id()).iphi()-360 == seed_id.iphi()-1 ){
253  s4s9_[3]+=RecHitsInWindow[j].energy();
254  }else{
255  if(((EBDetId)RecHitsInWindow[j].id()).iphi() == seed_id.iphi()){
256  s4s9_[2]+=RecHitsInWindow[j].energy();
257  s4s9_[3]+=RecHitsInWindow[j].energy();
258  }else{
259  if(((EBDetId)RecHitsInWindow[j].id()).iphi() == seed_id.iphi()+1 ||((EBDetId)RecHitsInWindow[j].id()).iphi()-360 == seed_id.iphi()+1 ){
260  s4s9_[2]+=RecHitsInWindow[j].energy();
261  }
262  }
263  }
264  }else{
265  cout<<" (EBDetId)RecHitsInWindow[j].id()).ieta() "<<((EBDetId)RecHitsInWindow[j].id()).ieta()<<" seed_id.ieta() "<<seed_id.ieta()<<endl;
266  cout<<" Problem with S4 calculation "<<endl;return;
267  }
268  }
269  }
270  }
271  s4s9Clus.push_back(*max_element( s4s9_,s4s9_+4)/simple_energy);
272  // cout<<" s4s9Clus[0] "<<s4s9_[0]/simple_energy<<" s4s9Clus[1] "<<s4s9_[1]/simple_energy<<" s4s9Clus[2] "<<s4s9_[2]/simple_energy<<" s4s9Clus[3] "<<s4s9_[3]/simple_energy<<endl;
273  // cout<<" Max "<<*max_element( s4s9_,s4s9_+4)/simple_energy<<endl;
274  nClus++;
275  if (nClus == MAXCLUS) return;
276  } // End loop over seed clusters
277 
278  // cout<< " Pi0 clusters: "<<nClus<<endl;
279 
280  // Selection, based on Simple clustering
281  //pi0 candidates
282  static const int MAXPI0S = 200;
283  int npi0_s=0;
284 
285  vector<EBDetId> scXtals;
286  scXtals.clear();
287 
288  if (nClus <= 1) return;
289  for(Int_t i=0 ; i<nClus ; i++){
290  for(Int_t j=i+1 ; j<nClus ; j++){
291  // cout<<" i "<<i<<" etClus[i] "<<etClus[i]<<" j "<<j<<" etClus[j] "<<etClus[j]<<endl;
292  if( etClus[i]>selePtGammaOne_ && etClus[j]>selePtGammaTwo_ && s4s9Clus[i]>seleS4S9GammaOne_ && s4s9Clus[j]>seleS4S9GammaTwo_){
293  float theta_0 = 2. * atan(exp(-etaClus[i]));
294  float theta_1 = 2. * atan(exp(-etaClus[j]));
295 
296  float p0x = eClus[i] * sin(theta_0) * cos(phiClus[i]);
297  float p1x = eClus[j] * sin(theta_1) * cos(phiClus[j]);
298  float p0y = eClus[i] * sin(theta_0) * sin(phiClus[i]);
299  float p1y = eClus[j] * sin(theta_1) * sin(phiClus[j]);
300  float p0z = eClus[i] * cos(theta_0);
301  float p1z = eClus[j] * cos(theta_1);
302 
303  float pt_pi0 = sqrt( (p0x+p1x)*(p0x+p1x) + (p0y+p1y)*(p0y+p1y));
304  // cout<<" pt_pi0 "<<pt_pi0<<endl;
305  if (pt_pi0 < selePtPi0_)continue;
306  float m_inv = sqrt ( (eClus[i] + eClus[j])*(eClus[i] + eClus[j]) - (p0x+p1x)*(p0x+p1x) - (p0y+p1y)*(p0y+p1y) - (p0z+p1z)*(p0z+p1z) );
307  if ( (m_inv<seleMinvMaxPi0_) && (m_inv>seleMinvMinPi0_) ){
308 
309  //New Loop on cluster to measure isolation:
310  vector<int> IsoClus;
311  IsoClus.clear();
312  float Iso = 0;
313  TVector3 pi0vect = TVector3((p0x+p1x), (p0y+p1y), (p0z+p1z));
314  for(Int_t k=0 ; k<nClus ; k++){
315  if(k==i || k==j)continue;
316  TVector3 Clusvect = TVector3(eClus[k] * sin(2. * atan(exp(-etaClus[k]))) * cos(phiClus[k]), eClus[k] * sin(2. * atan(exp(-etaClus[k]))) * sin(phiClus[k]) , eClus[k] * cos(2. * atan(exp(-etaClus[k]))));
317  float dretaclpi0 = fabs(etaClus[k] - pi0vect.Eta());
318  float drclpi0 = Clusvect.DeltaR(pi0vect);
319 
320  if((drclpi0<selePi0BeltDR_) && (dretaclpi0<selePi0BeltDeta_) ){
321 
322  Iso = Iso + etClus[k];
323  IsoClus.push_back(k);
324  }
325  }
326 
327 
328  if(Iso/pt_pi0<selePi0Iso_){
329 
330  hMinvPi0EB_->Fill(m_inv);
331  hPt1Pi0EB_->Fill(etClus[i]);
332  hPt2Pi0EB_->Fill(etClus[j]);
333  hPtPi0EB_->Fill(pt_pi0);
334  hIsoPi0EB_->Fill(Iso/pt_pi0);
335 
336 
337  npi0_s++;
338  }
339 
340  if(npi0_s == MAXPI0S) return;
341  }
342  }
343  }
344  }
345 }
T getParameter(std::string const &) const
const CaloSubdetectorGeometry * getSubdetectorGeometry(const DetId &id) const
access the subdetector geometry for the given subdetector directly
Definition: CaloGeometry.cc:45
T getUntrackedParameter(std::string const &, T const &) const
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:460
PiZeroAnalyzer(const edm::ParameterSet &)
void makePizero(const edm::EventSetup &es, const edm::Handle< EcalRecHitCollection > eb, const edm::Handle< EcalRecHitCollection > ee)
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
std::vector< EcalRecHit >::const_iterator const_iterator
int iphi() const
get the crystal iphi
Definition: EBDetId.h:53
T sqrt(T t)
Definition: SSEVec.h:18
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
MonitorElement * book1D(Args &&...args)
Definition: DQMStore.h:115
int ieta() const
get the crystal ieta
Definition: EBDetId.h:51
void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override
bool isValid() const
Definition: HandleBase.h:74
virtual void analyze(const edm::Event &, const edm::EventSetup &) override
int k[5][pyjets_maxn]
const_iterator end() const
void setCurrentFolder(const std::string &fullpath)
Definition: DQMStore.cc:277
virtual std::vector< DetId > getWindow(const DetId &id, const int &northSouthSize, const int &eastWestSize) const
T const * product() const
Definition: Handle.h:81
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
const T & get() const
Definition: EventSetup.h:56
const CaloSubdetectorTopology * getSubdetectorTopology(const DetId &id) const
access the subdetector Topology for the given subdetector directly
Definition: CaloTopology.cc:26
edm::EventID id() const
Definition: EventBase.h:60
HLT enums.
math::XYZPoint Calculate_Location(const HitsAndFractions &iDetIds, const edm::SortedCollection< HitType > *iRecHits, const CaloSubdetectorGeometry *iSubGeom, const CaloSubdetectorGeometry *iESGeom=0)
Definition: PositionCalc.h:68
virtual ~PiZeroAnalyzer()
void setAxisTitle(const std::string &title, int axis=1)
set x-, y- or z-axis title (axis=1, 2, 3 respectively)
const_iterator begin() const
Definition: Run.h:42