ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/DTDPGAnalysis/src/DTEffOfflineAnalyzer.cc
Revision: 1.5
Committed: Thu Jul 4 17:16:42 2013 UTC (11 years, 10 months ago) by marycruz
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.4: +1 -0 lines
Log Message:
Update last version of PromptOffline

File Contents

# User Rev Content
1 giorgia 1.1 /******* \class DTEffOfflineAnalyzer *******
2     *
3     * Description:
4     *
5     * detailed description
6     *
7     * \author : Stefano Lacaprara - INFN LNL <stefano.lacaprara@pd.infn.it>
8     * $date : 20/11/2006 16:50:57 CET $
9     *
10     * Modification:
11     * Mary-Cruz Fouz
12 battilan 1.2 * March 2008: Histo Modifications To allow run over the root files
13     * Carlo Battilana
14     * October 2008: switched to DQMStore
15 giorgia 1.1 *
16     ************************************************************************/
17    
18     /* This Class Header */
19     #include "UserCode/DTDPGAnalysis/src/DTEffOfflineAnalyzer.h"
20    
21     /* Collaborating Class Header */
22     #include "FWCore/Framework/interface/MakerMacros.h"
23     #include "FWCore/Framework/interface/Frameworkfwd.h"
24     #include "FWCore/Framework/interface/Event.h"
25     #include "FWCore/ParameterSet/interface/ParameterSet.h"
26     #include "FWCore/Framework/interface/ESHandle.h"
27     #include "FWCore/Utilities/interface/Exception.h"
28 battilan 1.2 #include "DQMServices/Core/interface/DQMStore.h"
29     #include "DQMServices/Core/interface/MonitorElement.h"
30     #include "FWCore/ServiceRegistry/interface/Service.h"
31 giorgia 1.1
32     using namespace edm;
33    
34     #include "TFile.h"
35     #include "TH1F.h"
36     #include "TH2F.h"
37    
38     #include "DataFormats/LTCDigi/interface/LTCDigi.h"
39    
40     #include "Geometry/DTGeometry/interface/DTGeometry.h"
41     #include "Geometry/Records/interface/MuonGeometryRecord.h"
42     #include "DataFormats/DTRecHit/interface/DTRecHitCollection.h"
43     #include "DataFormats/DTRecHit/interface/DTRangeMapAccessor.h"
44    
45     #include "DataFormats/DTRecHit/interface/DTRecSegment2DCollection.h"
46     #include "DataFormats/DTRecHit/interface/DTRecSegment4DCollection.h"
47    
48     /* C++ Headers */
49     #include <iostream>
50     #include <cmath>
51     using namespace std;
52    
53     /* ====================================================================== */
54    
55     /* Constructor */
56     DTEffOfflineAnalyzer::DTEffOfflineAnalyzer(const ParameterSet& pset) {
57    
58     // Get the debug parameter for verbose output
59     debug = pset.getUntrackedParameter<bool>("debug");
60     theRootFileName = pset.getUntrackedParameter<string>("rootFileName");
61    
62     // the name of the digis collection
63     theDTLocalTriggerLabel = pset.getParameter<string>("DTLocalTriggerLabel");
64    
65     // the name of the 1D rec hits collection
66     theRecHits1DLabel = pset.getParameter<string>("recHits1DLabel");
67    
68     // the name of the 2D rec hits collection
69     theRecHits2DLabel = pset.getParameter<string>("recHits2DLabel");
70    
71     // the name of the 4D rec hits collection
72     theRecHits4DLabel = pset.getParameter<string>("recHits4DLabel");
73    
74     // if MC
75     mc = pset.getParameter<bool>("isMC");
76    
77     theMinHitsSegment = static_cast<unsigned int>(pset.getParameter<int>("minHitsSegment"));
78     theMinChi2NormSegment = pset.getParameter<double>("minChi2NormSegment");
79     theMinCloseDist = pset.getParameter<double>("minCloseDist");
80    
81     // trigger selection
82     LCT_RPC = pset.getParameter<bool>("LCT_RPC");
83     LCT_DT = pset.getParameter<bool>("LCT_DT");
84     LCT_CSC = pset.getParameter<bool>("LCT_CSC");
85    
86     init=false;
87     }
88    
89     void DTEffOfflineAnalyzer::beginJob(const EventSetup& eventSetup) {
90     if(debug) cout << "beginOfJob" << endl;
91     // Get the DT Geometry
92     eventSetup.get<MuonGeometryRecord>().get(dtGeom);
93    
94     // Create the root file
95 battilan 1.2 // theFile = new TFile(theRootFileName.c_str(), "RECREATE");
96    
97     theDQMStore = edm::Service<DQMStore>().operator->();
98 giorgia 1.1
99     // trigger Histos
100     createTH1F("hTrigBits","All trigger bits","", 10,0.,10.);
101    
102     for (int w=-2; w<=2; ++w) {
103     stringstream nameWheel;
104     nameWheel << "_Wh"<< w ;
105     for (int sec=1; sec<=14; ++sec) { // section 1 to 14
106     stringstream nameSector;
107     nameSector << nameWheel.str() << "_Sec" << sec;
108     for (int st=1; st<=4; ++st) { // station 1 to 4
109    
110     stringstream nameChamber;
111     nameChamber << nameSector.str() << "_St" << st;
112    
113     createTH1F("hDistSegFromExtrap",
114     "Distance segments from extrap position ",nameChamber.str(), 200,0.,200.);
115     createTH1F("hNaiveEffSeg","Naive eff ",nameChamber.str(), 10,0.,10.);
116     createTH2F("hEffSegVsPosDen", "Eff vs local position (all) ", nameChamber.str(),
117     25,-250.,250., 25,-250.,250.);
118     createTH2F("hEffGoodSegVsPosDen", "Eff vs local position (good) ", nameChamber.str(),
119     25,-250.,250., 25,-250.,250.);
120     createTH2F("hEffSegVsPosNum", "Eff vs local position ", nameChamber.str(),
121     25,-250.,250., 25,-250.,250.);
122     createTH2F("hEffGoodSegVsPosNum", "Eff vs local position (good segs) ", nameChamber.str(),
123     25,-250.,250., 25,-250.,250.);
124     createTH2F("hEffGoodCloseSegVsPosNum",
125     "Eff vs local position (good aand close segs) ", nameChamber.str(),
126     25,-250.,250., 25,-250.,250.);
127     }
128     }
129     }
130     }
131    
132     /* Destructor */
133     DTEffOfflineAnalyzer::~DTEffOfflineAnalyzer() {
134 battilan 1.2 theDQMStore->rmdir("DT/DTEffOfflineAnalyzer");
135 giorgia 1.1 }
136    
137     /* Operations */
138     void DTEffOfflineAnalyzer::analyze(const Event & event,
139     const EventSetup& eventSetup) {
140     if (debug) cout << endl<<"--- [DTEffOfflineAnalyzer] Event analysed #Run: " <<
141     event.id().run() << " #Event: " << event.id().event() << endl;
142    
143     float nrun=event.id().run();
144     if(!init)
145     {
146     createTH1F("RunNumbers","RunNumbers","",23,nrun-11.5,nrun+11.5);
147     init=true;
148     }
149     histo("RunNumbers")->Fill(nrun);
150    
151    
152     // Trigger analysis
153     if (debug) cout << "Is MC " << mc << endl;
154    
155     if (!mc) {
156     Handle<LTCDigiCollection> ltcdigis;
157 marycruz 1.5 //event.getByType(ltcdigis); // Doesn't work after 62X
158 pellicci 1.4 event.getByLabel("none",ltcdigis);
159 giorgia 1.1
160     for (std::vector<LTCDigi>::const_iterator ltc= ltcdigis->begin(); ltc!=
161     ltcdigis->end(); ++ltc) {
162     for (int i = 0; i < 6; i++)
163     if ((*ltc).HasTriggered(i)) {
164     LCT.set(i);
165     histo("hTrigBits")->Fill(i);
166     }
167     }
168     } else {
169     for (int i = 0; i < 6; i++)
170     LCT.set(i);
171     }
172    
173     if (selectEvent()) {
174     effSegments(event, eventSetup);
175     }
176     }
177    
178     bool DTEffOfflineAnalyzer::selectEvent() const {
179     bool trigger=false;
180     if (LCT_DT) trigger = trigger || getLCT(DT);
181     if (LCT_RPC) trigger = trigger || (getLCT(RPC_W1) || getLCT(RPC_W2));
182     if (LCT_CSC) trigger = trigger || getLCT(CSC);
183     if (debug) cout << "LCT " << trigger << endl;
184     return trigger;
185     }
186    
187     void DTEffOfflineAnalyzer::effSegments(const Event & event,
188     const EventSetup& eventSetup){
189    
190     event.getByLabel(theRecHits4DLabel, segs);
191     if (debug) {
192     cout << "4d " << segs->size() << endl;
193     for (DTRecSegment4DCollection::const_iterator seg=segs->begin() ;
194     seg!=segs->end() ; ++seg )
195     cout << *seg << endl;
196     }
197    
198 battilan 1.3
199 giorgia 1.1
200     // Get events with 3 segments in different station and look what happen on
201     // the other station. Note, must take into account geometrical acceptance
202    
203     // trivial pattern recognition: get 3 segments in 3 different station of a
204     // given wheel, sector
205    
206     for (int wheel = -2; wheel <=2; ++wheel) {
207     for (int sector = 1; sector <=12; ++sector) {
208     evaluateEff(DTChamberId(wheel, 1, sector),2,3 ); // get efficiency for MB1 using MB2 and MB3
209     evaluateEff(DTChamberId(wheel, 2, sector),1,3 ); // get efficiency for MB2 using MB1 and MB3
210     evaluateEff(DTChamberId(wheel, 3, sector),2,4 ); // get efficiency for MB3 using MB2 and MB4
211     evaluateEff(DTChamberId(wheel, 4, sector),2,3 ); // get efficiency for MB4 using MB2 and MB3
212    
213     }
214     }
215     }
216    
217     void DTEffOfflineAnalyzer::evaluateEff(const DTChamberId& MidId, int bottom, int top) const {
218     if (debug) cout << "evaluateEff " << MidId << " bott/top " << bottom << "/"<< top << endl;
219     // Select events with (good) segments in Bot and Top
220     DTChamberId BotId(MidId.wheel(), bottom, MidId.sector());
221     DTChamberId TopId(MidId.wheel(), top, MidId.sector());
222    
223     // Get segments in the bottom chambers (if any)
224     DTRecSegment4DCollection::range segsBot= segs->get(BotId);
225     int nSegsBot=segsBot.second-segsBot.first;
226     // check if any segments is there
227     if (nSegsBot==0) return;
228    
229     // Get segments in the top chambers (if any)
230     DTRecSegment4DCollection::range segsTop= segs->get(TopId);
231     int nSegsTop=segsTop.second-segsTop.first;
232    
233     // something more sophisticate check quality of segments
234     const DTRecSegment4D& bestBotSeg= getBestSegment(segsBot);
235     //cout << "BestBotSeg " << bestBotSeg << endl;
236    
237     DTRecSegment4D* pBestTopSeg=0;
238     if (nSegsTop>0) pBestTopSeg=
239     const_cast<DTRecSegment4D*>(&getBestSegment(segsTop));
240     //if top chamber is MB4 sector 10, consider also sector 14
241     if (TopId.station()==4 && TopId.sector()==10) {
242     DTChamberId TopId14(MidId.wheel(), top, 14);
243     DTRecSegment4DCollection::range segsTop14= segs->get(TopId14);
244     int nSegsTop14=segsTop14.second-segsTop14.first;
245     nSegsTop+=nSegsTop;
246     if (nSegsTop14) {
247     DTRecSegment4D* pBestTopSeg14=
248     const_cast<DTRecSegment4D*>(&getBestSegment(segsTop14));
249    
250     // get best between sector 10 and 14
251     pBestTopSeg =
252     const_cast<DTRecSegment4D*>(getBestSegment(pBestTopSeg, pBestTopSeg14));
253     }
254     }
255     if (!pBestTopSeg) return;
256     const DTRecSegment4D& bestTopSeg= *pBestTopSeg;
257    
258     DTRecSegment4DCollection::range segsMid= segs->get(MidId);
259     int nSegsMid=segsMid.second-segsMid.first;
260    
261     // very trivial efficiency, just count segments
262     histo(hName("hNaiveEffSeg",MidId))->Fill(0);
263     if (nSegsMid>0) histo(hName("hNaiveEffSeg",MidId))->Fill(1);
264    
265     // get position at Mid by interpolating the position (not direction) of best
266     // segment in Bot and Top to Mid surface
267     LocalPoint posAtMid = interpolate(bestBotSeg, bestTopSeg, MidId);
268    
269     // is best segment good enough?
270     if (isGoodSegment(bestBotSeg) && isGoodSegment(bestTopSeg)) {
271     histo2d(hName("hEffSegVsPosDen",MidId))->Fill(posAtMid.x(),posAtMid.y());
272     //check if interpolation fall inside middle chamber
273     if ((dtGeom->chamber(MidId))->surface().bounds().inside(posAtMid)) {
274    
275     histo2d(hName("hEffGoodSegVsPosDen",MidId))->Fill(posAtMid.x(),posAtMid.y());
276    
277     if (nSegsMid>0) {
278     histo(hName("hNaiveEffSeg",MidId))->Fill(2);
279     histo2d(hName("hEffSegVsPosNum",MidId))->Fill(posAtMid.x(),posAtMid.y());
280     const DTRecSegment4D& bestMidSeg= getBestSegment(segsMid);
281     // check if middle segments is good enough
282     if (isGoodSegment(bestMidSeg)) {
283     histo2d(hName("hEffGoodSegVsPosNum",MidId))->Fill(posAtMid.x(),posAtMid.y());
284     LocalPoint midSegPos=bestMidSeg.localPosition();
285     // check if middle segments is also close enough
286     double dist;
287     if (bestMidSeg.hasPhi()) {
288     if (bestTopSeg.hasZed() && bestBotSeg.hasZed() && bestMidSeg.hasZed()) {
289     dist = (midSegPos-posAtMid).mag();
290     } else {
291     dist = fabs((midSegPos-posAtMid).x());
292     }
293     } else {
294     dist = fabs((midSegPos-posAtMid).y());
295     }
296     if (dist < theMinCloseDist ) {
297     histo2d(hName("hEffGoodCloseSegVsPosNum",MidId))->Fill(posAtMid.x(),posAtMid.y());
298     }
299     histo(hName("hDistSegFromExtrap",MidId))->Fill(dist);
300     }
301    
302     }
303     }
304     }
305     // else cout << "Outside " << endl;
306     }
307    
308     // as usual max number of hits and min chi2
309     const DTRecSegment4D& DTEffOfflineAnalyzer::getBestSegment(const DTRecSegment4DCollection::range& segs) const{
310     DTRecSegment4DCollection::const_iterator bestIter;
311     unsigned int nHitBest=0;
312     double chi2Best=99999.;
313     for (DTRecSegment4DCollection::const_iterator seg=segs.first ;
314     seg!=segs.second ; ++seg ) {
315     unsigned int nHits= ((*seg).hasPhi() ? (*seg).phiSegment()->recHits().size() : 0 ) ;
316     nHits+= ((*seg).hasZed() ? (*seg).zSegment()->recHits().size() : 0 );
317    
318     if (nHits==nHitBest) {
319     if ((*seg).chi2()/(*seg).degreesOfFreedom() < chi2Best ) {
320     chi2Best=(*seg).chi2()/(*seg).degreesOfFreedom();
321     bestIter = seg;
322     }
323     }
324     else if (nHits>nHitBest) {
325     nHitBest=nHits;
326     bestIter = seg;
327     }
328     }
329     return *bestIter;
330     }
331    
332     const DTRecSegment4D* DTEffOfflineAnalyzer::getBestSegment(const DTRecSegment4D* s1,
333     const DTRecSegment4D* s2) const{
334    
335     if (!s1) return s2;
336     if (!s2) return s1;
337     unsigned int nHits1= (s1->hasPhi() ? s1->phiSegment()->recHits().size() : 0 ) ;
338     nHits1+= (s1->hasZed() ? s1->zSegment()->recHits().size() : 0 );
339    
340     unsigned int nHits2= (s2->hasPhi() ? s2->phiSegment()->recHits().size() : 0 ) ;
341     nHits2+= (s2->hasZed() ? s2->zSegment()->recHits().size() : 0 );
342    
343     if (nHits1==nHits2) {
344     if (s1->chi2()/s1->degreesOfFreedom() < s2->chi2()/s2->degreesOfFreedom() )
345     return s1;
346     else
347     return s2;
348     }
349     else if (nHits1>nHits2) return s1;
350     return s2;
351     }
352    
353     bool DTEffOfflineAnalyzer::isGoodSegment(const DTRecSegment4D& seg) const {
354     if (seg.chamberId().station()!=4 && !seg.hasZed()) return false;
355     unsigned int nHits= (seg.hasPhi() ? seg.phiSegment()->recHits().size() : 0 ) ;
356     nHits+= (seg.hasZed() ? seg.zSegment()->recHits().size() : 0 );
357     return ( nHits >= theMinHitsSegment &&
358     seg.chi2()/seg.degreesOfFreedom() < theMinChi2NormSegment );
359     }
360    
361     LocalPoint DTEffOfflineAnalyzer::interpolate(const DTRecSegment4D& seg1,
362     const DTRecSegment4D& seg3,
363     const DTChamberId& id2) const {
364     // Get GlobalPoition of Seg in MB1
365     GlobalPoint
366     gpos1=(dtGeom->chamber(seg1.chamberId()))->toGlobal(seg1.localPosition());
367    
368     // Get GlobalPoition of Seg in MB3
369     GlobalPoint
370     gpos3=(dtGeom->chamber(seg3.chamberId()))->toGlobal(seg3.localPosition());
371    
372     // interpolate
373     // get all in MB2 frame
374     LocalPoint pos1=(dtGeom->chamber(id2))->toLocal(gpos1);
375     LocalPoint pos3=(dtGeom->chamber(id2))->toLocal(gpos3);
376    
377     // case 1: 1 and 3 has both projection. No problem
378    
379     // case 2: one projection is missing for one of the segments. Keep the other's
380     // segment position
381     if (!seg1.hasZed()) pos1=LocalPoint(pos1.x(),pos3.y(),pos1.z());
382     if (!seg3.hasZed()) pos3=LocalPoint(pos3.x(),pos1.y(),pos3.z());
383    
384     if (!seg1.hasPhi()) pos1=LocalPoint(pos3.x(),pos1.y(),pos1.z());
385     if (!seg3.hasPhi()) pos3=LocalPoint(pos1.x(),pos3.y(),pos3.z());
386    
387     // direction
388     LocalVector dir = (pos3-pos1).unit(); // z points inward!
389     LocalPoint pos2 = pos1+dir*pos1.z()/(-dir.z());
390    
391    
392     return pos2;
393     }
394    
395     TH1F* DTEffOfflineAnalyzer::histo(const string& name) const{
396 battilan 1.2 MonitorElement* me = theDQMStore->get(("DT/DTEffOfflineAnalyzer/"+name).c_str());
397     if (!me) throw cms::Exception("DTEffOfflineAnalyzer") << " ME not existing " << name;
398     TH1F* histo = me->getTH1F();
399     if (!histo)cms::Exception("DTEffOfflineAnalyzer") << " Not a TH1F " << name;
400     return histo;
401 giorgia 1.1 }
402    
403     TH2F* DTEffOfflineAnalyzer::histo2d(const string& name) const{
404 battilan 1.2 MonitorElement* me = theDQMStore->get(("DT/DTEffOfflineAnalyzer/"+name).c_str());
405     if (!me) throw cms::Exception("DTEffOfflineAnalyzer") << " ME not existing " << name;
406     TH2F* histo = me->getTH2F();
407     if (!histo)cms::Exception("DTEffOfflineAnalyzer") << " Not a TH2F " << name;
408     return histo;
409 giorgia 1.1 }
410    
411     string DTEffOfflineAnalyzer::toString(const DTChamberId& id) const {
412     stringstream result;
413     result << "_Wh" << id.wheel()
414     << "_Sec" << id.sector()
415     << "_St" << id.station();
416     return result.str();
417     }
418    
419     template<class T> string DTEffOfflineAnalyzer::hName(const string& s, const T& id) const {
420     string name(toString(id));
421     stringstream hName;
422     hName << s << name;
423     return hName.str();
424     }
425    
426     void DTEffOfflineAnalyzer::createTH1F(const std::string& name,
427     const std::string& title,
428     const std::string& suffix,
429     int nbin,
430     const double& binMin,
431     const double& binMax) const {
432     stringstream hName;
433     stringstream hTitle;
434     hName << name << suffix;
435     hTitle << title << suffix;
436 battilan 1.2 theDQMStore->setCurrentFolder("DT/DTEffOfflineAnalyzer");
437     theDQMStore->book1D(hName.str().c_str(), hTitle.str().c_str(), nbin,binMin,binMax);
438     // TH1F * _h = new TH1F(hName.str().c_str(), hTitle.str().c_str(), nbin,binMin,binMax);
439     // _h->SetDirectory(theFile); // Needed when the input is a root file
440 giorgia 1.1 }
441    
442     void DTEffOfflineAnalyzer::createTH2F(const std::string& name,
443     const std::string& title,
444     const std::string& suffix,
445     int nBinX,
446     const double& binXMin,
447     const double& binXMax,
448     int nBinY,
449     const double& binYMin,
450     const double& binYMax) const {
451     stringstream hName;
452     stringstream hTitle;
453     hName << name << suffix;
454     hTitle << title << suffix;
455 battilan 1.2 theDQMStore->setCurrentFolder("DT/DTEffOfflineAnalyzer");
456     theDQMStore->book2D(hName.str().c_str(), hTitle.str().c_str(), nBinX,binXMin,binXMax, nBinY,binYMin,binYMax);
457     // TH2F * _h = new TH2F(hName.str().c_str(), hTitle.str().c_str(), nBinX,binXMin,binXMax, nBinY,binYMin,binYMax);
458     // _h->SetDirectory(theFile); // Needed when the input is a root file
459 giorgia 1.1
460     }
461    
462     bool DTEffOfflineAnalyzer::getLCT(LCTType t) const {
463     return LCT.test(t);
464     }