CMS 3D CMS Logo

DTVDriftCalibration.cc
Go to the documentation of this file.
1 
2 /*
3  * See header file for a description of this class.
4  *
5  * \author M. Giunta
6  */
7 
11 
15 
18 
21 
24 
27 
28 /* C++ Headers */
29 #include <map>
30 #include <iostream>
31 #include <fstream>
32 #include <string>
33 #include <sstream>
34 #include "TFile.h"
35 #include "TH1.h"
36 #include "TF1.h"
37 #include "TROOT.h"
38 
39 // Declare histograms.
40 TH1F * hChi2;
41 extern void bookHistos();
42 
43 using namespace std;
44 using namespace edm;
45 using namespace dttmaxenums;
46 
47 
49 
50  // The name of the 4D rec hits collection
51  theRecHits4DLabel = pset.getParameter<InputTag>("recHits4DLabel");
52 
53  // The root file which will contain the histos
54  string rootFileName = pset.getUntrackedParameter<string>("rootFileName");
55  theFile = new TFile(rootFileName.c_str(), "RECREATE");
56  theFile->cd();
57 
58  debug = pset.getUntrackedParameter<bool>("debug", false);
59 
60  theFitter = new DTMeanTimerFitter(theFile);
61  if(debug)
62  theFitter->setVerbosity(1);
63 
64  hChi2 = new TH1F("hChi2","Chi squared tracks",100,0,100);
65  h2DSegmRPhi = new h2DSegm("SLRPhi");
66  h2DSegmRZ = new h2DSegm("SLRZ");
67  h4DSegmAllCh = new h4DSegm("AllCh");
68  bookHistos();
69 
70  findVDriftAndT0 = pset.getUntrackedParameter<bool>("fitAndWrite", false);
71 
72  // Chamber/s to calibrate
73  theCalibChamber = pset.getUntrackedParameter<string>("calibChamber", "All");
74 
75  // the txt file which will contain the calibrated constants
76  theVDriftOutputFile = pset.getUntrackedParameter<string>("vDriftFileName");
77 
78  // Get the synchronizer
79  theSync = DTTTrigSyncFactory::get()->create(pset.getParameter<string>("tTrigMode"),
80  pset.getParameter<ParameterSet>("tTrigModeConfig"));
81 
82  // get parameter set for DTCalibrationMap constructor
83  theCalibFilePar = pset.getUntrackedParameter<ParameterSet>("calibFileConfig");
84 
85  // the granularity to be used for tMax
86  string tMaxGranularity = pset.getUntrackedParameter<string>("tMaxGranularity","bySL");
87 
88  // Enforce it to be by SL since rest is not implemented
89  if(tMaxGranularity != "bySL"){
90  LogError("Calibration") << "[DTVDriftCalibration] tMaxGranularity will be fixed to bySL.";
91  tMaxGranularity = "bySL";
92  }
93  // Initialize correctly the enum which specify the granularity for the calibration
94  if(tMaxGranularity == "bySL") {
96  } else if(tMaxGranularity == "byChamber"){
98  } else if(tMaxGranularity== "byPartition") {
100  } else throw cms::Exception("Configuration") << "[DTVDriftCalibration] Check parameter tMaxGranularity: "
101  << tMaxGranularity << " option not available";
102 
103 
104  LogVerbatim("Calibration") << "[DTVDriftCalibration]Constructor called!";
105 }
106 
108  theFile->Close();
109  delete theFitter;
110  LogVerbatim("Calibration") << "[DTVDriftCalibration]Destructor called!";
111 }
112 
113 void DTVDriftCalibration::analyze(const Event & event, const EventSetup& eventSetup) {
114  LogTrace("Calibration") << "--- [DTVDriftCalibration] Event analysed #Run: " << event.id().run()
115  << " #Event: " << event.id().event();
116  theFile->cd();
117  DTChamberId chosenChamberId;
118 
119  if(theCalibChamber != "All") {
120  stringstream linestr;
121  int selWheel, selStation, selSector;
122  linestr << theCalibChamber;
123  linestr >> selWheel >> selStation >> selSector;
124  chosenChamberId = DTChamberId(selWheel, selStation, selSector);
125  LogTrace("Calibration") << "chosen chamber " << chosenChamberId;
126  }
127 
128  // Get the DT Geometry
129  ESHandle<DTGeometry> dtGeom;
130  eventSetup.get<MuonGeometryRecord>().get(dtGeom);
131 
132  // Get the rechit collection from the event
133  Handle<DTRecSegment4DCollection> all4DSegments;
134  event.getByLabel(theRecHits4DLabel, all4DSegments);
135 
136  // Get the map of noisy channels
137  /*ESHandle<DTStatusFlag> statusMap;
138  if(checkNoisyChannels) {
139  eventSetup.get<DTStatusFlagRcd>().get(statusMap);
140  }*/
141 
142  // Set the event setup in the Synchronizer
143  theSync->setES(eventSetup);
144 
145  // Loop over segments by chamber
146  DTRecSegment4DCollection::id_iterator chamberIdIt;
147  for (chamberIdIt = all4DSegments->id_begin();
148  chamberIdIt != all4DSegments->id_end();
149  ++chamberIdIt){
150 
151  // Get the chamber from the setup
152  const DTChamber* chamber = dtGeom->chamber(*chamberIdIt);
153  LogTrace("Calibration") << "Chamber Id: " << *chamberIdIt;
154 
155  // Calibrate just the chosen chamber/s
156  if((theCalibChamber != "All") && ((*chamberIdIt) != chosenChamberId))
157  continue;
158 
159  // Get the range for the corresponding ChamberId
160  DTRecSegment4DCollection::range range = all4DSegments->get((*chamberIdIt));
161 
162  // Loop over the rechits of this DetUnit
163  for (DTRecSegment4DCollection::const_iterator segment = range.first;
164  segment!=range.second; ++segment){
165 
166  if( !(*segment).hasZed() && !(*segment).hasPhi() ){
167  LogError("Calibration") << "4D segment without Z and Phi segments";
168  continue;
169  }
170 
171  LogTrace("Calibration") << "Segment local pos (in chamber RF): " << (*segment).localPosition()
172  << "\nSegment global pos: " << chamber->toGlobal((*segment).localPosition());
173 
174  if( !select_(*segment, event, eventSetup) ) continue;
175 
176  LocalPoint phiSeg2DPosInCham;
177  LocalVector phiSeg2DDirInCham;
178  map<DTSuperLayerId,vector<DTRecHit1D> > hitsBySLMap;
179  if((*segment).hasPhi()){
180  const DTChamberRecSegment2D* phiSeg = (*segment).phiSegment(); // phiSeg lives in the chamber RF
181  phiSeg2DPosInCham = phiSeg->localPosition();
182  phiSeg2DDirInCham = phiSeg->localDirection();
183  vector<DTRecHit1D> phiHits = phiSeg->specificRecHits();
184  for(vector<DTRecHit1D>::const_iterator hit = phiHits.begin();
185  hit != phiHits.end(); ++hit) {
186  DTWireId wireId = (*hit).wireId();
187  DTSuperLayerId slId = wireId.superlayerId();
188  hitsBySLMap[slId].push_back(*hit);
189  }
190  }
191  // Get the Theta 2D segment and plot the angle in the chamber RF
192  LocalVector zSeg2DDirInCham;
193  LocalPoint zSeg2DPosInCham;
194  if((*segment).hasZed()) {
195  const DTSLRecSegment2D* zSeg = (*segment).zSegment(); // zSeg lives in the SL RF
196  const DTSuperLayer* sl = chamber->superLayer(zSeg->superLayerId());
197  zSeg2DPosInCham = chamber->toLocal(sl->toGlobal((*zSeg).localPosition()));
198  zSeg2DDirInCham = chamber->toLocal(sl->toGlobal((*zSeg).localDirection()));
199  hitsBySLMap[zSeg->superLayerId()] = zSeg->specificRecHits();
200  }
201 
202  LocalPoint segment4DLocalPos = (*segment).localPosition();
203  LocalVector segment4DLocalDir = (*segment).localDirection();
204  double chiSquare = ((*segment).chi2()/(*segment).degreesOfFreedom());
205 
206  hChi2->Fill(chiSquare);
207  if((*segment).hasPhi())
208  h2DSegmRPhi->Fill(phiSeg2DPosInCham.x(), phiSeg2DDirInCham.x()/phiSeg2DDirInCham.z());
209  if((*segment).hasZed())
210  h2DSegmRZ->Fill(zSeg2DPosInCham.y(), zSeg2DDirInCham.y()/zSeg2DDirInCham.z());
211 
212  if((*segment).hasZed() && (*segment).hasPhi())
213  h4DSegmAllCh->Fill(segment4DLocalPos.x(),
214  segment4DLocalPos.y(),
215  atan(segment4DLocalDir.x()/segment4DLocalDir.z())*180./Geom::pi(),
216  atan(segment4DLocalDir.y()/segment4DLocalDir.z())*180./Geom::pi(),
217  180 - segment4DLocalDir.theta()*180./Geom::pi());
218  else if((*segment).hasPhi())
219  h4DSegmAllCh->Fill(segment4DLocalPos.x(),
220  atan(segment4DLocalDir.x()/segment4DLocalDir.z())*180./Geom::pi());
221  else if((*segment).hasZed())
222  LogWarning("Calibration") << "4d segment with only Z";
223 
224  //loop over the segments
225  for(map<DTSuperLayerId,vector<DTRecHit1D> >::const_iterator slIdAndHits = hitsBySLMap.begin(); slIdAndHits != hitsBySLMap.end(); ++slIdAndHits) {
226  if (slIdAndHits->second.size() < 3) continue;
227  DTSuperLayerId slId = slIdAndHits->first;
228 
229  // Create the DTTMax, that computes the 4 TMax
230  DTTMax slSeg(slIdAndHits->second, *(chamber->superLayer(slIdAndHits->first)),chamber->toGlobal((*segment).localDirection()), chamber->toGlobal((*segment).localPosition()), theSync);
231 
232  if(theGranularity == bySL) {
233  vector<const TMax*> tMaxes = slSeg.getTMax(slId);
234  DTWireId wireId(slId, 0, 0);
235  theFile->cd();
236  cellInfo* cell = theWireIdAndCellMap[wireId];
237  if (cell==nullptr) {
238  TString name = (((((TString) "TMax"+(long) slId.wheel()) +(long) slId.station())
239  +(long) slId.sector())+(long) slId.superLayer());
240  cell = new cellInfo(name);
241  theWireIdAndCellMap[wireId] = cell;
242  }
243  cell->add(tMaxes);
244  cell->update(); // FIXME to reset the counter to avoid triple counting, which actually is not used...
245  }
246  else {
247  LogWarning("Calibration") << "[DTVDriftCalibration] ###Warning: the chosen granularity is not implemented yet, only bySL available!";
248  }
249  // to be implemented: granularity different from bySL
250 
251  // else if (theGranularity == byPartition) {
252  // // Use the custom granularity defined by partition();
253  // // in this case, add() should be called once for each Tmax of each layer
254  // // and triple counting should be avoided within add()
255  // vector<cellInfo*> cells;
256  // for (int i=1; i<=4; i++) {
257  // const DTTMax::InfoLayer* iLayer = slSeg.getInfoLayer(i);
258  // if(iLayer == 0) continue;
259  // cellInfo * cell = partition(iLayer->idWire);
260  // cells.push_back(cell);
261  // vector<const TMax*> tMaxes = slSeg.getTMax(iLayer->idWire);
262  // cell->add(tMaxes);
263  // }
264  // //reset the counter to avoid triple counting
265  // for (vector<cellInfo*>::const_iterator i = cells.begin();
266  // i!= cells.end(); i++) {
267  // (*i)->update();
268  // }
269  // }
270  }
271  }
272  }
273 }
274 
276  theFile->cd();
277  gROOT->GetList()->Write();
278  h2DSegmRPhi->Write();
279  h2DSegmRZ->Write();
280  h4DSegmAllCh->Write();
281  hChi2->Write();
282  // Instantiate a DTCalibrationMap object if you want to calculate the calibration constants
283  DTCalibrationMap calibValuesFile(theCalibFilePar);
284  // Create the object to be written to DB
285  DTMtime* mTime = new DTMtime();
286 
287  // write the TMax histograms of each SL to the root file
288  if(theGranularity == bySL) {
289  for(map<DTWireId, cellInfo*>::const_iterator wireCell = theWireIdAndCellMap.begin();
290  wireCell != theWireIdAndCellMap.end(); ++wireCell) {
291  cellInfo* cell= theWireIdAndCellMap[(*wireCell).first];
292  hTMaxCell* cellHists = cell->getHists();
293  theFile->cd();
294  cellHists->Write();
295  if(findVDriftAndT0) { // if TRUE: evaluate calibration constants from TMax hists filled in this job
296  // evaluate v_drift and sigma from the TMax histograms
297  DTWireId wireId = (*wireCell).first;
298  vector<float> newConstants;
299  TString N=(((((TString) "TMax"+(long) wireId.wheel()) +(long) wireId.station())
300  +(long) wireId.sector())+(long) wireId.superLayer());
301  vector<float> vDriftAndReso = theFitter->evaluateVDriftAndReso(N);
302 
303  // Don't write the constants for the SL if the vdrift was not computed
304  if(vDriftAndReso.front() == -1)
305  continue;
306  const DTCalibrationMap::CalibConsts* oldConstants = calibValuesFile.getConsts(wireId);
307  if(oldConstants != nullptr) {
308  newConstants.push_back((*oldConstants)[0]);
309  newConstants.push_back((*oldConstants)[1]);
310  newConstants.push_back((*oldConstants)[2]);
311  } else {
312  newConstants.push_back(-1);
313  newConstants.push_back(-1);
314  newConstants.push_back(-1);
315  }
316  for(int ivd=0; ivd<=5;ivd++) {
317  // 0=vdrift, 1=reso, 2=(3deltat0-2deltat0), 3=(2deltat0-1deltat0),
318  // 4=(1deltat0-0deltat0), 5=deltat0 from hists with max entries,
319  newConstants.push_back(vDriftAndReso[ivd]);
320  }
321 
322  calibValuesFile.addCell(calibValuesFile.getKey(wireId), newConstants);
323 
324  // vdrift is cm/ns , resolution is cm
325  mTime->set((wireId.layerId()).superlayerId(),
326  vDriftAndReso[0],
327  vDriftAndReso[1],
329  LogTrace("Calibration") << " SL: " << (wireId.layerId()).superlayerId()
330  << " vDrift = " << vDriftAndReso[0]
331  << " reso = " << vDriftAndReso[1];
332  }
333  }
334  }
335 
336  // to be implemented: granularity different from bySL
337 
338  // if(theGranularity == "byChamber") {
339  // const vector<DTChamber*> chambers = dMap.chambers();
340 
341  // // Loop over all chambers
342  // for(vector<MuBarChamber*>::const_iterator chamber = chambers.begin();
343  // chamber != chambers.end(); chamber ++) {
344  // MuBarChamberId chamber_id = (*chamber)->id();
345  // MuBarDigiParameters::Key wire_id(chamber_id, 0, 0, 0);
346  // vector<float> newConstants;
347  // vector<float> vDriftAndReso = evaluateVDriftAndReso(wire_id, f);
348  // const CalibConsts* oldConstants = digiParams.getConsts(wire_id);
349  // if(oldConstants !=0) {
350  // newConstants = *oldConstants;
351  // newConstants.push_back(vDriftAndReso[0]);
352  // newConstants.push_back(vDriftAndReso[1]);
353  // newConstants.push_back(vDriftAndReso[2]);
354  // newConstants.push_back(vDriftAndReso[3]);
355  // } else {
356  // newConstants.push_back(-1);
357  // newConstants.push_back(-1);
358  // newConstants.push_back(vDriftAndReso[0]);
359  // newConstants.push_back(vDriftAndReso[1]);
360  // newConstants.push_back(vDriftAndReso[2]);
361  // newConstants.push_back(vDriftAndReso[3]);
362  // }
363  // digiParams.addCell(wire_id, newConstants);
364  // }
365  // }
366 
367  // Write values to a table
368  calibValuesFile.writeConsts(theVDriftOutputFile);
369 
370  LogVerbatim("Calibration") << "[DTVDriftCalibration]Writing vdrift object to DB!";
371 
372  // Write the vdrift object to DB
373  string record = "DTMtimeRcd";
374  DTCalibDBUtils::writeToDB<DTMtime>(record, mTime);
375 }
376 
377 // to be implemented: granularity different from bySL
378 
379 // // Create partitions
380 // DTVDriftCalibration::cellInfo* DTVDriftCalibration::partition(const DTWireId& wireId) {
381 // for( map<MuBarWireId, cellInfo*>::const_iterator iter =
382 // mapCellTmaxPart.begin(); iter != mapCellTmaxPart.end(); iter++) {
383 // // Divide wires per SL (with phi symmetry)
384 // if(iter->first.wheel() == wireId.wheel() &&
385 // iter->first.station() == wireId.station() &&
386 // // iter->first.sector() == wireId.sector() && // phi symmetry!
387 // iter->first.superlayer() == wireId.superlayer()) {
388 // return iter->second;
389 // }
390 // }
391 // cellInfo * result = new cellInfo("dummy string"); // FIXME: change constructor; create tree?
392 // mapCellTmaxPart.insert(make_pair(wireId, result));
393 // return result;
394 //}
395 
396 
397 void DTVDriftCalibration::cellInfo::add(const vector<const TMax*>& _tMaxes) {
398  vector<const TMax*> tMaxes = _tMaxes;
399  float tmax123 = -1.;
400  float tmax124 = -1.;
401  float tmax134 = -1.;
402  float tmax234 = -1.;
403  SigmaFactor s124 = noR;
404  SigmaFactor s134 = noR;
405  unsigned t0_123 = 0;
406  unsigned t0_124 = 0;
407  unsigned t0_134 = 0;
408  unsigned t0_234 = 0;
409  unsigned hSubGroup = 0;
410  for (vector<const TMax*>::const_iterator it=tMaxes.begin(); it!=tMaxes.end();
411  ++it) {
412  if(*it == nullptr) {
413  continue;
414  }
415  else {
416  //FIXME check cached,
417  if (addedCells.size()==4 ||
418  find(addedCells.begin(), addedCells.end(), (*it)->cells)
419  != addedCells.end()) {
420  continue;
421  }
422  addedCells.push_back((*it)->cells);
423  SigmaFactor sigma = (*it)->sigma;
424  float t = (*it)->t;
425  TMaxCells cells = (*it)->cells;
426  unsigned t0Factor = (*it)->t0Factor;
427  hSubGroup = (*it)->hSubGroup;
428  if(t < 0.) continue;
429  switch(cells) {
430  case notInit : cout << "Error: no cell type assigned to TMax" << endl; break;
431  case c123 : tmax123 =t; t0_123 = t0Factor; break;
432  case c124 : tmax124 =t; s124 = sigma; t0_124 = t0Factor; break;
433  case c134 : tmax134 =t; s134 = sigma; t0_134 = t0Factor; break;
434  case c234 : tmax234 =t; t0_234 = t0Factor; break;
435  }
436  }
437  }
438  //add entries to the TMax histograms
439  histos->Fill(tmax123, tmax124, tmax134, tmax234, s124, s134, t0_123,
440  t0_124, t0_134, t0_234, hSubGroup);
441 }
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
const DTSuperLayer * superLayer(const DTSuperLayerId &id) const
Return the superlayer corresponding to the given id.
Definition: DTChamber.cc:65
Key getKey(DTWireId wireId) const
void writeConsts(const std::string &outputFileName) const
std::pair< const_iterator, const_iterator > range
iterator range
Definition: RangeMap.h:50
TMaxGranularity theGranularity
const DTChamber * chamber(const DTChamberId &id) const
Return a DTChamber given its id.
Definition: DTGeometry.cc:99
JetCorrectorParameters::Record record
Definition: classes.h:7
int set(int wheelId, int stationId, int sectorId, int slId, float mTime, float mTrms, DTTimeUnits::type unit)
Definition: DTMtime.cc:250
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:54
Definition: DTTMax.h:32
T y() const
Definition: PV3DBase.h:63
void Fill(float x, float y, float phi, float theta, float impact)
Definition: vDriftHistos.h:42
LocalPoint toLocal(const GlobalPoint &gp) const
Conversion to the R.F. of the GeomDet.
Definition: GeomDet.h:69
void Fill(float pos, float localAngle)
Definition: vDriftHistos.h:97
void Write()
Definition: vDriftHistos.h:103
DTSuperLayerId superlayerId() const
Return the corresponding SuperLayerId.
Definition: DTLayerId.h:59
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
std::vector< const TMax * > getTMax(const DTWireId &idWire)
Definition: DTTMax.cc:325
Geom::Theta< T > theta() const
Definition: PV3DBase.h:75
virtual void setES(const edm::EventSetup &setup)=0
Pass the Event Setup to the synchronization module at each event.
std::map< DTWireId, cellInfo * > theWireIdAndCellMap
void bookHistos()
Definition: Histogram.h:33
edm::ParameterSet theCalibFilePar
T z() const
Definition: PV3DBase.h:64
std::vector< float > CalibConsts
int superLayer() const
Return the superlayer number.
void addCell(Key wireId, const CalibConsts &calibConst)
void add(const std::vector< const TMax * > &tMaxes)
TH1F * hChi2
void Write()
Definition: vDriftHistos.h:358
#define LogTrace(id)
std::vector< DTRecHit1D > specificRecHits() const
Access to specific components.
DTSuperLayerId superLayerId() const
The id of the superlayer on which reside the segment.
#define N
Definition: blowfish.cc:9
LocalPoint localPosition() const override
local position in SL frame
~DTVDriftCalibration() override
Destructor.
DTSegmentSelector select_
DTMeanTimerFitter * theFitter
void analyze(const edm::Event &event, const edm::EventSetup &eventSetup) override
const CalibConsts * getConsts(DTWireId wireId) const
DTLayerId layerId() const
Return the corresponding LayerId.
Definition: DTWireId.h:62
HLT enums.
int sector() const
Definition: DTChamberId.h:61
LocalVector localDirection() const override
the local direction in SL frame
T get() const
Definition: EventSetup.h:63
DTVDriftCalibration(const edm::ParameterSet &pset)
Constructor.
constexpr double pi()
Definition: Pi.h:31
int station() const
Return the station number.
Definition: DTChamberId.h:51
int wheel() const
Return the wheel number.
Definition: DTChamberId.h:45
DTTTrigBaseSync * theSync
T x() const
Definition: PV3DBase.h:62
std::vector< float > evaluateVDriftAndReso(const TString &N)
Fit the TMax histos and evaluate VDrift and resolution.
edm::InputTag theRecHits4DLabel
T get(const Candidate &c)
Definition: component.h:55
void Write()
Definition: vDriftHistos.h:53
Definition: event.py:1