ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitPhysics/Mods/src/PhotonPairSelector.cc
Revision: 1.5
Committed: Sun Jul 24 20:08:26 2011 UTC (13 years, 9 months ago) by bendavid
Content type: text/plain
Branch: MAIN
Changes since 1.4: +81 -34 lines
Log Message:
go back to flat trees, but now dynamically generated

File Contents

# User Rev Content
1 fabstoec 1.1 #include "MitPhysics/Mods/interface/PhotonPairSelector.h"
2     #include "MitAna/DataTree/interface/PhotonCol.h"
3     #include "MitAna/DataTree/interface/PFCandidateCol.h"
4     #include "MitPhysics/Init/interface/ModNames.h"
5     #include "MitPhysics/Utils/interface/IsolationTools.h"
6     #include "MitPhysics/Utils/interface/PhotonTools.h"
7     #include "MitPhysics/Utils/interface/VertexTools.h"
8 bendavid 1.5 #include "TDataMember.h"
9 fabstoec 1.1 #include <TNtuple.h>
10     #include <TRandom3.h>
11    
12     using namespace mithep;
13    
14     ClassImp(mithep::PhotonPairSelector)
15 bendavid 1.4 ClassImp(mithep::PhotonPairSelectorPhoton)
16     ClassImp(mithep::PhotonPairSelectorDiphotonEvent)
17    
18 fabstoec 1.1
19     //--------------------------------------------------------------------------------------------------
20     PhotonPairSelector::PhotonPairSelector(const char *name, const char *title) :
21     // Base Module...
22     BaseMod (name,title),
23    
24     // define all the Branches to load
25     fPhotonBranchName (Names::gkPhotonBrn),
26     fElectronName (Names::gkElectronBrn),
27     fConversionName (Names::gkMvfConversionBrn),
28     fTrackBranchName (Names::gkTrackBrn),
29     fPileUpDenName (Names::gkPileupEnergyDensityBrn),
30     fPVName (Names::gkPVBeamSpotBrn),
31     fBeamspotName (Names::gkBeamSpotBrn),
32     fPFCandName (Names::gkPFCandidatesBrn),
33     // MC specific stuff...
34     fMCParticleName (Names::gkMCPartBrn),
35     fPileUpName (Names::gkPileupInfoBrn),
36    
37     fGoodPhotonsName (ModNames::gkGoodPhotonsName),
38    
39     // ----------------------------------------
40     // Selection Types
41     fPhotonSelType ("NoSelection"),
42     fVertexSelType ("StdSelection"),
43     fPhSelType (kNoPhSelection),
44     fVtxSelType (kStdVtxSelection),
45    
46     // ----------------------------------------
47     fPhotonPtMin (20.0),
48     fPhotonEtaMax (2.5),
49    
50     fLeadingPtMin (40.0),
51     fTrailingPtMin (30.0),
52    
53     fIsData (false),
54     fPhotonsFromBranch (true),
55     fPVFromBranch (true),
56    
57     // ----------------------------------------
58     // collections....
59     fPhotons (0),
60     fElectrons (0),
61     fConversions (0),
62     fTracks (0),
63     fPileUpDen (0),
64     fPV (0),
65     fBeamspot (0),
66     fPFCands (0),
67     fMCParticles (0),
68     fPileUp (0),
69    
70     // ---------------------------------------
71     fDataEnCorr_EB_hR9 (0.),
72     fDataEnCorr_EB_lR9 (0.),
73     fDataEnCorr_EE_hR9 (0.),
74     fDataEnCorr_EE_lR9 (0.),
75    
76     fRunStart (0),
77     fRunEnd (0),
78    
79     fMCSmear_EB_hR9 (0.),
80     fMCSmear_EB_lR9 (0.),
81     fMCSmear_EE_hR9 (0.),
82     fMCSmear_EE_lR9 (0.),
83    
84     // ---------------------------------------
85     rng (new TRandom3()),
86    
87     // ---------------------------------------
88     fDoDataEneCorr (true),
89     fDoMCSmear (true),
90 fabstoec 1.2 fDoVtxSelection (true),
91     fApplyEleVeto (true),
92    
93     fTupleName ("hCiCtuple")
94 fabstoec 1.1
95     {
96     // Constructor.
97     }
98    
99     PhotonPairSelector::~PhotonPairSelector(){
100     if(rng) delete rng;
101     }
102    
103     //--------------------------------------------------------------------------------------------------
104     void PhotonPairSelector::Process()
105     {
106     // ------------------------------------------------------------
107     // Process entries of the tree.
108     LoadEventObject(fPhotonBranchName, fPhotons);
109     LoadEventObject(fElectronName, fElectrons);
110     LoadEventObject(fConversionName, fConversions);
111     LoadEventObject(fTrackBranchName, fTracks);
112     LoadEventObject(fPileUpDenName, fPileUpDen);
113     LoadEventObject(fPVName, fPV);
114     LoadEventObject(fBeamspotName, fBeamspot);
115     LoadEventObject(fPFCandName, fPFCands);
116    
117     if( !fIsData ) {
118     LoadBranch(fMCParticleName);
119     LoadBranch(fPileUpName);
120     }
121    
122     // -----------------------------------------------------------
123     // OUtput Photon Collection. It will ALWAYS conatrin either 0 or 2 Photons
124     PhotonOArr *GoodPhotons = new PhotonOArr;
125     GoodPhotons->SetName(fGoodPhotonsName);
126     GoodPhotons->SetOwner(kTRUE);
127    
128    
129     // ------------------------------------------------------------
130     // load event based information
131 bendavid 1.4 Int_t _numPU = -1.; // some sensible default values....
132     Int_t _numPUminus = -1.; // some sensible default values....
133     Int_t _numPUplus = -1.; // some sensible default values....
134    
135 fabstoec 1.1 Float_t _tRho = -99.;
136 fabstoec 1.2 if( fPileUpDen->GetEntries() > 0 )
137     _tRho = (Double_t) fPileUpDen->At(0)->RhoRandomLowEta();
138    
139     if( !fIsData ) {
140     for (UInt_t i=0; i<fPileUp->GetEntries(); ++i) {
141     const PileupInfo *puinfo = fPileUp->At(i);
142 bendavid 1.4 if (puinfo->GetBunchCrossing()==0) _numPU = puinfo->GetPU_NumInteractions();
143     else if (puinfo->GetBunchCrossing() == -1) _numPUminus = puinfo->GetPU_NumInteractions();
144     else if (puinfo->GetBunchCrossing() == 1) _numPUplus = puinfo->GetPU_NumInteractions();
145 fabstoec 1.2 }
146     }
147    
148 fabstoec 1.1 const BaseVertex *bsp = dynamic_cast<const BaseVertex*>(fBeamspot->At(0));
149    
150     // ------------------------------------------------------------
151     // Get Event header for Run info etc.
152     const EventHeader* evtHead = this->GetEventHeader();
153     unsigned int evtNum = evtHead->EvtNum();
154     Float_t _evtNum1 = (Float_t) ( (int) (evtNum/10000.) );
155     Float_t _evtNum2 = (Float_t) ( (int) (evtNum % 10000) );
156     UInt_t runNumber = evtHead->RunNum();
157     Float_t _runNum = (Float_t) runNumber;
158     Float_t _lumiSec = (Float_t) evtHead->LumiSec();
159    
160     // ------------------------------------------------------------
161     // here we'll store the preselected Photons (and which CiCCategory they are...)
162     PhotonOArr* preselPh = new PhotonOArr;
163     std::vector<PhotonTools::CiCBaseLineCats> preselCat;
164     preselCat.resize(0);
165    
166     // 1. we do the pre-selection; but keep the non-passing photons in a secont container...
167     for (UInt_t i=0; i<fPhotons->GetEntries(); ++i) {
168     const Photon *ph = fPhotons->At(i);
169    
170     if(ph->SCluster()->AbsEta()>= fPhotonEtaMax || (ph->SCluster()->AbsEta()>=1.4442 && ph->SCluster()->AbsEta()<=1.566)) continue;
171     if(ph->Et() < fPhotonPtMin) continue;
172     if(ph->HadOverEm() > 0.15) continue;
173     if(ph->IsEB()) {
174     if(ph->CoviEtaiEta() > 0.013) continue;
175     } else {
176     if(ph->CoviEtaiEta() > 0.03) continue;
177     }
178     preselPh->Add(ph);
179 fabstoec 1.2 }
180    
181     // Sorry... need the second loop here in order to sort & assign the right Categories..
182     preselPh->Sort();
183     for(unsigned int iPh = 0; iPh <preselPh->GetEntries(); ++iPh) {
184     const Photon* ph = preselPh->At(iPh);
185 fabstoec 1.1 preselCat.push_back(PhotonTools::CiCBaseLineCat(ph));
186     }
187    
188     // ------------------------------------------------------------
189     // compute how many pairs there are ...
190     unsigned int numPairs = 0;
191     if( preselPh->GetEntries() > 0) numPairs = (preselPh->GetEntries()-1)*preselPh->GetEntries()/2;
192     // ... and create all possible pairs of pre-selected photons
193     std::vector<unsigned int> idx1st;
194     std::vector<unsigned int> idx2nd;
195     std::vector<PhotonTools::CiCBaseLineCats> cat1st;
196     std::vector<PhotonTools::CiCBaseLineCats> cat2nd;
197     // ... this will be used to store whether a givne pair passes the cuts
198     std::vector<bool> pairPasses;
199    
200     if(numPairs > 0) {
201     for(unsigned int i1st = 0; i1st <preselPh->GetEntries() - 1; ++i1st) {
202     for(unsigned int i2nd = i1st + 1; i2nd <preselPh->GetEntries(); ++i2nd) {
203     idx1st.push_back(i1st);
204     idx2nd.push_back(i2nd);
205     pairPasses.push_back(true);
206     }
207     }
208     }
209    
210     // ------------------------------------------------------------
211     // array to store the index of 'chosen Vtx' for each pair
212     const Vertex** theVtx = new const Vertex*[numPairs]; // holds the 'chosen' Vtx for each Pair
213     Photon** fixPh1st = new Photon*[numPairs]; // holds the 1st Photon for each Pair
214     Photon** fixPh2nd = new Photon*[numPairs]; // holds the 2nd photon for each Pair
215    
216    
217     // store pair-indices for pairs passing the selection
218     std::vector<unsigned int> passPairs;
219     passPairs.resize(0);
220    
221     // ------------------------------------------------------------
222     // Loop over all Pairs and to the 'incredible machine' running....
223     for(unsigned int iPair = 0; iPair < numPairs; ++iPair) {
224    
225     // first we need a hard copy of the incoming photons
226     fixPh1st[iPair] = new Photon(*preselPh->At(idx1st[iPair]));
227     fixPh2nd[iPair] = new Photon(*preselPh->At(idx2nd[iPair]));
228     // we also store the category, so we don't have to ask all the time...
229     cat1st.push_back(preselCat[idx1st[iPair]]);
230     cat2nd.push_back(preselCat[idx2nd[iPair]]);
231    
232     // now we dicide if we either scale (Data) or Smear (MC) the Photons
233     if (fIsData) {
234     if(fDoDataEneCorr) {
235     // statring with scale = 1.
236     double scaleFac1 = 1.;
237     double scaleFac2 = 1.;
238     // checking the run Rangees ...
239     Int_t runRange = FindRunRangeIdx(runNumber);
240     if(runRange > -1) {
241     scaleFac1 += GetDataEnCorr(runRange, cat1st[iPair]);
242     scaleFac2 += GetDataEnCorr(runRange, cat2nd[iPair]);
243     }
244     PhotonTools::ScalePhoton(fixPh1st[iPair], scaleFac1);
245     PhotonTools::ScalePhoton(fixPh2nd[iPair], scaleFac2);
246     }
247     } else {
248     if(fDoMCSmear) {
249     // get the seed to do deterministic smearing...
250     UInt_t seedBase = (UInt_t) evtNum + (UInt_t) _runNum + (UInt_t) _lumiSec;
251     UInt_t seed1 = seedBase + (UInt_t) fixPh1st[iPair]->E() + (UInt_t) (TMath::Abs(10.*fixPh1st[iPair]->SCluster()->Eta()));
252     UInt_t seed2 = seedBase + (UInt_t) fixPh2nd[iPair]->E() + (UInt_t) (TMath::Abs(10.*fixPh2nd[iPair]->SCluster()->Eta()));
253     // get the smearing for MC photons..
254 fabstoec 1.3
255 fabstoec 1.1 double width1 = GetMCSmearFac(cat1st[iPair]);
256     double width2 = GetMCSmearFac(cat2nd[iPair]);
257 fabstoec 1.3
258 fabstoec 1.1 PhotonTools::SmearPhoton(fixPh1st[iPair], rng, width1, seed1);
259     PhotonTools::SmearPhoton(fixPh2nd[iPair], rng, width2, seed2);
260 fabstoec 1.3
261 fabstoec 1.1 }
262     }
263    
264     // store the vertex for this pair
265     switch( fVtxSelType ){
266     case kStdVtxSelection:
267     theVtx[iPair] = fPV->At(0);
268     break;
269     case kCiCVtxSelection:
270     theVtx[iPair] = VertexTools::findVtxBasicRanking(fixPh1st[iPair],fixPh2nd[iPair], bsp, fPV, fConversions);
271     break;
272     case kMITVtxSelection:
273     // need PFCandidate Collection
274     theVtx[iPair] = VertexTools::BestVtx(fPFCands, fPV, bsp, mithep::FourVector((fixPh1st[iPair]->Mom()+fixPh2nd[iPair]->Mom())));
275     break;
276     default:
277     theVtx[iPair] = fPV->At(0);
278 fabstoec 1.2
279 fabstoec 1.1 }
280 fabstoec 1.2
281 fabstoec 1.1 // fix the kinematics for both events
282     FourVectorM newMom1st = fixPh1st[iPair]->MomVtx(theVtx[iPair]->Position());
283     FourVectorM newMom2nd = fixPh2nd[iPair]->MomVtx(theVtx[iPair]->Position());
284     fixPh1st[iPair]->SetMom(newMom1st.X(), newMom1st.Y(), newMom1st.Z(), newMom1st.E());
285     fixPh2nd[iPair]->SetMom(newMom2nd.X(), newMom2nd.Y(), newMom2nd.Z(), newMom2nd.E());
286    
287     // check if both photons pass the CiC selection
288     // FIX-ME: Add other possibilities....
289     bool pass1 = false;
290     bool pass2 = false;
291     switch( fVtxSelType ){
292     case kNoPhSelection:
293     pass1 = ( fixPh1st[iPair]->Pt() > fLeadingPtMin );
294     pass2 = ( fixPh2nd[iPair]->Pt() > fTrailingPtMin );
295     break;
296     case kCiCPhSelection:
297 fabstoec 1.3
298    
299 fabstoec 1.2 pass1 = PhotonTools::PassCiCSelection(fixPh1st[iPair], theVtx[iPair], fTracks, fElectrons, fPV, _tRho, fLeadingPtMin, fApplyEleVeto);
300     if(pass1) pass2 = PhotonTools::PassCiCSelection(fixPh2nd[iPair], theVtx[iPair], fTracks, fElectrons, fPV, _tRho, fTrailingPtMin, fApplyEleVeto);
301 fabstoec 1.3
302 fabstoec 1.1 break;
303     case kMITPhSelection:
304 fabstoec 1.3 // FIX-ME: This is a place-holder.. MIT guys: Please work hard... ;)
305 fabstoec 1.1 pass1 = ( fixPh1st[iPair]->Pt() > fLeadingPtMin );
306     pass2 = ( fixPh2nd[iPair]->Pt() > fTrailingPtMin );
307     break;
308     default:
309     pass1 = true;
310     pass2 = true;
311     }
312     // finally, if both Photons pass the selections, add the pair to the 'passing Pairs)
313     if( pass1 && pass2 ) passPairs.push_back(iPair);
314     }
315    
316    
317     // ---------------------------------------------------------------
318     // ... we're almost done, stau focused...
319     // loop over all passing pairs and find the one with the highest sum Et
320     const Vertex* _theVtx = NULL;
321     Photon* phHard = NULL;
322     Photon* phSoft = NULL;
323    
324     PhotonTools::CiCBaseLineCats catPh1 = PhotonTools::kCiCNoCat;
325     PhotonTools::CiCBaseLineCats catPh2 = PhotonTools::kCiCNoCat;
326    
327     double maxSumEt = 0.;
328     for(unsigned int iPair=0; iPair<passPairs.size(); ++iPair){
329     double sumEt = fixPh1st[passPairs[iPair]]->Et();
330     sumEt += fixPh2nd[passPairs[iPair]]->Et();
331     if( sumEt > maxSumEt ) {
332     maxSumEt = sumEt;
333     phHard = fixPh1st[passPairs[iPair]];
334     phSoft = fixPh2nd[passPairs[iPair]];
335     catPh1 = cat1st[passPairs[iPair]];
336     catPh2 = cat2nd[passPairs[iPair]];
337     _theVtx = theVtx[iPair];
338     }
339     }
340    
341     // ---------------------------------------------------------------
342     // we have the Photons (*PARTY*)... compute some useful qunatities
343    
344     Float_t _theVtxZ = -999.;
345    
346     if(phHard && phSoft) {
347     GoodPhotons->AddOwned(phHard);
348     GoodPhotons->AddOwned(phSoft);
349     }
350    
351     if(_theVtx) _theVtxZ=_theVtx->Position().Z();
352    
353     // sort according to pt
354     GoodPhotons->Sort();
355    
356     // add to event for other modules to use
357     AddObjThisEvt(GoodPhotons);
358    
359     // delete auxiliary photon collection...
360     delete preselPh;
361     delete[] theVtx;
362    
363     // Fill the useful information (mass and di-photon pt)
364     bool doFill = ( phHard && phSoft );
365 bendavid 1.4 if (!doFill) return;
366    
367 fabstoec 1.1 Float_t _mass = ( doFill ? (phHard->Mom()+phSoft->Mom()).M() : -100.);
368     Float_t _ptgg = ( doFill ? (phHard->Mom()+phSoft->Mom()).Pt() : -100.);
369 bendavid 1.4
370 fabstoec 1.1 // in case of a MC event, try to find Higgs and Higgs decay Z poisition
371     Float_t _pth = -100.;
372     Float_t _decayZ = -100.;
373     if( !fIsData ) FindHiggsPtAndZ(_pth, _decayZ);
374    
375     Float_t evtCat = -1.;
376     if( doFill ) {
377     evtCat = GetEventCat(catPh1, catPh2);
378     if(_ptgg < 40.) evtCat += 4.;
379     }
380 bendavid 1.4
381     const MCParticle *phgen1 = MatchMC(phHard);
382     const MCParticle *phgen2 = MatchMC(phSoft);
383 fabstoec 1.1
384 bendavid 1.4 Float_t _gencostheta = -99.;
385     if (phgen1 && phgen2) {
386     _gencostheta = ThreeVector(phgen1->Mom()).Unit().Dot(ThreeVector(phgen2->Mom()).Unit());
387     }
388    
389     if(_mass > 0.) {
390     fDiphotonEvent->rho = _tRho;
391     fDiphotonEvent->genHiggspt = _pth;
392     fDiphotonEvent->genHiggsZ = _decayZ;
393     fDiphotonEvent->gencostheta = _gencostheta;
394     fDiphotonEvent->vtxZ = _theVtxZ;
395     fDiphotonEvent->numPU = _numPU;
396     fDiphotonEvent->numPUminus = _numPUminus;
397     fDiphotonEvent->numPUplus = _numPUplus;
398     fDiphotonEvent->mass = _mass;
399     fDiphotonEvent->ptgg = _ptgg;
400     fDiphotonEvent->costheta = ThreeVector(phHard->Mom()).Unit().Dot(ThreeVector(phSoft->Mom()).Unit());
401     fDiphotonEvent->evt = GetEventHeader()->EvtNum();
402     fDiphotonEvent->run = GetEventHeader()->RunNum();
403     fDiphotonEvent->lumi = GetEventHeader()->LumiSec();
404     fDiphotonEvent->evtcat = evtCat;
405 bendavid 1.5
406     fDiphotonEvent->photons[0].SetVars(phHard,phgen1);
407     fDiphotonEvent->photons[1].SetVars(phSoft,phgen2);
408 bendavid 1.4
409    
410 bendavid 1.5 hCiCTuple->Fill();
411 bendavid 1.4
412 bendavid 1.5 fSinglePhoton->SetVars(phHard,phgen1);
413     hCiCTupleSingle->Fill();
414     fSinglePhoton->SetVars(phSoft,phgen2);
415     hCiCTupleSingle->Fill();
416 bendavid 1.4
417 bendavid 1.5 }
418 bendavid 1.4
419 fabstoec 1.1 return;
420    
421     }
422    
423     //--------------------------------------------------------------------------------------------------
424     void PhotonPairSelector::SlaveBegin()
425     {
426     // Run startup code on the computer (slave) doing the actual analysis. Here,
427     // we just request the photon collection branch.
428    
429     ReqEventObject(fPhotonBranchName, fPhotons, fPhotonsFromBranch);
430     ReqEventObject(fTrackBranchName, fTracks, true);
431     ReqEventObject(fElectronName, fElectrons, true);
432     ReqEventObject(fPileUpDenName, fPileUpDen, true);
433     ReqEventObject(fPVName, fPV, fPVFromBranch);
434     ReqEventObject(fConversionName, fConversions,true);
435     ReqEventObject(fBeamspotName, fBeamspot, true);
436     ReqEventObject(fPFCandName, fPFCands, true);
437    
438     if (!fIsData) {
439     ReqBranch(fPileUpName, fPileUp);
440     ReqBranch(fMCParticleName, fMCParticles);
441     }
442    
443     if (fPhotonSelType.CompareTo("CiCSelection") == 0)
444     fPhSelType = kCiCPhSelection;
445     else if (fPhotonSelType.CompareTo("MITSelection") == 0)
446     fPhSelType = kMITPhSelection;
447     else
448     fPhSelType = kNoPhSelection;
449    
450     if (fVertexSelType.CompareTo("CiCSelection") == 0)
451     fVtxSelType = kCiCVtxSelection;
452     else if (fVertexSelType.CompareTo("MITSelection") == 0)
453     fVtxSelType = kMITVtxSelection;
454     else
455     fVtxSelType = kStdVtxSelection;
456    
457 bendavid 1.5 //PhotonPairSelectorDiphotonEvent::Class()->IgnoreTObjectStreamer();
458     //PhotonPairSelectorPhoton::Class()->IgnoreTObjectStreamer();
459 bendavid 1.4
460     fDiphotonEvent = new PhotonPairSelectorDiphotonEvent;
461 bendavid 1.5 fSinglePhoton = new PhotonPairSelectorPhoton;
462    
463    
464 bendavid 1.4 hCiCTuple = new TTree(fTupleName.Data(),fTupleName.Data());
465 bendavid 1.5 TString singlename = fTupleName + TString("Single");
466     hCiCTupleSingle = new TTree(singlename,singlename);
467 fabstoec 1.1
468 bendavid 1.5 //make flattish tree from classes so we don't have to rely on dictionaries for reading later
469     TClass *eclass = TClass::GetClass("mithep::PhotonPairSelectorDiphotonEvent");
470     TClass *pclass = TClass::GetClass("mithep::PhotonPairSelectorPhoton");
471     TList *elist = eclass->GetListOfDataMembers();
472     TList *plist = pclass->GetListOfDataMembers();
473    
474     for (int i=0; i<elist->GetEntries(); ++i) {
475     const TDataMember *tdm = static_cast<const TDataMember*>(elist->At(i));
476     if (!(tdm->IsBasic() && tdm->IsPersistent())) continue;
477     TString typestring;
478     if (TString(tdm->GetTypeName())=="Char_t") typestring = "B";
479     else if (TString(tdm->GetTypeName())=="UChar_t") typestring = "b";
480     else if (TString(tdm->GetTypeName())=="Short_t") typestring = "S";
481     else if (TString(tdm->GetTypeName())=="UShort_t") typestring = "s";
482     else if (TString(tdm->GetTypeName())=="Int_t") typestring = "I";
483     else if (TString(tdm->GetTypeName())=="UInt_t") typestring = "i";
484     else if (TString(tdm->GetTypeName())=="Float_t") typestring = "F";
485     else if (TString(tdm->GetTypeName())=="Double_t") typestring = "D";
486     else if (TString(tdm->GetTypeName())=="Long64_t") typestring = "L";
487     else if (TString(tdm->GetTypeName())=="ULong64_t") typestring = "l";
488     else if (TString(tdm->GetTypeName())=="Bool_t") typestring = "O";
489     else continue;
490     //printf("%s %s: %i\n",tdm->GetTypeName(),tdm->GetName(),int(tdm->GetOffset()));
491     Char_t *addr = (Char_t*)fDiphotonEvent;
492     assert(sizeof(Char_t)==1);
493     hCiCTuple->Branch(tdm->GetName(),addr + tdm->GetOffset(),TString::Format("%s/%s",tdm->GetName(),typestring.Data()));
494     hCiCTupleSingle->Branch(tdm->GetName(),addr + tdm->GetOffset(),TString::Format("%s/%s",tdm->GetName(),typestring.Data()));
495     }
496    
497     for (int iph=0; iph<2; ++iph) {
498     for (int i=0; i<plist->GetEntries(); ++i) {
499     const TDataMember *tdm = static_cast<const TDataMember*>(plist->At(i));
500     if (!(tdm->IsBasic() && tdm->IsPersistent())) continue;
501     TString typestring;
502     if (TString(tdm->GetTypeName())=="Char_t") typestring = "B";
503     else if (TString(tdm->GetTypeName())=="UChar_t") typestring = "b";
504     else if (TString(tdm->GetTypeName())=="Short_t") typestring = "S";
505     else if (TString(tdm->GetTypeName())=="UShort_t") typestring = "s";
506     else if (TString(tdm->GetTypeName())=="Int_t") typestring = "I";
507     else if (TString(tdm->GetTypeName())=="UInt_t") typestring = "i";
508     else if (TString(tdm->GetTypeName())=="Float_t") typestring = "F";
509     else if (TString(tdm->GetTypeName())=="Double_t") typestring = "D";
510     else if (TString(tdm->GetTypeName())=="Long64_t") typestring = "L";
511     else if (TString(tdm->GetTypeName())=="ULong64_t") typestring = "l";
512     else if (TString(tdm->GetTypeName())=="Bool_t") typestring = "O";
513     else continue;
514     //printf("%s\n",tdm->GetTypeName());
515     TString varname = TString::Format("ph%d.%s",iph+1,tdm->GetName());
516    
517     Char_t *addr = (Char_t*)&fDiphotonEvent->photons[iph];
518     assert(sizeof(Char_t)==1);
519     hCiCTuple->Branch(varname,addr+tdm->GetOffset(),TString::Format("%s/%s",varname.Data(),typestring.Data()));
520    
521     if (iph==0) {
522     TString singlename = TString::Format("ph.%s",tdm->GetName());
523     Char_t *addrsingle = (Char_t*)fSinglePhoton;
524     hCiCTupleSingle->Branch(singlename,addrsingle+tdm->GetOffset(),TString::Format("%s/%s",singlename.Data(),typestring.Data()));
525     }
526     }
527     }
528    
529    
530 fabstoec 1.1 AddOutput(hCiCTuple);
531 bendavid 1.5 AddOutput(hCiCTupleSingle);
532    
533 fabstoec 1.1
534     }
535    
536     // ----------------------------------------------------------------------------------------
537     // some helpfer functions....
538     void PhotonPairSelector::FindHiggsPtAndZ(Float_t& pt, Float_t& decayZ) {
539    
540     pt = -999.;
541     decayZ = -999.;
542    
543     // loop over all GEN particles and look for status 1 photons
544     for(UInt_t i=0; i<fMCParticles->GetEntries(); ++i) {
545     const MCParticle* p = fMCParticles->At(i);
546     if( !(p->Is(MCParticle::kH)) ) continue;
547     pt=p->Pt();
548     decayZ = p->DecayVertex().Z();
549     break;
550     }
551    
552     return;
553     }
554    
555     // this routine looks for the idx of the run-range
556     Int_t PhotonPairSelector::FindRunRangeIdx(UInt_t run) {
557     Int_t runRange=-1;
558     for(UInt_t iRun = 0; iRun<fRunStart.size(); ++iRun) {
559     if( run >= fRunStart[iRun] && run <= fRunEnd[iRun]) {
560     runRange = (Int_t) iRun;
561     return runRange;
562     }
563     }
564     return runRange;
565     }
566    
567    
568     Double_t PhotonPairSelector::GetDataEnCorr(Int_t runRange, PhotonTools::CiCBaseLineCats cat) {
569     switch( cat ) {
570     case PhotonTools::kCiCCat1:
571     return fDataEnCorr_EB_hR9[runRange];
572     case PhotonTools::kCiCCat2:
573     return fDataEnCorr_EB_lR9[runRange];
574     case PhotonTools::kCiCCat3:
575     return fDataEnCorr_EE_hR9[runRange];
576     case PhotonTools::kCiCCat4:
577     return fDataEnCorr_EE_lR9[runRange];
578     default:
579     return 1.;
580     }
581     }
582    
583    
584     Double_t PhotonPairSelector::GetMCSmearFac(PhotonTools::CiCBaseLineCats cat) {
585     switch( cat ) {
586     case PhotonTools::kCiCCat1:
587     return fMCSmear_EB_hR9;
588     case PhotonTools::kCiCCat2:
589     return fMCSmear_EB_lR9;
590     case PhotonTools::kCiCCat3:
591     return fMCSmear_EE_hR9;
592     case PhotonTools::kCiCCat4:
593     return fMCSmear_EE_lR9;
594     default:
595     return 1.;
596     }
597     }
598    
599     Float_t PhotonPairSelector::GetEventCat(PhotonTools::CiCBaseLineCats cat1, PhotonTools::CiCBaseLineCats cat2) {
600    
601     bool ph1IsEB = (cat1 == PhotonTools::kCiCCat1 || cat1 == PhotonTools::kCiCCat2);
602     bool ph2IsEB = (cat2 == PhotonTools::kCiCCat1 || cat2 == PhotonTools::kCiCCat2);
603    
604     bool ph1IsHR9 = (cat1 == PhotonTools::kCiCCat1 || cat1 == PhotonTools::kCiCCat3);
605     bool ph2IsHR9 = (cat2 == PhotonTools::kCiCCat1 || cat2 == PhotonTools::kCiCCat3);
606    
607     if( ph1IsEB && ph2IsEB )
608     return ( ph1IsHR9 && ph2IsHR9 ? 0. : 1.);
609    
610     return ( ph1IsHR9 && ph2IsHR9 ? 2. : 3.);
611     }
612 bendavid 1.4
613     const MCParticle *PhotonPairSelector::MatchMC(const Photon *ph) const
614     {
615    
616     for (UInt_t i=0; i<fMCParticles->GetEntries(); ++i) {
617     const MCParticle *p = fMCParticles->At(i);
618     if ( p->AbsPdgId()==22 && p->IsGenerated() && MathUtils::DeltaR(*ph,*p) < 0.3 && p->Mother() && (p->Mother()->AbsPdgId()==25 || p->Mother()->AbsPdgId()<=21) ) {
619     return p;
620     }
621     }
622     return 0;
623    
624     }
625    
626     void PhotonPairSelectorPhoton::SetVars(const Photon *p, const MCParticle *m) {
627     e = p->E();
628     pt = p->Pt();
629     eta = p->Eta();
630     phi = p->Phi();
631     r9 = p->R9();
632     e5x5 = p->E55();
633     const SuperCluster *s = p->SCluster();
634     sce = s->Energy();
635     scrawe = s->RawEnergy();
636     scpse = s->PreshowerEnergy();
637     sceta = s->Eta();
638     scphi = s->Phi();
639     isbarrel = (s->AbsEta()<1.5);
640     isr9reco = (isbarrel && r9>0.94) || (!isbarrel && r9>0.95);
641     isr9cat = (r9>0.94);
642    
643     if (isbarrel) {
644     if (isr9cat) phcat = 1;
645     else phcat = 2;
646     }
647     else {
648     if (isr9cat) phcat = 3;
649     else phcat = 4;
650     }
651    
652     if (m) {
653     ispromptgen = kTRUE;
654     gene = m->E();
655     genpt = m->Pt();
656     geneta = m->Eta();
657     genphi = m->Phi();
658     }
659     else {
660     ispromptgen = kFALSE;
661     gene = -99.;
662     genpt = -99.;
663     geneta = -99.;
664     genphi = -99.;
665     }
666    
667     }