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