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 |
|
|
}
|