1 |
/******* \class STAnalyzer *******
|
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 |
* March 2008: Histo Modifications To allow run over the root files
|
13 |
*
|
14 |
*********************************/
|
15 |
|
16 |
/* This Class Header */
|
17 |
#include "UserCode/DTDPGAnalysis/src/STAOfflineAnalyzer.h"
|
18 |
|
19 |
/* Collaborating Class Header */
|
20 |
#include "FWCore/Framework/interface/MakerMacros.h"
|
21 |
#include "FWCore/Framework/interface/Frameworkfwd.h"
|
22 |
#include "FWCore/Framework/interface/Event.h"
|
23 |
#include "FWCore/ParameterSet/interface/ParameterSet.h"
|
24 |
#include "FWCore/Framework/interface/ESHandle.h"
|
25 |
#include "FWCore/Utilities/interface/Exception.h"
|
26 |
#include "DQMServices/Core/interface/DQMStore.h"
|
27 |
#include "DQMServices/Core/interface/MonitorElement.h"
|
28 |
#include "FWCore/ServiceRegistry/interface/Service.h"
|
29 |
|
30 |
using namespace edm;
|
31 |
|
32 |
#include "TFile.h"
|
33 |
#include "TH1F.h"
|
34 |
#include "TH2F.h"
|
35 |
|
36 |
#include "DataFormats/LTCDigi/interface/LTCDigi.h"
|
37 |
|
38 |
#include "Geometry/DTGeometry/interface/DTGeometry.h"
|
39 |
#include "Geometry/Records/interface/MuonGeometryRecord.h"
|
40 |
#include "DataFormats/DTRecHit/interface/DTRecHitCollection.h"
|
41 |
#include "DataFormats/DTRecHit/interface/DTRecSegment2DCollection.h"
|
42 |
#include "DataFormats/DTRecHit/interface/DTRecSegment4DCollection.h"
|
43 |
|
44 |
#include "Geometry/Records/interface/GlobalTrackingGeometryRecord.h"
|
45 |
#include "Geometry/CommonDetUnit/interface/GlobalTrackingGeometry.h"
|
46 |
#include "MagneticField/Engine/interface/MagneticField.h"
|
47 |
#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
|
48 |
#include "TrackingTools/TransientTrack/interface/TransientTrack.h"
|
49 |
#include "RecoMuon/TrackingTools/interface/MuonPatternRecoDumper.h"
|
50 |
|
51 |
#include "DataFormats/GeometrySurface/interface/Cylinder.h"
|
52 |
#include "TrackingTools/GeomPropagators/interface/Propagator.h"
|
53 |
#include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
|
54 |
#include "TrackingTools/TransientTrack/interface/TransientTrack.h"
|
55 |
|
56 |
#include "DataFormats/TrajectorySeed/interface/TrajectorySeedCollection.h"
|
57 |
#include "DataFormats/TrackReco/interface/Track.h"
|
58 |
|
59 |
/* C++ Headers */
|
60 |
#include <iostream>
|
61 |
#include <cmath>
|
62 |
using namespace std;
|
63 |
|
64 |
/* ====================================================================== */
|
65 |
|
66 |
/* Constructor */
|
67 |
STAOfflineAnalyzer::STAOfflineAnalyzer(const ParameterSet& pset) : _ev(0){
|
68 |
|
69 |
// Get the debug parameter for verbose output
|
70 |
debug = pset.getUntrackedParameter<bool>("debug");
|
71 |
theRootFileName = pset.getUntrackedParameter<string>("rootFileName");
|
72 |
|
73 |
// the name of the digis collection
|
74 |
theDTLocalTriggerLabel = pset.getParameter<string>("DTLocalTriggerLabel");
|
75 |
|
76 |
// the name of the 1D rec hits collection
|
77 |
theRecHits1DLabel = pset.getParameter<string>("recHits1DLabel");
|
78 |
|
79 |
// the name of the 2D rec hits collection
|
80 |
theRecHits2DLabel = pset.getParameter<string>("recHits2DLabel");
|
81 |
|
82 |
// the name of the 4D rec hits collection
|
83 |
theRecHits4DLabel = pset.getParameter<string>("recHits4DLabel");
|
84 |
|
85 |
// the name of the STA rec hits collection
|
86 |
theSTAMuonLabel = pset.getParameter<string>("SALabel");
|
87 |
|
88 |
thePropagatorName = pset.getParameter<std::string>("PropagatorName");
|
89 |
thePropagator = 0;
|
90 |
|
91 |
// if MC
|
92 |
mc = pset.getParameter<bool>("isMC");
|
93 |
|
94 |
LCT_RPC = pset.getParameter<bool>("LCT_RPC");
|
95 |
LCT_DT = pset.getParameter<bool>("LCT_DT");
|
96 |
LCT_CSC = pset.getParameter<bool>("LCT_CSC");
|
97 |
|
98 |
doSA = pset.getParameter<bool>("doSA");
|
99 |
|
100 |
theDQMStore = edm::Service<DQMStore>().operator->();
|
101 |
|
102 |
init=false;
|
103 |
// Create the root file
|
104 |
// theFile = new TFile(theRootFileName.c_str(), "RECREATE");
|
105 |
|
106 |
// CosmicMuon
|
107 |
createTH1F("hNSA","Num SA tracks in events","", 6, -0.5, 5.5);
|
108 |
createTH1F("hNSADifferentSectors","Num SA tracks with hits in different sectors","", 6, -0.5, 5.5);
|
109 |
createTH1F("hNhitsSA","Num hits in SA tracks","", 50, .5, 50.5);
|
110 |
createTH1F("hChi2SA","#chi^{2}/NDoF for SA tracks","", 100, 0, 100.);
|
111 |
createTH1F("hPIPSA","p for SA tracks @ IP","", 100, 0., 100);
|
112 |
createTH1F("hPtIPSA","pt for SA tracks @ IP","", 100, 0., 100);
|
113 |
createTH1F("hPhiIPSA","#phi for SA tracks @ IP","", 100, -M_PI_2, M_PI_2);
|
114 |
createTH1F("hEtaIPSA","#eta for SA tracks @ IP","", 100, -2.5, 2.5);
|
115 |
createTH1F("hPInnerTSOSSA","p for SA tracks @ innermost TSOS","", 100, 0., 100);
|
116 |
createTH1F("hPtInnerTSOSSA","pt for SA tracks @ innermost TSOS","", 100, 0., 100);
|
117 |
createTH1F("hPhiInnerTSOSSA","#phi for SA tracks @ innermost TSOS","", 100, -M_PI_2, M_PI_2);
|
118 |
createTH1F("hEtaInnerTSOSSA","#eta for SA tracks @ innermost TSOS","", 100, -2.5, 2.5);
|
119 |
createTH1F("hInnerRSA","Radius of innermost TSOS for SA tracks","", 100, 400, 1000.);
|
120 |
createTH1F("hOuterRSA","Radius of outermost TSOS for SA tracks","", 100, 400, 1000.);
|
121 |
createTH2F("hInnerOuterRSA","Radius of outermost TSOS vs innermost one for SA tracks","",
|
122 |
40, 400, 1000.,40, 400, 1000.);
|
123 |
|
124 |
createTH2F("hNSAVsNHits","Num 1d Hits vs N SA","", 100,-0.5,39.5, 5,-0.5, 4.5);
|
125 |
createTH2F("hNSAVsNSegs2D","Num 2d Segs vs N SA","", 20,-0.5,19.5, 5,-0.5, 4.5);
|
126 |
createTH2F("hNSAVsNSegs4D","Num 4d Segs vs N SA","", 10,-0.5,9.5, 5,-0.5, 4.5);
|
127 |
|
128 |
createTH2F("hNHitsSAVsNHits","Num 1d Hits vs N Hits SA","", 40,-0.5,39.5, 100,0,100);
|
129 |
createTH2F("hNHitsSAVsNSegs2D","Num 2d Segs vs N Hits SA","", 20,-0.5,19.5,100,0,100);
|
130 |
createTH2F("hNHitsSAVsNSegs4D","Num 4d Segs vs N Hits SA","", 10,-0.5,9.5, 100,0,100);
|
131 |
|
132 |
createTH1F("hSANLayers","Num Layers used SA","", 50,-0.5,49.5);
|
133 |
createTH1F("hSANSLs","Num SuperLayers used SA","", 15,-0.5,14.5);
|
134 |
createTH1F("hSANLayersPerSL","Num Layers per SL used SA","", 15,-0.5,14.5);
|
135 |
createTH1F("hSANChambers","Num Chambers used SA","", 6,-0.5,5.5);
|
136 |
createTH1F("hSANLayersPerChamber","Num Layers per SL used SA","", 15,-0.5,14.5);
|
137 |
createTH1F("hSANSLsPerChamber","Num SLs per SL used SA","", 5,-0.5,4.5);
|
138 |
|
139 |
createTH2F("hSANLayersVsNChambers","Num Layers Vs Num Chambers used SA","", 6,-0.5,5.5, 50,-0.5,49.5);
|
140 |
createTH2F("hSANSLsVsNChambers","Num SuperLayers Vs Num Chambers used SA","", 6,-0.5,5.5, 16,-0.5,15.5);
|
141 |
|
142 |
createTH2F("hSANHitsVsNLayers","Num Hits vs Num Layers used SA","", 50,-0.5,49.5, 50,0.,50.);
|
143 |
createTH2F("hSANHitsVsNSLs","Num Hits vs Num SuperLayers used SA","", 16,-0.5,15.5,50,0.,50.);
|
144 |
createTH2F("hSANHitsVsNChambers","Num Hits vs Num Chambers used SA","", 6,-0.5,5.5,50,0.,50.);
|
145 |
|
146 |
createTH2F("hHitsPosXYSA","Hits position (x,y) SA","",100,-200,200,100,400,800);
|
147 |
createTH2F("hHitsPosXZSA","Hits position (x,z) SA","",100,-200,200,100,-150,150);
|
148 |
createTH2F("hHitsPosYZSA","Hits position (y,z) SA","",100,-150,150,100,400,800);
|
149 |
|
150 |
createTH1F("nHitsSAInChamber","Num STA recHits in each chamber","", 4, 0.5, 4.5);
|
151 |
createTH1F("nHitsSAInSL","Num STA recHits in each sl","", 50, 0.5, 50.5);
|
152 |
createTH1F("nHitsSAInLayer","Num STA recHits in each layer","", 75, 25.5, 100.5);
|
153 |
|
154 |
createTH1F("hHitsLostChamber","Num hits in det w/o associated hits chamber","", 30, 0.,30.);
|
155 |
createTH1F("hHitsLostSL","Num hits in det w/o associated hits SL","", 30, 0.,30.);
|
156 |
createTH1F("hHitsLostLayer","Num hits in det w/o associated hits Layer","", 30, 0.,30.);
|
157 |
createTH1F("hMinDistChamber","Min distance between extrap post and closest hit in det w/o associated hits chamber","", 100, 0., 300.);
|
158 |
createTH1F("hMinDistSL","Min distance between extrap post and closest hit in det w/o associated hits SL","", 100, 0., 300.);
|
159 |
createTH1F("hMinDistLayer","Min distance between extrap post and closest hit in det w/o associated hits Layer","", 100, 0., 300.);
|
160 |
}
|
161 |
|
162 |
/* Destructor */
|
163 |
STAOfflineAnalyzer::~STAOfflineAnalyzer() {
|
164 |
theDQMStore->rmdir("DT/STAOfflineAnalyzer");
|
165 |
}
|
166 |
|
167 |
/* Operations */
|
168 |
void STAOfflineAnalyzer::beginJob(const EventSetup& eventSetup) {
|
169 |
// Get the DT Geometry
|
170 |
ESHandle<DTGeometry> dtGeom;
|
171 |
eventSetup.get<MuonGeometryRecord>().get(dtGeom);
|
172 |
|
173 |
const std::vector<DTChamber*> & chs = dtGeom->chambers();
|
174 |
for (std::vector<DTChamber*>::const_iterator ch = chs.begin();
|
175 |
ch!=chs.end() ; ++ch)
|
176 |
hitsPerChamber[(*ch)->id()]=0;
|
177 |
|
178 |
}
|
179 |
|
180 |
void STAOfflineAnalyzer::analyze(const Event & event,
|
181 |
const EventSetup& eventSetup) {
|
182 |
|
183 |
int nprt = event.id().event() - 100*(event.id().event()/100);
|
184 |
if( nprt == 1000)
|
185 |
cout << "Run:Event analyzed " << event.id().run() << ":" << event.id().event() <<
|
186 |
" Num " << _ev++ << endl;
|
187 |
|
188 |
if (debug) cout << endl<<"--- [STAOfflineAnalyzer] Event analysed #Run: " <<
|
189 |
event.id().run() << " #Event: " << event.id().event() << endl;
|
190 |
|
191 |
float nrun=event.id().run();
|
192 |
if(!init)
|
193 |
{
|
194 |
createTH1F("Info_RunNumbers","Info_RunNumbers","",23,nrun-11.5,nrun+11.5);
|
195 |
init=true;
|
196 |
}
|
197 |
histo("Info_RunNumbers")->Fill(nrun);
|
198 |
|
199 |
|
200 |
|
201 |
// Trigger analysis
|
202 |
if (debug) cout << "Is MC " << mc << endl;
|
203 |
|
204 |
if (!mc) {
|
205 |
Handle<LTCDigiCollection> ltcdigis;
|
206 |
//event.getByType(ltcdigis); // Doesn't work after 62X
|
207 |
event.getByLabel("none",ltcdigis);
|
208 |
|
209 |
for (std::vector<LTCDigi>::const_iterator ltc= ltcdigis->begin(); ltc!=
|
210 |
ltcdigis->end(); ++ltc) {
|
211 |
for (int i = 0; i < 6; i++)
|
212 |
if ((*ltc).HasTriggered(i)) {
|
213 |
LCT.set(i);
|
214 |
histo("hTrigBits")->Fill(i);
|
215 |
}
|
216 |
}
|
217 |
} else {
|
218 |
for (int i = 0; i < 6; i++)
|
219 |
LCT.set(i);
|
220 |
}
|
221 |
|
222 |
if (selectEvent()) {
|
223 |
if (doSA) analyzeSATrack(event, eventSetup);
|
224 |
}
|
225 |
}
|
226 |
|
227 |
bool STAOfflineAnalyzer::selectEvent() const {
|
228 |
bool trigger=false;
|
229 |
if (LCT_DT) trigger = trigger || getLCT(DT);
|
230 |
if (LCT_RPC) trigger = trigger || (getLCT(RPC_W1) || getLCT(RPC_W2));
|
231 |
if (LCT_CSC) trigger = trigger || getLCT(CSC);
|
232 |
if (debug) cout << "LCT " << trigger << endl;
|
233 |
return trigger;
|
234 |
}
|
235 |
|
236 |
void STAOfflineAnalyzer::analyzeSATrack(const Event & event,
|
237 |
const EventSetup& eventSetup){
|
238 |
if (!thePropagator){
|
239 |
ESHandle<Propagator> prop;
|
240 |
eventSetup.get<TrackingComponentsRecord>().get(thePropagatorName, prop);
|
241 |
thePropagator = prop->clone();
|
242 |
thePropagator->setPropagationDirection(anyDirection);
|
243 |
}
|
244 |
|
245 |
MuonPatternRecoDumper muonDumper;
|
246 |
|
247 |
// Get the 4D rechit collection from the event -------------------
|
248 |
edm::Handle<DTRecSegment4DCollection> segs;
|
249 |
event.getByLabel(theRecHits4DLabel, segs);
|
250 |
|
251 |
// Get the 2D rechit collection from the event -------------------
|
252 |
edm::Handle<DTRecSegment2DCollection> segs2d;
|
253 |
event.getByLabel(theRecHits2DLabel, segs2d);
|
254 |
|
255 |
// Get the 1D rechits from the event --------------
|
256 |
Handle<DTRecHitCollection> dtRecHits;
|
257 |
event.getByLabel(theRecHits1DLabel, dtRecHits);
|
258 |
|
259 |
// Get the RecTrack collection from the event
|
260 |
Handle<reco::TrackCollection> staTracks;
|
261 |
event.getByLabel(theSTAMuonLabel, staTracks);
|
262 |
|
263 |
ESHandle<MagneticField> theMGField;
|
264 |
eventSetup.get<IdealMagneticFieldRecord>().get(theMGField);
|
265 |
|
266 |
ESHandle<GlobalTrackingGeometry> theTrackingGeometry;
|
267 |
eventSetup.get<GlobalTrackingGeometryRecord>().get(theTrackingGeometry);
|
268 |
|
269 |
reco::TrackCollection::const_iterator staTrack;
|
270 |
|
271 |
double recPt=0.;
|
272 |
histo("hNSA")->Fill(staTracks->size());
|
273 |
histo2d("hNSAVsNHits")->Fill(dtRecHits->size(),staTracks->size());
|
274 |
histo2d("hNSAVsNSegs2D")->Fill(segs2d->size(),staTracks->size());
|
275 |
histo2d("hNSAVsNSegs4D")->Fill(segs->size(),staTracks->size());
|
276 |
|
277 |
if (debug && staTracks->size() )
|
278 |
cout << endl<<"R:E " << event.id().run() << ":" << event.id().event() <<
|
279 |
" SA " << staTracks->size() << endl;
|
280 |
|
281 |
for (staTrack = staTracks->begin(); staTrack != staTracks->end(); ++staTrack){
|
282 |
reco::TransientTrack track(*staTrack,&*theMGField,theTrackingGeometry);
|
283 |
|
284 |
if (debug) {
|
285 |
cout << muonDumper.dumpFTS(track.impactPointTSCP().theState());
|
286 |
|
287 |
recPt = track.impactPointTSCP().momentum().perp();
|
288 |
cout<<" p: "<<track.impactPointTSCP().momentum().mag()<< " pT: "<<recPt<<endl;
|
289 |
cout<<" normalized chi2: "<<track.normalizedChi2()<<endl;
|
290 |
}
|
291 |
|
292 |
histo("hChi2SA")->Fill(track.normalizedChi2());
|
293 |
|
294 |
histo("hPIPSA")->Fill(track.impactPointTSCP().momentum().mag());
|
295 |
histo("hPtIPSA")->Fill(recPt);
|
296 |
histo("hPhiIPSA")->Fill(track.impactPointTSCP().momentum().phi());
|
297 |
histo("hEtaIPSA")->Fill(track.impactPointTSCP().momentum().eta());
|
298 |
|
299 |
|
300 |
TrajectoryStateOnSurface innerTSOS = track.innermostMeasurementState();
|
301 |
if (debug) {
|
302 |
cout << "Inner TSOS:"<<endl;
|
303 |
cout << muonDumper.dumpTSOS(innerTSOS);
|
304 |
cout<<" p: "<<innerTSOS.globalMomentum().mag()<< " pT: "<<innerTSOS.globalMomentum().perp()<<endl;
|
305 |
}
|
306 |
|
307 |
// try to extrapolate using thePropagator
|
308 |
|
309 |
// Get a surface (here a cylinder of radius 1290mm) ECAL
|
310 |
float radiusECAL = 129.0; // radius in centimeter
|
311 |
Cylinder::PositionType pos0;
|
312 |
Cylinder::RotationType rot0;
|
313 |
const Cylinder::CylinderPointer ecal = Cylinder::build(pos0, rot0,
|
314 |
radiusECAL);
|
315 |
|
316 |
TrajectoryStateOnSurface tsosAtEcal =
|
317 |
thePropagator->propagate(*innerTSOS.freeState(), *ecal);
|
318 |
// if (tsosAtEcal.isValid())
|
319 |
// cout << "extrap to ECAL " << tsosAtEcal.globalPosition() << " r " <<
|
320 |
// tsosAtEcal.globalPosition().perp() << endl;
|
321 |
// else
|
322 |
// cout << "Extrapolation to ECAL failed" << endl;
|
323 |
|
324 |
// Get a surface (here a cylinder of radius 1811 mm) HCAL
|
325 |
float radiusHCAL = 181.1; // radius in centimeter
|
326 |
const Cylinder::CylinderPointer hcal = Cylinder::build(pos0, rot0,
|
327 |
radiusHCAL);
|
328 |
//cout << "Cyl " << hcal->radius() << endl;
|
329 |
|
330 |
TrajectoryStateOnSurface tsosAtHcal =
|
331 |
thePropagator->propagate(*innerTSOS.freeState(), *hcal);
|
332 |
// if (tsosAtHcal.isValid())
|
333 |
// cout << "extrap to HCAL " << tsosAtHcal.globalPosition() << " r " <<
|
334 |
// tsosAtHcal.globalPosition().perp() << endl;
|
335 |
// else
|
336 |
// cout << "Extrapolation to HCAL failed" << endl;
|
337 |
|
338 |
histo("hPInnerTSOSSA")->Fill(innerTSOS.globalMomentum().mag());
|
339 |
histo("hPtInnerTSOSSA")->Fill(innerTSOS.globalMomentum().perp());
|
340 |
histo("hPhiInnerTSOSSA")->Fill(innerTSOS.globalMomentum().phi());
|
341 |
histo("hEtaInnerTSOSSA")->Fill(innerTSOS.globalMomentum().eta());
|
342 |
|
343 |
histo("hNhitsSA")->Fill(staTrack->recHitsSize());
|
344 |
|
345 |
histo2d("hNHitsSAVsNHits")->Fill(dtRecHits->size(),staTrack->recHitsSize());
|
346 |
histo2d("hNHitsSAVsNSegs2D")->Fill(segs2d->size(),staTrack->recHitsSize());
|
347 |
histo2d("hNHitsSAVsNSegs4D")->Fill(segs->size(),staTrack->recHitsSize());
|
348 |
|
349 |
histo("hInnerRSA")->Fill(sqrt(staTrack->innerPosition().perp2()));
|
350 |
histo("hOuterRSA")->Fill(sqrt(staTrack->outerPosition().perp2()));
|
351 |
histo2d("hInnerOuterRSA")->Fill(sqrt(staTrack->innerPosition().perp2()),
|
352 |
sqrt(staTrack->outerPosition().perp2()));
|
353 |
|
354 |
if (debug) cout<<"RecHits:"<<endl;
|
355 |
|
356 |
trackingRecHit_iterator rhbegin = staTrack->recHitsBegin();
|
357 |
trackingRecHit_iterator rhend = staTrack->recHitsEnd();
|
358 |
|
359 |
// zero's the maps
|
360 |
for ( std::map<DTChamberId, int>::iterator h=hitsPerChamber.begin(); h!=hitsPerChamber.end(); ++h) (*h).second=0;
|
361 |
for ( std::map<DTSuperLayerId, int>::iterator h=hitsPerSL.begin(); h!=hitsPerSL.end(); ++h) (*h).second=0;
|
362 |
for ( std::map<DTLayerId, int>::iterator h=hitsPerLayer.begin(); h!=hitsPerLayer.end(); ++h) (*h).second=0;
|
363 |
|
364 |
int firstHitWheel = 0; // the Wheel of first hit
|
365 |
int lastHitWheel = 0; // the Wheel of last hit
|
366 |
int firstHitSector = 0; // the sector of first hit
|
367 |
int lastHitSector = 0; // the sector of last hit
|
368 |
for(trackingRecHit_iterator recHit = rhbegin; recHit != rhend; ++recHit){
|
369 |
const GeomDet* geomDet = theTrackingGeometry->idToDet((*recHit)->geographicalId());
|
370 |
GlobalPoint gpos=geomDet->toGlobal((*recHit)->localPosition());
|
371 |
if (debug) cout<<"r: "<< gpos.perp() <<" z: "<<gpos.z() <<endl;
|
372 |
histo2d("hHitsPosXYSA")->Fill(gpos.x(),gpos.y());
|
373 |
histo2d("hHitsPosXZSA")->Fill(gpos.z(),gpos.x());
|
374 |
histo2d("hHitsPosYZSA")->Fill(gpos.z(),gpos.y());
|
375 |
|
376 |
if (const DTLayer* lay=dynamic_cast<const DTLayer*>(geomDet)) {
|
377 |
if (firstHitSector == 0 ) firstHitSector=lay->id().sector();
|
378 |
lastHitSector=lay->id().sector();
|
379 |
if (firstHitWheel == 0 ) firstHitWheel=lay->id().wheel();
|
380 |
lastHitWheel=lay->id().wheel();
|
381 |
|
382 |
if(debug)cout << "Layer " << lay->id() << endl;
|
383 |
histo("nHitsSAInChamber")->Fill(lay->id().station());
|
384 |
hitsPerChamber[lay->id()]++;
|
385 |
histo("nHitsSAInSL")->Fill(lay->id().station()*10+lay->id().superlayer());
|
386 |
hitsPerSL[lay->id()]++;
|
387 |
histo("nHitsSAInLayer")->Fill(lay->id().station()*20+lay->id().superlayer()*5+lay->id().layer());
|
388 |
hitsPerLayer[lay->id()]++;
|
389 |
}
|
390 |
|
391 |
TrajectoryStateOnSurface extraptsos = thePropagator->propagate(innerTSOS,
|
392 |
geomDet->specificSurface());
|
393 |
}
|
394 |
|
395 |
|
396 |
// Get the DT Geometry
|
397 |
ESHandle<DTGeometry> dtGeom;
|
398 |
eventSetup.get<MuonGeometryRecord>().get(dtGeom);
|
399 |
|
400 |
// Get the 1D rechits from the event --------------
|
401 |
Handle<DTRecHitCollection> hits1d;
|
402 |
event.getByLabel(theRecHits1DLabel, hits1d);
|
403 |
|
404 |
// Get the 2D rechit collection from the event -------------------
|
405 |
edm::Handle<DTRecSegment2DCollection> segs2d;
|
406 |
event.getByLabel(theRecHits2DLabel, segs2d);
|
407 |
|
408 |
// Get the 4D rechit collection from the event -------------------
|
409 |
edm::Handle<DTRecSegment4DCollection> segs;
|
410 |
event.getByLabel(theRecHits4DLabel, segs);
|
411 |
|
412 |
// Now loop on chamber of relevant sector and look if there are hits in all
|
413 |
// of them
|
414 |
if (firstHitWheel == lastHitWheel && (
|
415 |
(firstHitSector == lastHitSector) ||
|
416 |
(firstHitSector==10 && lastHitSector ==14) ||
|
417 |
(firstHitSector==14 && lastHitSector ==10) ||
|
418 |
(firstHitSector==13 && lastHitSector ==4) ||
|
419 |
(firstHitSector==4 && lastHitSector ==13) )) {
|
420 |
|
421 |
|
422 |
int nLay=0, nSL=0, nCh=0;
|
423 |
for (int c=1; c<=5;++c) {
|
424 |
if (c==5 && firstHitSector==14) firstHitSector=10;
|
425 |
else if (c==5 && lastHitSector==14) lastHitSector=10;
|
426 |
else if (c==5 && firstHitSector==13) firstHitSector=4;
|
427 |
else if (c==5 && lastHitSector==13) lastHitSector=4;
|
428 |
else if (c==5) continue;
|
429 |
int cc=c;
|
430 |
if (c==5) cc=4;
|
431 |
|
432 |
int sect = min(firstHitSector,lastHitSector);
|
433 |
if (firstHitSector==14 && lastHitSector==14 && cc<4)sect=10;
|
434 |
if (firstHitSector==13 && lastHitSector==13 && cc<4)sect=4;
|
435 |
DTChamberId chid(firstHitWheel, cc, sect);
|
436 |
const DTChamber * ch = dtGeom->chamber(chid);
|
437 |
|
438 |
if (hitsPerChamber[chid]==0) {
|
439 |
missingHit(dtGeom, segs, ch, innerTSOS);
|
440 |
} else {
|
441 |
nCh++;
|
442 |
}
|
443 |
int nLayPerCh=0, nSLPerCh=0;
|
444 |
for (int isl=1; isl<=3; ++isl) {
|
445 |
if (isl==2 && cc==4) continue;
|
446 |
DTSuperLayerId slid(chid, isl);
|
447 |
const DTSuperLayer* sl = dtGeom->superLayer(slid);
|
448 |
if (hitsPerSL[slid]==0) {
|
449 |
missingHit(dtGeom, segs2d, sl, innerTSOS);
|
450 |
} else {
|
451 |
nSL++;
|
452 |
nSLPerCh++;
|
453 |
}
|
454 |
int nLayPerSL=0;
|
455 |
for (int l=1; l<=4; ++l) {
|
456 |
DTLayerId lid(slid, l);
|
457 |
const DTLayer* lay = dtGeom->layer(lid);
|
458 |
if (hitsPerLayer[lid]==0) {
|
459 |
missingHit(dtGeom, hits1d, lay, innerTSOS);
|
460 |
} else {
|
461 |
nLay++;
|
462 |
nLayPerCh++;
|
463 |
nLayPerSL++;
|
464 |
}
|
465 |
}
|
466 |
histo("hSANLayersPerSL")->Fill(nLayPerSL);
|
467 |
}
|
468 |
histo("hSANLayersPerChamber")->Fill(nLayPerCh);
|
469 |
histo("hSANSLsPerChamber")->Fill(nSLPerCh);
|
470 |
}
|
471 |
|
472 |
// how many different Chambers, SL, Layers are used in a SA?
|
473 |
histo("hSANLayers")->Fill(nLay);
|
474 |
histo("hSANSLs")->Fill(nSL);
|
475 |
histo("hSANChambers")->Fill(nCh);
|
476 |
histo2d("hSANLayersVsNChambers")->Fill(nCh, nLay);
|
477 |
histo2d("hSANSLsVsNChambers")->Fill(nCh,nSL);
|
478 |
// n det vs num hits used
|
479 |
histo2d("hSANHitsVsNLayers")->Fill(nLay,staTrack->recHitsSize());
|
480 |
histo2d("hSANHitsVsNSLs")->Fill(nSL, staTrack->recHitsSize());
|
481 |
histo2d("hSANHitsVsNChambers")->Fill(nCh, staTrack->recHitsSize());
|
482 |
if (nCh>4) cout << endl<<"R:E " << event.id().run() << ":" << event.id().event() <<
|
483 |
" nCh " << nCh << endl;
|
484 |
} else { // different wheel/sector
|
485 |
// cout << "First/Last hit in different wheel/sector " << firstHitSector
|
486 |
// << " " << lastHitSector<< endl;
|
487 |
histo("hNSADifferentSectors")->Fill(1);
|
488 |
}
|
489 |
|
490 |
}
|
491 |
if (debug) cout<<"---"<<endl;
|
492 |
}
|
493 |
|
494 |
template <typename T, typename C>
|
495 |
void STAOfflineAnalyzer::missingHit(const ESHandle<DTGeometry>& dtGeom,
|
496 |
const Handle<C>& segs,
|
497 |
const T* ch,
|
498 |
const TrajectoryStateOnSurface& startTsos) {
|
499 |
|
500 |
TrajectoryStateOnSurface extraptsos =
|
501 |
thePropagator->propagate(startTsos, ch->specificSurface());
|
502 |
if (extraptsos.isValid() ) {
|
503 |
//cout << "extraptsos " << extraptsos.localPosition() << endl;
|
504 |
bool inside =
|
505 |
ch->specificSurface().bounds().inside(extraptsos.localPosition());
|
506 |
//cout << "Is extrap inside? " << inside << endl;
|
507 |
if (inside) {
|
508 |
// Here I should loop on all hits of this chamber (if any) and get
|
509 |
// the closest
|
510 |
typename C::range segsch= segs->get(ch->id());
|
511 |
//int nSegsCh=segsch.second-segsch.first;
|
512 |
//cout << "Hits in chamber " << nSegsCh << endl;
|
513 |
pippo(segsch, ch, extraptsos);
|
514 |
// histo("hHitsLost")->Fill(nSegsCh);
|
515 |
// if (nSegsCh) {
|
516 |
// LocalPoint extrapPos=extraptsos.localPosition();
|
517 |
// //cout << "Extrap pos " << extrapPos << endl;
|
518 |
// double minDist=99999.;
|
519 |
// for (typename C::const_iterator hit=segsch.first; hit!=segsch.second;
|
520 |
// ++hit) {
|
521 |
// //cout << "Hit pos " << hit->localPosition() << endl;
|
522 |
// LocalVector dist = hit->localPosition() - extrapPos;
|
523 |
// //cout << "dist " << dist << " " << dist.perp() << endl;
|
524 |
// if (dist.perp()<minDist) minDist=dist.perp();
|
525 |
// }
|
526 |
// histo("hMinDist")->Fill(minDist);
|
527 |
// }
|
528 |
}
|
529 |
}
|
530 |
}
|
531 |
|
532 |
void STAOfflineAnalyzer::pippo(const DTRecSegment4DCollection::range segsch,
|
533 |
const DTChamber* ch,
|
534 |
const TrajectoryStateOnSurface& extraptsos) {
|
535 |
int nSegsCh=segsch.second-segsch.first;
|
536 |
histo("hHitsLostChamber")->Fill(nSegsCh);
|
537 |
if (nSegsCh) {
|
538 |
LocalPoint extrapPos=extraptsos.localPosition();
|
539 |
double minDist=99999.;
|
540 |
for (DTRecSegment4DCollection::const_iterator hit=segsch.first; hit!=segsch.second;
|
541 |
++hit) {
|
542 |
LocalVector dist = hit->localPosition() - extrapPos;
|
543 |
if (dist.perp()<minDist) minDist=dist.perp();
|
544 |
}
|
545 |
histo("hMinDistChamber")->Fill(minDist);
|
546 |
}
|
547 |
}
|
548 |
|
549 |
void STAOfflineAnalyzer::pippo(const DTRecSegment2DCollection::range segsch,
|
550 |
const DTSuperLayer* ch,
|
551 |
const TrajectoryStateOnSurface& extraptsos) {
|
552 |
int nSegsCh=segsch.second-segsch.first;
|
553 |
histo("hHitsLostSL")->Fill(nSegsCh);
|
554 |
if (nSegsCh) {
|
555 |
LocalPoint extrapPos=extraptsos.localPosition();
|
556 |
double minDist=99999.;
|
557 |
for (DTRecSegment2DCollection::const_iterator hit=segsch.first; hit!=segsch.second;
|
558 |
++hit) {
|
559 |
LocalVector dist = hit->localPosition() - extrapPos;
|
560 |
if (dist.perp()<minDist) minDist=dist.x();
|
561 |
}
|
562 |
histo("hMinDistSL")->Fill(minDist);
|
563 |
}
|
564 |
}
|
565 |
|
566 |
void STAOfflineAnalyzer::pippo(const DTRecHitCollection::range segsch,
|
567 |
const DTLayer* ch,
|
568 |
const TrajectoryStateOnSurface& extraptsos) {
|
569 |
int nSegsCh=segsch.second-segsch.first;
|
570 |
histo("hHitsLostLayer")->Fill(nSegsCh);
|
571 |
if (nSegsCh) {
|
572 |
LocalPoint extrapPos=extraptsos.localPosition();
|
573 |
double minDist=99999.;
|
574 |
for (DTRecHitCollection::const_iterator hit=segsch.first; hit!=segsch.second;
|
575 |
++hit) {
|
576 |
LocalVector dist = hit->localPosition() - extrapPos;
|
577 |
if (dist.perp()<minDist) minDist=dist.x();
|
578 |
}
|
579 |
histo("hMinDistLayer")->Fill(minDist);
|
580 |
}
|
581 |
}
|
582 |
|
583 |
TH1F* STAOfflineAnalyzer::histo(const string& name) const{
|
584 |
MonitorElement* me = theDQMStore->get(("DT/STAOfflineAnalyzer/"+name).c_str());
|
585 |
if (!me) throw cms::Exception("STAOfflineAnalyzer") << " ME not existing " << name;
|
586 |
TH1F* histo = me->getTH1F();
|
587 |
if (!histo)cms::Exception("STAOfflineAnalyzer") << " Not a TH1F " << name;
|
588 |
return histo;
|
589 |
}
|
590 |
|
591 |
TH2F* STAOfflineAnalyzer::histo2d(const string& name) const{
|
592 |
MonitorElement* me = theDQMStore->get(("DT/STAOfflineAnalyzer/"+name).c_str());
|
593 |
if (!me) throw cms::Exception("STAOfflineAnalyzer") << " ME not existing " << name;
|
594 |
TH2F* histo = me->getTH2F();
|
595 |
if (!histo)cms::Exception("STAOfflineAnalyzer") << " Not a TH2F " << name;
|
596 |
return histo;
|
597 |
}
|
598 |
|
599 |
bool STAOfflineAnalyzer::getLCT(LCTType t) const {
|
600 |
return LCT.test(t);
|
601 |
}
|
602 |
|
603 |
string STAOfflineAnalyzer::toString(const DTLayerId& id) const {
|
604 |
stringstream result;
|
605 |
result << "_Wh" << id.wheel()
|
606 |
<< "_Sec" << id.sector()
|
607 |
<< "_St" << id.station()
|
608 |
<< "_Sl" << id.superLayer()
|
609 |
<< "_Lay" << id.layer();
|
610 |
return result.str();
|
611 |
}
|
612 |
|
613 |
string STAOfflineAnalyzer::toString(const DTSuperLayerId& id) const {
|
614 |
stringstream result;
|
615 |
result << "_Wh" << id.wheel()
|
616 |
<< "_Sec" << id.sector()
|
617 |
<< "_St" << id.station()
|
618 |
<< "_Sl" << id.superLayer();
|
619 |
return result.str();
|
620 |
}
|
621 |
|
622 |
string STAOfflineAnalyzer::toString(const DTChamberId& id) const {
|
623 |
stringstream result;
|
624 |
result << "_Wh" << id.wheel()
|
625 |
<< "_Sec" << id.sector()
|
626 |
<< "_St" << id.station();
|
627 |
return result.str();
|
628 |
}
|
629 |
|
630 |
template<class T> string STAOfflineAnalyzer::hName(const string& s, const T& id) const {
|
631 |
string name(toString(id));
|
632 |
stringstream hName;
|
633 |
hName << s << name;
|
634 |
return hName.str();
|
635 |
}
|
636 |
|
637 |
void STAOfflineAnalyzer::createTH1F(const std::string& name,
|
638 |
const std::string& title,
|
639 |
const std::string& suffix,
|
640 |
int nbin,
|
641 |
const double& binMin,
|
642 |
const double& binMax) const {
|
643 |
stringstream hName;
|
644 |
stringstream hTitle;
|
645 |
hName << name << suffix;
|
646 |
hTitle << title << suffix;
|
647 |
theDQMStore->setCurrentFolder("DT/STAOfflineAnalyzer");
|
648 |
theDQMStore->book1D(hName.str().c_str(), hTitle.str().c_str(), nbin,binMin,binMax);
|
649 |
// TH1F * _h = new TH1F(hName.str().c_str(), hTitle.str().c_str(), nbin,binMin,binMax);
|
650 |
// _h->SetDirectory(theFile); // Needed when the input is a root file
|
651 |
}
|
652 |
|
653 |
void STAOfflineAnalyzer::createTH2F(const std::string& name,
|
654 |
const std::string& title,
|
655 |
const std::string& suffix,
|
656 |
int nBinX,
|
657 |
const double& binXMin,
|
658 |
const double& binXMax,
|
659 |
int nBinY,
|
660 |
const double& binYMin,
|
661 |
const double& binYMax) const {
|
662 |
stringstream hName;
|
663 |
stringstream hTitle;
|
664 |
hName << name << suffix;
|
665 |
hTitle << title << suffix;
|
666 |
theDQMStore->setCurrentFolder("DT/STAOfflineAnalyzer");
|
667 |
theDQMStore->book2D(hName.str().c_str(), hTitle.str().c_str(), nBinX,binXMin,binXMax, nBinY,binYMin,binYMax);
|
668 |
// TH2F * _h = new TH2F(hName.str().c_str(), hTitle.str().c_str(), nBinX,binXMin,binXMax, nBinY,binYMin,binYMax);
|
669 |
// _h->SetDirectory(theFile); // Needed when the input is a root file
|
670 |
|
671 |
}
|
672 |
|