CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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==0) {
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 != 0) {
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 == 0) {
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
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
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:7
std::vector< const TMax * > getTMax(const DTWireId &idWire)
Definition: DTTMax.cc:325
void bookHistos()
Definition: Histogram.h:33
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
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 analyze(const edm::Event &event, const edm::EventSetup &eventSetup)
void Write()
Definition: vDriftHistos.h:358
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
#define LogTrace(id)
virtual ~DTVDriftCalibration()
Destructor.
std::vector< DTRecHit1D > specificRecHits() const
Access to specific components.
DTSuperLayerId superLayerId() const
The id of the superlayer on which reside the segment.
virtual LocalPoint localPosition() const
local position in SL frame
void Fill(float tmax123, float tmax124, float tmax134, float tmax234, dttmaxenums::SigmaFactor s124, dttmaxenums::SigmaFactor s134, unsigned t0_123, unsigned t0_124, unsigned t0_134, unsigned t0_234, unsigned hSubGroup)
Definition: vDriftHistos.h:220
#define N
Definition: blowfish.cc:9
DTSegmentSelector select_
DTMeanTimerFitter * theFitter
const T & get() const
Definition: EventSetup.h:56
const CalibConsts * getConsts(DTWireId wireId) const
DTLayerId layerId() const
Return the corresponding LayerId.
Definition: DTWireId.h:62
int sector() const
Definition: DTChamberId.h:61
DTVDriftCalibration(const edm::ParameterSet &pset)
Constructor.
virtual LocalVector localDirection() const
the local direction in SL frame
tuple cout
Definition: gather_cfg.py:145
std::vector< dttmaxenums::TMaxCells > addedCells
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
const DTSuperLayer * superLayer(DTSuperLayerId id) const
Return the superlayer corresponding to the given id.
Definition: DTChamber.cc:65