CMS 3D CMS Logo

DTSegment2DQuality.cc
Go to the documentation of this file.
1 /*
2  * See header file for a description of this class.
3  *
4  * \author S. Bolognesi and G. Cerminara - INFN Torino
5  */
6 
7 #include <iostream>
8 #include <map>
9 
21 
22 #include "DTSegment2DQuality.h"
23 #include "Histograms.h"
24 
25 using namespace std;
26 using namespace edm;
27 
28 namespace dtsegment2d {
29 struct Histograms {
30  std::unique_ptr<HRes2DHit> h2DHitRPhi;
31  std::unique_ptr<HRes2DHit> h2DHitRZ;
32  std::unique_ptr<HRes2DHit> h2DHitRZ_W0;
33  std::unique_ptr<HRes2DHit> h2DHitRZ_W1;
34  std::unique_ptr<HRes2DHit> h2DHitRZ_W2;
35 
36  std::unique_ptr<HEff2DHit> h2DHitEff_RPhi;
37  std::unique_ptr<HEff2DHit> h2DHitEff_RZ;
38  std::unique_ptr<HEff2DHit> h2DHitEff_RZ_W0;
39  std::unique_ptr<HEff2DHit> h2DHitEff_RZ_W1;
40  std::unique_ptr<HEff2DHit> h2DHitEff_RZ_W2;
41 };
42 }
43 
44 using namespace dtsegment2d;
45 
46 // Constructor
48  // get the debug parameter for verbose output
49  debug_ = pset.getUntrackedParameter<bool>("debug");
50  DTHitQualityUtils::debug = debug_;
51  // the name of the simhit collection
52  simHitLabel_ = pset.getUntrackedParameter<InputTag>("simHitLabel");
53  simHitToken_ = consumes<PSimHitContainer>(pset.getUntrackedParameter<InputTag>("simHitLabel"));
54  // the name of the 2D rec hit collection
55  segment2DLabel_ = pset.getUntrackedParameter<InputTag>("segment2DLabel");
56  segment2DToken_ = consumes<DTRecSegment2DCollection>(pset.getUntrackedParameter<InputTag>("segment2DLabel"));
57 
58  // sigma resolution on position
59  sigmaResPos_ = pset.getParameter<double>("sigmaResPos");
60  // sigma resolution on angle
61  sigmaResAngle_ = pset.getParameter<double>("sigmaResAngle");
62 
63  if (debug_) {
64  cout << "[DTSegment2DQuality] Constructor called " << endl;
65 }
66 }
67 
69  histograms.h2DHitRPhi = std::make_unique<HRes2DHit> ("RPhi", booker, true, true);
70  histograms.h2DHitRZ = std::make_unique<HRes2DHit> ("RZ", booker, true, true);
71  histograms.h2DHitRZ_W0 = std::make_unique<HRes2DHit> ("RZ_W0", booker, true, true);
72  histograms.h2DHitRZ_W1 = std::make_unique<HRes2DHit> ("RZ_W1", booker, true, true);
73  histograms.h2DHitRZ_W2 = std::make_unique<HRes2DHit> ("RZ_W2", booker, true, true);
74 
75  histograms.h2DHitEff_RPhi = std::make_unique<HEff2DHit> ("RPhi", booker);
76  histograms.h2DHitEff_RZ = std::make_unique<HEff2DHit> ("RZ", booker);
77  histograms.h2DHitEff_RZ_W0 = std::make_unique<HEff2DHit> ("RZ_W0", booker);
78  histograms.h2DHitEff_RZ_W1 = std::make_unique<HEff2DHit> ("RZ_W1", booker);
79  histograms.h2DHitEff_RZ_W2 = std::make_unique<HEff2DHit> ("RZ_W2", booker);
80  if (debug_) {
81  cout << "[DTSegment2DQuality] hitsos created " << endl;
82  }
83 }
84 
85 // The real analysis
87  // Get the DT Geometry
88  ESHandle<DTGeometry> dtGeom;
89  setup.get<MuonGeometryRecord>().get(dtGeom);
90 
91  // Get the SimHit collection from the event
93  event.getByToken(simHitToken_, simHits); // FIXME: second string to be removed
94 
95  // Map simHits by sl
96  map<DTSuperLayerId, PSimHitContainer > simHitsPerSl;
97  for (const auto & simHit : *simHits) {
98  // Create the id of the sl (the simHits in the DT known their wireId)
99  DTSuperLayerId slId = ((DTWireId(simHit.detUnitId())).layerId()).superlayerId();
100  // Fill the map
101  simHitsPerSl[slId].push_back(simHit);
102  }
103 
104  // Get the 2D rechits from the event
106  event.getByToken(segment2DToken_, segment2Ds);
107 
108  if (not segment2Ds.isValid()) {
109  if (debug_) { cout << "[DTSegment2DQuality]**Warning: no 2DSegments with label: " << segment2DLabel_
110  << " in this event, skipping !" << endl;
111 }
112  return;
113  }
114 
115  // Loop over all superlayers containing a segment
116  DTRecSegment2DCollection::id_iterator slId;
117  for (slId = segment2Ds->id_begin();
118  slId != segment2Ds->id_end();
119  ++slId) {
120 
121  //------------------------- simHits ---------------------------//
122  // Get simHits of each superlayer
123  PSimHitContainer simHits = simHitsPerSl[(*slId)];
124 
125  // Map simhits per wire
126  map<DTWireId, PSimHitContainer> simHitsPerWire = DTHitQualityUtils::mapSimHitsPerWire(simHits);
127  map<DTWireId, const PSimHit*> muSimHitPerWire = DTHitQualityUtils::mapMuSimHitsPerWire(simHitsPerWire);
128  int nMuSimHit = muSimHitPerWire.size();
129  if (nMuSimHit == 0 or nMuSimHit == 1) {
130  if (debug_ and nMuSimHit == 1) {
131  cout << "[DTSegment2DQuality] Only " << nMuSimHit << " mu SimHit in this SL, skipping !" << endl;
132 }
133  continue; // If no or only one mu SimHit is found skip this SL
134  }
135  if (debug_) {
136  cout << "=== SL " << (*slId) << " has " << nMuSimHit << " SimHits" << endl;
137 }
138 
139  // Find outer and inner mu SimHit to build a segment
140  pair<const PSimHit*, const PSimHit*> inAndOutSimHit = DTHitQualityUtils::findMuSimSegment(muSimHitPerWire);
141  // Check that outermost and innermost SimHit are not the same
142  if (inAndOutSimHit.first == inAndOutSimHit.second ) {
143  cout << "[DTHitQualityUtils]***Warning: outermost and innermost SimHit are the same !" << endl;
144  continue;
145  }
146 
147  // Find direction and position of the sim Segment in SL RF
148  pair<LocalVector, LocalPoint> dirAndPosSimSegm = DTHitQualityUtils::findMuSimSegmentDirAndPos(inAndOutSimHit,
149  (*slId),&(*dtGeom));
150 
151  LocalVector simSegmLocalDir = dirAndPosSimSegm.first;
152  LocalPoint simSegmLocalPos = dirAndPosSimSegm.second;
153  if (debug_) {
154  cout << " Simulated segment: local direction " << simSegmLocalDir << endl
155  << " local position " << simSegmLocalPos << endl;
156 }
157  const DTSuperLayer* superLayer = dtGeom->superLayer(*slId);
158  GlobalPoint simSegmGlobalPos = superLayer->toGlobal(simSegmLocalPos);
159 
160  // Atan(x/z) angle and x position in SL RF
161  float angleSimSeg = DTHitQualityUtils::findSegmentAlphaAndBeta(simSegmLocalDir).first;
162  float posSimSeg = simSegmLocalPos.x();
163  // Position (in eta, phi coordinates) in the global RF
164  float etaSimSeg = simSegmGlobalPos.eta();
165  float phiSimSeg = simSegmGlobalPos.phi();
166 
167  //---------------------------- recHits --------------------------//
168  // Get the range of rechit for the corresponding slId
169  bool recHitFound = false;
170  DTRecSegment2DCollection::range range = segment2Ds->get(*slId);
171  int nsegm = distance(range.first, range.second);
172  if (debug_) {
173  cout << " Sl: " << *slId << " has " << nsegm
174  << " 2D segments" << endl;
175 }
176 
177  if (nsegm != 0) {
178  // Find the best RecHit: look for the 2D RecHit with the angle closest
179  // to that of segment made of SimHits.
180  // RecHits must have delta alpha and delta position within 5 sigma of
181  // the residual distribution (we are looking for residuals of segments
182  // usefull to the track fit) for efficency purpose
183  const DTRecSegment2D* bestRecHit = nullptr;
184  bool bestRecHitFound = false;
185  double deltaAlpha = 99999;
186 
187  // Loop over the recHits of this slId
188  for (DTRecSegment2DCollection::const_iterator segment2D = range.first;
189  segment2D != range.second;
190  ++segment2D) {
191  // Check the dimension
192  if ((*segment2D).dimension() != 2) {
193  if (debug_) { cout << "[DTSegment2DQuality]***Error: This is not 2D segment !!!" << endl;
194 }
195  abort();
196  }
197  // Segment Local Direction and position (in SL RF)
198  LocalVector recSegDirection = (*segment2D).localDirection();
199  LocalPoint recSegPosition = (*segment2D).localPosition();
200 
201  float recSegAlpha = DTHitQualityUtils::findSegmentAlphaAndBeta(recSegDirection).first;
202  if (debug_) {
203  cout << " RecSegment direction: " << recSegDirection << endl
204  << " position : " << recSegPosition << endl
205  << " alpha : " << recSegAlpha << endl;
206 }
207 
208  if (fabs(recSegAlpha - angleSimSeg) < deltaAlpha) {
209  deltaAlpha = fabs(recSegAlpha - angleSimSeg);
210  bestRecHit = &(*segment2D);
211  bestRecHitFound = true;
212  }
213  } // End of Loop over all 2D RecHits
214 
215  if (bestRecHitFound) {
216  // Best rechit direction and position in SL RF
217  LocalPoint bestRecHitLocalPos = bestRecHit->localPosition();
218  LocalVector bestRecHitLocalDir = bestRecHit->localDirection();
219 
220  LocalError bestRecHitLocalPosErr = bestRecHit->localPositionError();
221  LocalError bestRecHitLocalDirErr = bestRecHit->localDirectionError();
222 
223  float angleBestRHit = DTHitQualityUtils::findSegmentAlphaAndBeta(bestRecHitLocalDir).first;
224 
225  if (fabs(angleBestRHit - angleSimSeg) < 5*sigmaResAngle_ and
226  fabs(bestRecHitLocalPos.x() - posSimSeg) < 5*sigmaResPos_) {
227  recHitFound = true;
228  }
229 
230  // Fill Residual histos
231  HRes2DHit *hRes = nullptr;
232  if ((*slId).superlayer() == 1 or (*slId).superlayer() == 3) { // RPhi SL
233  hRes = histograms.h2DHitRPhi.get();
234  } else if ((*slId).superlayer() == 2) { // RZ SL
235  histograms.h2DHitRZ->fill(angleSimSeg,
236  angleBestRHit,
237  posSimSeg,
238  bestRecHitLocalPos.x(),
239  etaSimSeg,
240  phiSimSeg,
241  sqrt(bestRecHitLocalPosErr.xx()),
242  sqrt(bestRecHitLocalDirErr.xx())
243  );
244  if (abs((*slId).wheel()) == 0) {
245  hRes = histograms.h2DHitRZ_W0.get();
246  } else if (abs((*slId).wheel()) == 1) {
247  hRes = histograms.h2DHitRZ_W1.get();
248  } else if (abs((*slId).wheel()) == 2) {
249  hRes = histograms.h2DHitRZ_W2.get();
250 }
251  }
252  hRes->fill(angleSimSeg,
253  angleBestRHit,
254  posSimSeg,
255  bestRecHitLocalPos.x(),
256  etaSimSeg,
257  phiSimSeg,
258  sqrt(bestRecHitLocalPosErr.xx()),
259  sqrt(bestRecHitLocalDirErr.xx())
260  );
261  }
262  } // end of if (nsegm != 0)
263 
264  // Fill Efficiency plot
265  HEff2DHit *hEff = nullptr;
266  if ((*slId).superlayer() == 1 or (*slId).superlayer() == 3) { // RPhi SL
267  hEff = histograms.h2DHitEff_RPhi.get();
268  } else if ((*slId).superlayer() == 2) { // RZ SL
269  histograms.h2DHitEff_RZ->fill(etaSimSeg, phiSimSeg, posSimSeg, angleSimSeg, recHitFound);
270  if (abs((*slId).wheel()) == 0) {
271  hEff = histograms.h2DHitEff_RZ_W0.get();
272  } else if (abs((*slId).wheel()) == 1) {
273  hEff = histograms.h2DHitEff_RZ_W1.get();
274  } else if (abs((*slId).wheel()) == 2) {
275  hEff = histograms.h2DHitEff_RZ_W2.get();
276  }
277  }
278  hEff->fill(etaSimSeg, phiSimSeg, posSimSeg, angleSimSeg, recHitFound);
279  } // End of loop over superlayers
280 }
281 
282 // declare this as a framework plugin
std::pair< double, double > findSegmentAlphaAndBeta(const LocalVector &direction)
LocalError localPositionError() const override
local position error in SL frame
T getParameter(std::string const &) const
void fill(float angleSimSegment, float angleRecSegment, float posSimSegment, float posRecSegment, float etaSimSegment, float phiSimSegment, float sigmaPos, float sigmaAngle)
Definition: Histograms.h:245
T getUntrackedParameter(std::string const &, T const &) const
float xx() const
Definition: LocalError.h:24
std::pair< const_iterator, const_iterator > range
iterator range
Definition: RangeMap.h:50
std::map< DTWireId, const PSimHit * > mapMuSimHitsPerWire(const std::map< DTWireId, edm::PSimHitContainer > &simHitWireMap)
Create a map between the Mu SimHits and corresponding MuBarWireId ;.
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:54
void fill(float etaSimSegm, float phiSimSegm, float posSimSegm, float angleSimSegm, bool fillRecHit)
Definition: Histograms.h:309
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
def setup(process, global_tag, zero_tesla=False)
Definition: GeneralSetup.py:1
DTSegment2DQuality(const edm::ParameterSet &pset)
Constructor.
std::atomic< bool > debug
std::unique_ptr< HRes2DHit > h2DHitRZ_W2
std::map< DTWireId, edm::PSimHitContainer > mapSimHitsPerWire(const edm::PSimHitContainer &simhits)
T sqrt(T t)
Definition: SSEVec.h:18
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
void bookHistograms(DQMStore::ConcurrentBooker &, edm::Run const &, edm::EventSetup const &, dtsegment2d::Histograms &) const override
Book the DQM plots.
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::unique_ptr< HEff2DHit > h2DHitEff_RZ_W1
bool isValid() const
Definition: HandleBase.h:74
LocalPoint localPosition() const override
local position in SL frame
std::unique_ptr< HRes2DHit > h2DHitRZ_W0
std::unique_ptr< HEff2DHit > h2DHitEff_RZ_W0
std::unique_ptr< HEff2DHit > h2DHitEff_RPhi
std::unique_ptr< HRes2DHit > h2DHitRPhi
std::pair< LocalVector, LocalPoint > findMuSimSegmentDirAndPos(const std::pair< const PSimHit *, const PSimHit * > &inAndOutSimHit, const DetId detId, const DTGeometry *muonGeom)
Find direction and position of a segment (in local RF) from outer and inner mu SimHit in the RF of ob...
T eta() const
Definition: PV3DBase.h:76
HLT enums.
std::pair< const PSimHit *, const PSimHit * > findMuSimSegment(const std::map< DTWireId, const PSimHit * > &mapWireAndMuSimHit)
Find Innermost and outermost SimHit from Mu in a SL (they identify a simulated segment) ...
LocalVector localDirection() const override
the local direction in SL frame
T get() const
Definition: EventSetup.h:63
std::unique_ptr< HRes2DHit > h2DHitRZ_W1
std::vector< PSimHit > PSimHitContainer
void dqmAnalyze(edm::Event const &, edm::EventSetup const &, dtsegment2d::Histograms const &) const override
Perform the real analysis.
LocalError localDirectionError() const override
the local direction error (xx,xy,yy) in SL frame: only xx is not 0.
std::unique_ptr< HEff2DHit > h2DHitEff_RZ
T x() const
Definition: PV3DBase.h:62
Definition: event.py:1
Definition: Run.h:44
const DTSuperLayer * superLayer(const DTSuperLayerId &id) const
Return a DTSuperLayer given its id.
Definition: DTGeometry.cc:104
std::unique_ptr< HEff2DHit > h2DHitEff_RZ_W2
std::unique_ptr< HRes2DHit > h2DHitRZ