CMS 3D CMS Logo

List of all members | Public Member Functions | Private Member Functions | Private Attributes
DTT0Calibration Class Reference

#include <DTT0Calibration.h>

Inheritance diagram for DTT0Calibration:
edm::one::EDAnalyzer<> edm::one::EDAnalyzerBase edm::EDConsumerBase

Public Member Functions

void analyze (const edm::Event &event, const edm::EventSetup &eventSetup) override
 Fill the maps with t0 (by channel) More...
 
 DTT0Calibration (const edm::ParameterSet &pset)
 Constructor. More...
 
void endJob () override
 Compute the mean and the RMS of the t0 from the maps and write them to the DB with channel granularity. More...
 
 ~DTT0Calibration () override
 Destructor. More...
 
- Public Member Functions inherited from edm::one::EDAnalyzer<>
 EDAnalyzer ()=default
 
SerialTaskQueueglobalLuminosityBlocksQueue () final
 
SerialTaskQueueglobalRunsQueue () final
 
bool wantsGlobalLuminosityBlocks () const final
 
bool wantsGlobalRuns () const final
 
- Public Member Functions inherited from edm::one::EDAnalyzerBase
void callWhenNewProductsRegistered (std::function< void(BranchDescription const &)> const &func)
 
 EDAnalyzerBase ()
 
ModuleDescription const & moduleDescription () const
 
bool wantsStreamLuminosityBlocks () const
 
bool wantsStreamRuns () const
 
 ~EDAnalyzerBase () override
 
- Public Member Functions inherited from edm::EDConsumerBase
std::vector< ConsumesInfoconsumesInfo () const
 
void convertCurrentProcessAlias (std::string const &processName)
 Convert "@currentProcess" in InputTag process names to the actual current process name. More...
 
 EDConsumerBase ()
 
 EDConsumerBase (EDConsumerBase const &)=delete
 
 EDConsumerBase (EDConsumerBase &&)=default
 
ESProxyIndex const * esGetTokenIndices (edm::Transition iTrans) const
 
ProductResolverIndexAndSkipBit indexFrom (EDGetToken, BranchType, TypeID const &) const
 
void itemsMayGet (BranchType, std::vector< ProductResolverIndexAndSkipBit > &) const
 
void itemsToGet (BranchType, std::vector< ProductResolverIndexAndSkipBit > &) const
 
std::vector< ProductResolverIndexAndSkipBit > const & itemsToGetFrom (BranchType iType) const
 
void labelsForToken (EDGetToken iToken, Labels &oLabels) const
 
void modulesWhoseProductsAreConsumed (std::vector< ModuleDescription const * > &modules, ProductRegistry const &preg, std::map< std::string, ModuleDescription const * > const &labelsToDesc, std::string const &processName) const
 
EDConsumerBase const & operator= (EDConsumerBase const &)=delete
 
EDConsumerBaseoperator= (EDConsumerBase &&)=default
 
bool registeredToConsume (ProductResolverIndex, bool, BranchType) const
 
bool registeredToConsumeMany (TypeID const &, BranchType) const
 
ProductResolverIndexAndSkipBit uncheckedIndexFrom (EDGetToken) const
 
void updateLookup (BranchType iBranchType, ProductResolverIndexHelper const &, bool iPrefetchMayGet)
 
void updateLookup (eventsetup::ESRecordsToProxyIndices const &)
 
virtual ~EDConsumerBase () noexcept(false)
 

Private Member Functions

std::string getHistoName (const DTWireId &wId) const
 
std::string getHistoName (const DTLayerId &lId) const
 

Private Attributes

bool debug
 
edm::EDGetTokenT< DTDigiCollectiondigiToken
 
edm::ESHandle< DTGeometrydtGeom
 
unsigned int eventsForLayerT0
 
unsigned int eventsForWireT0
 
TH1D hLayerPeaks
 
std::vector< DTLayerIdlayerIdWithWireHistos
 
std::map< DTWireId, double > mK
 
std::map< DTWireId, double > mK_ref
 
std::map< DTWireId, int > nDigiPerWire
 
std::map< DTWireId, int > nDigiPerWire_ref
 
unsigned int nevents
 
std::map< DTWireId, double > qK
 
unsigned int rejectDigiFromPeak
 
int selSector
 
int selWheel
 
TSpectrum spectrum
 
std::map< DTWireId, double > theAbsoluteT0PerWire
 
std::string theCalibSector
 
std::string theCalibWheel
 
std::map< DTChamberId, int > theCountT0ByChamber
 
TFile theFile
 
std::map< DTLayerId, TH1I > theHistoLayerMap
 
std::map< DTWireId, TH1I > theHistoWireMap
 
std::map< DTChamberId, double > theMeanT0ByChamber
 
std::map< DTChamberId, double > theRefT0ByChamber
 
std::map< DTWireId, double > theRelativeT0PerWire
 
std::map< DTChamberId, double > theSigmaT0ByChamber
 
std::map< std::string, double > theSigmaT0LayerMap
 
std::map< DTWireId, double > theSigmaT0PerWire
 
std::map< DTChamberId, double > theSumT0ByChamber
 
std::map< std::string, double > theT0LayerMap
 
std::map< DTLayerId, double > theTPPeakMap
 
double tpPeakWidth
 
double tpPeakWidthPerLayer
 
std::vector< DTWireIdwireIdWithHistos
 

Additional Inherited Members

- Public Types inherited from edm::one::EDAnalyzerBase
typedef EDAnalyzerBase ModuleType
 
- Public Types inherited from edm::EDConsumerBase
typedef ProductLabels Labels
 
- Static Public Member Functions inherited from edm::one::EDAnalyzerBase
static const std::string & baseType ()
 
static void fillDescriptions (ConfigurationDescriptions &descriptions)
 
static void prevalidate (ConfigurationDescriptions &descriptions)
 
- Protected Member Functions inherited from edm::EDConsumerBase
template<typename ProductType , BranchType B = InEvent>
EDGetTokenT< ProductType > consumes (edm::InputTag const &tag)
 
EDGetToken consumes (const TypeToGet &id, edm::InputTag const &tag)
 
template<BranchType B>
EDGetToken consumes (TypeToGet const &id, edm::InputTag const &tag)
 
ConsumesCollector consumesCollector ()
 Use a ConsumesCollector to gather consumes information from helper functions. More...
 
template<typename ProductType , BranchType B = InEvent>
void consumesMany ()
 
void consumesMany (const TypeToGet &id)
 
template<BranchType B>
void consumesMany (const TypeToGet &id)
 
template<typename ESProduct , typename ESRecord , Transition Tr = Transition::Event>
auto esConsumes ()
 
template<typename ESProduct , typename ESRecord , Transition Tr = Transition::Event>
auto esConsumes (ESInputTag const &tag)
 
template<typename ProductType , BranchType B = InEvent>
EDGetTokenT< ProductType > mayConsume (edm::InputTag const &tag)
 
EDGetToken mayConsume (const TypeToGet &id, edm::InputTag const &tag)
 
template<BranchType B>
EDGetToken mayConsume (const TypeToGet &id, edm::InputTag const &tag)
 

Detailed Description

Analyzer class computes the mean and RMS of t0 from pulses. Those values are written in the DB with cell granularity. The mean value for each channel is normalized to a reference time common to all the sector. The t0 of wires in odd layers are corrected for the relative difference between odd and even layers

Author
S. Bolognesi - INFN Torino

Definition at line 36 of file DTT0Calibration.h.

Constructor & Destructor Documentation

DTT0Calibration::DTT0Calibration ( const edm::ParameterSet pset)

Constructor.

Definition at line 34 of file DTT0Calibration.cc.

References gather_cfg::cout, debug, edm::ParameterSet::getUntrackedParameter(), selSector, selWheel, relativeConstraints::station, theCalibSector, theCalibWheel, makeMuonMisalignmentScenario::wheel, and wireIdWithHistos.

34  :
35  debug(pset.getUntrackedParameter<bool>("debug")),
36  digiToken(consumes<DTDigiCollection>(pset.getUntrackedParameter<string>("digiLabel"))),
37  theFile(pset.getUntrackedParameter<string>("rootFileName", "DTT0PerLayer.root").c_str(), "RECREATE"),
38  nevents(0),
39  eventsForLayerT0(pset.getParameter<unsigned int>("eventsForLayerT0")),
40  eventsForWireT0(pset.getParameter<unsigned int>("eventsForWireT0")),
41  tpPeakWidth(pset.getParameter<double>("tpPeakWidth")),
42  tpPeakWidthPerLayer(pset.getParameter<double>("tpPeakWidthPerLayer")),
43  rejectDigiFromPeak(pset.getParameter<unsigned int>("rejectDigiFromPeak")),
44  hLayerPeaks("hLayerPeaks", "", 3000, 0, 3000),
45  spectrum(20)
46 
47 {
48  // Get the debug parameter for verbose output
49  if(debug)
50  cout << "[DTT0Calibration]Constructor called!" << endl;
51 
52  theCalibWheel = pset.getUntrackedParameter<string>("calibWheel", "All"); //FIXME amke a vector of integer instead of a string
53  if(theCalibWheel != "All") {
54  stringstream linestr;
55  int selWheel;
56  linestr << theCalibWheel;
57  linestr >> selWheel;
58  cout << "[DTT0CalibrationPerLayer] chosen wheel " << selWheel << endl;
59  }
60 
61  // Sector/s to calibrate
62  theCalibSector = pset.getUntrackedParameter<string>("calibSector", "All"); //FIXME amke a vector of integer instead of a string
63  if(theCalibSector != "All") {
64  stringstream linestr;
65  int selSector;
66  linestr << theCalibSector;
67  linestr >> selSector;
68  cout << "[DTT0CalibrationPerLayer] chosen sector " << selSector << endl;
69  }
70 
71  vector<string> defaultCell;
72  const auto& cellsWithHistos = pset.getUntrackedParameter<vector<string> >("cellsWithHisto", defaultCell);
73  for(const auto& cell : cellsWithHistos){
74  stringstream linestr;
75  int wheel, sector, station, sl, layer, wire;
76  linestr << cell;
77  linestr >> wheel >> sector >> station >> sl >> layer >> wire;
78  wireIdWithHistos.push_back(DTWireId(wheel, station, sector, sl, layer, wire));
79  }
80 }
T getParameter(std::string const &) const
double tpPeakWidthPerLayer
T getUntrackedParameter(std::string const &, T const &) const
unsigned int nevents
std::vector< DTWireId > wireIdWithHistos
std::string theCalibWheel
unsigned int eventsForLayerT0
unsigned int rejectDigiFromPeak
std::string theCalibSector
edm::EDGetTokenT< DTDigiCollection > digiToken
TSpectrum spectrum
unsigned int eventsForWireT0
DTT0Calibration::~DTT0Calibration ( )
override

Destructor.

Definition at line 83 of file DTT0Calibration.cc.

References gather_cfg::cout, debug, and theFile.

83  {
84  if(debug)
85  cout << "[DTT0Calibration]Destructor called!" << endl;
86 
87  theFile.Close();
88 }

Member Function Documentation

void DTT0Calibration::analyze ( const edm::Event event,
const edm::EventSetup eventSetup 
)
override

Fill the maps with t0 (by channel)

Perform the real analysis.

Definition at line 91 of file DTT0Calibration.cc.

References funct::abs(), DTSuperLayerId::chamberId(), gather_cfg::cout, debug, digiToken, dtGeom, eventsForLayerT0, eventsForWireT0, spr::find(), edm::EventSetup::get(), getHistoName(), create_public_lumi_plots::hist, hLayerPeaks, layerIdWithWireHistos, mK, mK_ref, nDigiPerWire, nDigiPerWire_ref, nevents, or, qK, rejectDigiFromPeak, DTChamberId::sector(), selSector, selWheel, spectrum, DTLayerId::superlayerId(), genVertex_cff::t0, theAbsoluteT0PerWire, theCalibSector, theCalibWheel, theHistoLayerMap, theHistoWireMap, theTPPeakMap, tpPeakWidth, tpPeakWidthPerLayer, DTChamberId::wheel(), and wireIdWithHistos.

91  {
92  nevents++;
93 
94  // Get the digis from the event
96  event.getByToken(digiToken, digis);
97 
98  // Get the DT Geometry
99  if (nevents == 1)
100  eventSetup.get<MuonGeometryRecord>().get(dtGeom);
101 
102  // Iterate through all digi collections ordered by LayerId
103  for (const auto& digis_per_layer : *digis)
104  {
105  //std::cout << __LINE__ << std::endl;
106  // Get the iterators over the digis associated with this LayerId
107  const DTDigiCollection::Range& digiRange = digis_per_layer.second;
108 
109  // Get the layerId
110  const DTLayerId layerId = digis_per_layer.first;
111  //const DTChamberId chamberId = layerId.superlayerId().chamberId();
112 
113  if((theCalibWheel != "All") && (layerId.superlayerId().chamberId().wheel() != selWheel))
114  continue;
115  if((theCalibSector != "All") && (layerId.superlayerId().chamberId().sector() != selSector))
116  continue;
117 
118  // Loop over all digis in the given layer
119  for (DTDigiCollection::const_iterator digi = digiRange.first;
120  digi != digiRange.second;
121  ++digi)
122  {
123  const double t0 = digi->countsTDC();
124  const DTWireId wireIdtmp(layerId, (*digi).wire());
125 
126  // Use first bunch of events to fill t0 per layer
127  if(nevents <= eventsForLayerT0){
128  // If it doesn't exist, book it
129  if(not theHistoLayerMap.count(layerId)){
130  theHistoLayerMap[layerId] = TH1I(getHistoName(layerId).c_str(),
131  "T0 from pulses by layer (TDC counts, 1 TDC count = 0.781 ns)",
132  3000,
133  0,
134  3000
135  );
136  if(debug)
137  cout << " New T0 per Layer Histo: " << theHistoLayerMap[layerId].GetName() << endl;
138  }
139  theHistoLayerMap[layerId].Fill(t0);
140  }
141 
142  // Use all the remaining events to compute t0 per wire
144  // Get the wireId
145  const DTWireId wireId(layerId, (*digi).wire());
146  if(debug) {
147  cout << " Wire: " << wireId << endl
148  << " time (TDC counts): " << (*digi).countsTDC()<< endl;
149  }
150 
151  //Fill the histos per wire for the chosen cells
153  std::find(wireIdWithHistos.begin(),wireIdWithHistos.end(),wireId) != wireIdWithHistos.end())
154  {
155  //If it doesn't exist, book it
156  if(theHistoWireMap.count(wireId) == 0){
157  theHistoWireMap[wireId] = TH1I(getHistoName(wireId).c_str(),
158  "T0 from pulses by wire (TDC counts, 1 TDC count = 0.781 ns)",
159  7000,
160  0,
161  7000
162  );
163  if(debug)
164  cout << " New T0 per wire Histo: " << theHistoWireMap[wireId].GetName() << endl;
165  }
166  theHistoWireMap[wireId].Fill(t0);
167  }
168 
169  //Select per layer
170  if(fabs(theTPPeakMap[layerId] - t0) > rejectDigiFromPeak){
171  if(debug)
172  cout<<"digi skipped because t0 too far from peak " << theTPPeakMap[layerId] << endl;
173  continue;
174  }
175 
176  //Use second bunch of events to compute a t0 reference per wire
178  if(!nDigiPerWire_ref[wireId]){
179  mK_ref[wireId] = 0;
180  }
181  nDigiPerWire_ref[wireId] = nDigiPerWire_ref[wireId] + 1;
182  mK_ref[wireId] = mK_ref[wireId] + (t0-mK_ref[wireId])/nDigiPerWire_ref[wireId];
183  }
184  //Use last all the remaining events to compute the mean and sigma t0 per wire
186  if(abs(t0-mK_ref[wireId]) > tpPeakWidth)
187  continue;
188  if(!nDigiPerWire[wireId]){
189  theAbsoluteT0PerWire[wireId] = 0;
190  qK[wireId] = 0;
191  mK[wireId] = 0;
192  }
193  nDigiPerWire[wireId] = nDigiPerWire[wireId] + 1;
194  theAbsoluteT0PerWire[wireId] = theAbsoluteT0PerWire[wireId] + t0;
195  qK[wireId] = qK[wireId] + ((nDigiPerWire[wireId]-1)*(t0-mK[wireId])*(t0-mK[wireId])/nDigiPerWire[wireId]);
196  mK[wireId] = mK[wireId] + (t0-mK[wireId])/nDigiPerWire[wireId];
197  }
198  }//end if(nevents>1000)
199  }//end loop on digi
200  }//end loop on layer
201 
202  //Use the t0 per layer histos to have an indication about the t0 position
203  if(nevents == eventsForLayerT0){
204  for(const auto& lHisto : theHistoLayerMap)
205  {
206  const auto& layerId = lHisto.first;
207  const auto& hist = lHisto.second;
208  if(debug)
209  cout << "Reading histogram " << hist.GetName() << " with mean " << hist.GetMean() << " and RMS " << hist.GetRMS() << endl;
210 
211  //Find peaks
212  int npeaks = spectrum.Search(&hist, (tpPeakWidthPerLayer / 2.), "", 0.3);
213 
214  double *peaks = spectrum.GetPositionX();
215  //Put in a std::vector<float>
216  vector<double> peakMeans(peaks, peaks + npeaks);
217  //Sort the peaks in ascending order
218  sort(peakMeans.begin(), peakMeans.end());
219 
220  if (peakMeans.empty())
221  {
222  theTPPeakMap[layerId] = hist.GetMaximumBin();
223  std::cout << "No peaks found by peakfinder in layer " << layerId << ". Taking maximum bin at " << theTPPeakMap[layerId] << ". Please check!" << std::endl;
224  layerIdWithWireHistos.push_back(layerId);
225  }
226  else if (fabs(hist.GetXaxis()->FindBin(peakMeans.front()) - hist.GetXaxis()->FindBin(peakMeans.back())) < rejectDigiFromPeak)
227  {
228  theTPPeakMap[layerId] = peakMeans[peakMeans.size() / 2];
229  }
230  else
231  {
232  bool peak_set = false;
233  for (const auto& peak : peakMeans)
234  {
235  // Skip if at low edge
236  if (peak - tpPeakWidthPerLayer <= 0)
237  continue;
238  // Get integral of peak
239  double sum = 0;
240  for (int ibin=peak - tpPeakWidthPerLayer; ibin<peak + tpPeakWidthPerLayer; ibin++)
241  {
242  sum += hist.GetBinContent(ibin);
243  }
244  // Skip if peak too small
245  if (sum < hist.GetMaximum() / 2)
246  continue;
247 
248  // Passed all cuts
249  theTPPeakMap[layerId] = peak;
250  peak_set = true;
251  break;
252  }
253  if (peak_set)
254  {
255  std::cout << "Peaks to far away from each other in layer " << layerId << ". Maybe cross talk? Taking first good peak at " << theTPPeakMap[layerId] << ". Please check!" << std::endl;
256  layerIdWithWireHistos.push_back(layerId);
257  }
258  else
259  {
260  theTPPeakMap[layerId] = hist.GetMaximumBin();
261  std::cout << "Peaks to far away from each other in layer " << layerId << " and no good peak found. Taking maximum bin at " << theTPPeakMap[layerId] << ". Please check!" << std::endl;
262  layerIdWithWireHistos.push_back(layerId);
263  }
264  }
265  if (peakMeans.size() > 5)
266  {
267  std::cout << "Found more than 5 peaks in layer " << layerId << ". Please check!" << std::endl;
268  if (std::find(layerIdWithWireHistos.begin(), layerIdWithWireHistos.end(), layerId) == layerIdWithWireHistos.end())
269  layerIdWithWireHistos.push_back(layerId);
270  }
271  // Check for noise
272  int nspikes = 0;
273  for (int ibin=0; ibin<hist.GetNbinsX(); ibin++)
274  {
275  if (hist.GetBinContent(ibin + 1) > hist.GetMaximum() * 0.001)
276  nspikes++;
277  }
278  if (nspikes > 50)
279  {
280  std::cout << "Found a lot of (>50) small spikes in layer " << layerId << ". Please check if all wires are functioning as expected!" << std::endl;
281  if (std::find(layerIdWithWireHistos.begin(), layerIdWithWireHistos.end(), layerId) == layerIdWithWireHistos.end())
282  layerIdWithWireHistos.push_back(layerId);
283  }
284  hLayerPeaks.Fill(theTPPeakMap[layerId]);
285  }
286  }
287 }
std::vector< DTLayerId > layerIdWithWireHistos
double tpPeakWidthPerLayer
std::map< DTLayerId, TH1I > theHistoLayerMap
unsigned int nevents
std::map< DTWireId, double > theAbsoluteT0PerWire
DTChamberId chamberId() const
Return the corresponding ChamberId.
std::map< DTLayerId, double > theTPPeakMap
std::map< DTWireId, int > nDigiPerWire
std::vector< DTWireId > wireIdWithHistos
std::string theCalibWheel
std::string getHistoName(const DTWireId &wId) const
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
edm::ESHandle< DTGeometry > dtGeom
std::map< DTWireId, double > mK
unsigned int eventsForLayerT0
unsigned int rejectDigiFromPeak
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
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::string theCalibSector
std::map< DTWireId, double > qK
edm::EDGetTokenT< DTDigiCollection > digiToken
std::map< DTWireId, double > mK_ref
std::map< DTWireId, TH1I > theHistoWireMap
std::vector< DigiType >::const_iterator const_iterator
int sector() const
Definition: DTChamberId.h:61
T get() const
Definition: EventSetup.h:71
std::pair< const_iterator, const_iterator > Range
int wheel() const
Return the wheel number.
Definition: DTChamberId.h:45
TSpectrum spectrum
unsigned int eventsForWireT0
std::map< DTWireId, int > nDigiPerWire_ref
void DTT0Calibration::endJob ( void  )
overridevirtual

Compute the mean and the RMS of the t0 from the maps and write them to the DB with channel granularity.

Write the t0 map into DB

Reimplemented from edm::one::EDAnalyzerBase.

Definition at line 289 of file DTT0Calibration.cc.

References funct::abs(), DTTimeUnits::counts, gather_cfg::cout, debug, dtGeom, plotBeamSpotDB::first, hLayerPeaks, SiStripPI::mean, nDigiPerWire, nevents, funct::pow(), qK, edm::second(), DTT0::set(), mathSSE::sqrt(), DTGeometry::superLayers(), genVertex_cff::t0, theAbsoluteT0PerWire, theFile, theHistoLayerMap, theHistoWireMap, theRelativeT0PerWire, theSigmaT0PerWire, relativeConstraints::value, MuonErrorMatrixValues_cff::values, and DTCalibDBUtils::writeToDB().

Referenced by o2olib.O2ORunMgr::executeJob().

289  {
290 
291  std::cout << "Analyzed " << nevents << " events" << std::endl;
292 
293  DTT0* t0sWRTChamber = new DTT0();
294 
295  if(debug)
296  cout << "[DTT0CalibrationPerLayer]Writing histos to file!" << endl;
297 
298  theFile.cd();
299  //hT0SectorHisto->Write();
300  hLayerPeaks.Write();
301  for(const auto& wHisto : theHistoWireMap){
302  wHisto.second.Write();
303  }
304  for(const auto& lHisto : theHistoLayerMap ) {
305  lHisto.second.Write();
306  }
307 
308  if(debug)
309  cout << "[DTT0Calibration] Compute and store t0 and sigma per wire" << endl;
310 
311  // Calculate uncertainties per wire (counting experiment)
312  for (auto& wiret0 : theAbsoluteT0PerWire)
313  {
314  auto& wireId = wiret0.first;
315  if (nDigiPerWire[wireId] > 1 )
316  theSigmaT0PerWire[wireId] = qK[wireId] / (nDigiPerWire[wireId] - 1);
317  else
318  theSigmaT0PerWire[wireId] = 999.; // Only one measurement: uncertainty -> infinity
319  // syst uncert
320  //theSigmaT0PerWire[wireId] += pow(0.5, 2));
321  // Every time the same measurement. Use Laplace estimator as estimation how propable it is to measure another value due to limited size of sample
322  if (theSigmaT0PerWire[wireId] == 0)
323  {
324  theSigmaT0PerWire[wireId] += pow(1. / (nDigiPerWire[wireId] + 1), 2);
325  }
326  }
327 
328  // function to calculate unweighted means
329  auto unweighted_mean_function = [] (const std::list<double>& values, const std::list<double>& sigmas)
330  {
331  double mean = 0;
332  for (auto& value : values)
333  {
334  mean += value;
335  }
336  mean /= values.size();
337 
338  double uncertainty = 0;
339  for (auto& value : values)
340  {
341  uncertainty += pow(value - mean, 2);
342  }
343  uncertainty /= values.size();
344  uncertainty = sqrt(uncertainty);
345  return std::make_pair(mean, uncertainty);
346  };
347 
348  // correct for odd-even effect in each super layer
349  std::map<DTSuperLayerId, std::pair<double, double> > mean_sigma_even;
350  std::map<DTSuperLayerId, std::pair<double, double> > mean_sigma_odd;
351  for (const auto& superlayer : dtGeom->superLayers())
352  {
353  const auto superlayer_id = superlayer->id();
354  std::list<double> values_even;
355  std::list<double> sigmas_even;
356  std::list<double> values_odd;
357  std::list<double> sigmas_odd;
358 
359  for (const auto& wiret0 : theAbsoluteT0PerWire)
360  {
361  const auto& wireId = wiret0.first;
362  if (wireId.layerId().superlayerId() == superlayer_id)
363  {
364  const auto& t0 = wiret0.second / nDigiPerWire[wireId];
365  if (wireId.layerId().layer() % 2)
366  {
367  values_odd.push_back(t0);
368  sigmas_odd.push_back(sqrt(theSigmaT0PerWire[wireId]));
369  }
370  else
371  {
372  values_even.push_back(t0);
373  sigmas_even.push_back(sqrt(theSigmaT0PerWire[wireId]));
374  }
375  }
376  }
377  // get mean and uncertainty
378  mean_sigma_even.emplace(superlayer_id, unweighted_mean_function(values_even, sigmas_even));
379  mean_sigma_odd.emplace(superlayer_id, unweighted_mean_function(values_odd, sigmas_odd));
380  }
381 
382  // filter outliers
383  for (const auto& superlayer : dtGeom->superLayers())
384  {
385  const auto superlayer_id = superlayer->id();
386  std::list<double> values_even;
387  std::list<double> sigmas_even;
388  std::list<double> values_odd;
389  std::list<double> sigmas_odd;
390 
391  for (const auto& wiret0 : theAbsoluteT0PerWire)
392  {
393  const auto& wireId = wiret0.first;
394  if (wireId.layerId().superlayerId() == superlayer_id)
395  {
396  const auto& t0 = wiret0.second / nDigiPerWire[wireId];
397  if (wireId.layerId().layer() % 2 and abs(t0 - mean_sigma_odd[superlayer_id].first) < 2 * mean_sigma_odd[superlayer_id].second)
398  {
399  values_odd.push_back(t0);
400  sigmas_odd.push_back(sqrt(theSigmaT0PerWire[wireId]));
401  }
402  else
403  {
404  if (abs(t0 - mean_sigma_even[superlayer_id].first) < 2 * mean_sigma_even[superlayer_id].second)
405  {
406  values_even.push_back(t0);
407  sigmas_even.push_back(sqrt(theSigmaT0PerWire[wireId]));
408  }
409  }
410  }
411  }
412  // get mean and uncertainty
413  mean_sigma_even[superlayer_id] = unweighted_mean_function(values_even, sigmas_even);
414  mean_sigma_odd[superlayer_id] = unweighted_mean_function(values_odd, sigmas_odd);
415  }
416 
417  // apply correction
418  for (auto& wiret0 : theAbsoluteT0PerWire)
419  {
420  const auto& wire_id = wiret0.first;
421  const auto& superlayer_id = wiret0.first.layerId().superlayerId();
422  const auto& layer = wiret0.first.layerId().layer();
423  auto& t0 = wiret0.second;
424  t0 /= nDigiPerWire[wire_id];
425  if (not layer % 2)
426  continue;
427  // t0 is reference. Changing it changes the map
428  t0 += mean_sigma_even[superlayer_id].first - mean_sigma_odd[superlayer_id].first;
429  theSigmaT0PerWire[wire_id] += pow(mean_sigma_odd[superlayer_id].second, 2) + pow(mean_sigma_even[superlayer_id].second, 2);
430  }
431 
432  // get chamber mean
433  std::map<DTChamberId, std::list<double> > values_per_chamber;
434  std::map<DTChamberId, std::list<double> > sigmas_per_chamber;
435  for (const auto& wire_t0 : theAbsoluteT0PerWire)
436  {
437  const auto& wire_id = wire_t0.first;
438  const auto& chamber_id = wire_id.chamberId();
439  const auto& t0 = wire_t0.second;
440  values_per_chamber[chamber_id].push_back(t0);
441  sigmas_per_chamber[chamber_id].push_back(sqrt(theSigmaT0PerWire[wire_id]));
442  }
443 
444  std::map<DTChamberId, std::pair<double, double> > mean_per_chamber;
445  for (const auto& chamber_mean : values_per_chamber)
446  {
447  const auto& chamber_id = chamber_mean.first;
448  const auto& means = chamber_mean.second;
449  const auto& sigmas = sigmas_per_chamber[chamber_id];
450  mean_per_chamber.emplace(chamber_id, unweighted_mean_function(means, sigmas));
451  }
452 
453  // calculate relative values
454  for (const auto& wire_t0 : theAbsoluteT0PerWire)
455  {
456  const auto& wire_id = wire_t0.first;
457  const auto& chamber_id = wire_id.chamberId();
458  const auto& t0 = wire_t0.second;
459  theRelativeT0PerWire.emplace(wire_id, t0 - mean_per_chamber[chamber_id].first);
460  cout << "[DTT0Calibration] Wire " << wire_id << " has t0 "<< theRelativeT0PerWire[wire_id] << " (relative, after even-odd layer corrections) "
461  << " sigma "<< sqrt(theSigmaT0PerWire[wire_id]) <<endl;
462  }
463 
464  for(const auto& wire_t0 : theRelativeT0PerWire)
465  {
466  const auto& wire_id = wire_t0.first;
467  const auto& t0 = wire_t0.second;
468  t0sWRTChamber->set(wire_id,
469  t0,
470  sqrt(theSigmaT0PerWire[wire_id]),
472  );
473  }
474 
476  if(debug)
477  cout << "[DTT0Calibration]Writing values in DB!" << endl;
478  // FIXME: to be read from cfg?
479  string t0Record = "DTT0Rcd";
480  // Write the t0 map to DB
481  DTCalibDBUtils::writeToDB(t0Record, t0sWRTChamber);
482  delete t0sWRTChamber;
483 }
int set(int wheelId, int stationId, int sectorId, int slId, int layerId, int cellId, float t0mean, float t0rms, DTTimeUnits::type unit)
Definition: DTT0.cc:140
std::map< DTLayerId, TH1I > theHistoLayerMap
unsigned int nevents
std::map< DTWireId, double > theAbsoluteT0PerWire
std::map< DTWireId, int > nDigiPerWire
std::map< DTWireId, double > theSigmaT0PerWire
edm::ESHandle< DTGeometry > dtGeom
U second(std::pair< T, U > const &p)
Definition: DTT0.h:53
std::map< DTWireId, double > theRelativeT0PerWire
T sqrt(T t)
Definition: SSEVec.h:18
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::map< DTWireId, double > qK
Definition: value.py:1
std::map< DTWireId, TH1I > theHistoWireMap
static void writeToDB(std::string record, T *payload)
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
const std::vector< const DTSuperLayer * > & superLayers() const
Return a vector of all SuperLayer.
Definition: DTGeometry.cc:107
string DTT0Calibration::getHistoName ( const DTWireId wId) const
private

Definition at line 485 of file DTT0Calibration.cc.

References DTLayerId::layer(), DTChamberId::sector(), DTChamberId::station(), DTSuperLayerId::superlayer(), DTChamberId::wheel(), and DTWireId::wire().

Referenced by analyze().

485  {
486  string histoName;
487  stringstream theStream;
488  theStream << "Ch_" << wId.wheel() << "_" << wId.station() << "_" << wId.sector()
489  << "_SL" << wId.superlayer() << "_L" << wId.layer() << "_W"<< wId.wire() <<"_hT0Histo";
490  theStream >> histoName;
491  return histoName;
492 }
int layer() const
Return the layer number.
Definition: DTLayerId.h:53
int wire() const
Return the wire number.
Definition: DTWireId.h:56
int superlayer() const
Return the superlayer number (deprecated method name)
int sector() const
Definition: DTChamberId.h:61
int station() const
Return the station number.
Definition: DTChamberId.h:51
int wheel() const
Return the wheel number.
Definition: DTChamberId.h:45
string DTT0Calibration::getHistoName ( const DTLayerId lId) const
private

Definition at line 494 of file DTT0Calibration.cc.

References DTLayerId::layer(), DTChamberId::sector(), DTChamberId::station(), DTSuperLayerId::superlayer(), and DTChamberId::wheel().

494  {
495  string histoName;
496  stringstream theStream;
497  theStream << "Ch_" << lId.wheel() << "_" << lId.station() << "_" << lId.sector()
498  << "_SL" << lId.superlayer() << "_L" << lId.layer() <<"_hT0Histo";
499  theStream >> histoName;
500  return histoName;
501 }
int layer() const
Return the layer number.
Definition: DTLayerId.h:53
int superlayer() const
Return the superlayer number (deprecated method name)
int sector() const
Definition: DTChamberId.h:61
int station() const
Return the station number.
Definition: DTChamberId.h:51
int wheel() const
Return the wheel number.
Definition: DTChamberId.h:45

Member Data Documentation

bool DTT0Calibration::debug
private
edm::EDGetTokenT<DTDigiCollection> DTT0Calibration::digiToken
private

Definition at line 64 of file DTT0Calibration.h.

Referenced by analyze().

edm::ESHandle<DTGeometry> DTT0Calibration::dtGeom
private

Definition at line 126 of file DTT0Calibration.h.

Referenced by analyze(), and endJob().

unsigned int DTT0Calibration::eventsForLayerT0
private

Definition at line 72 of file DTT0Calibration.h.

Referenced by analyze().

unsigned int DTT0Calibration::eventsForWireT0
private

Definition at line 74 of file DTT0Calibration.h.

Referenced by analyze().

TH1D DTT0Calibration::hLayerPeaks
private

Definition at line 95 of file DTT0Calibration.h.

Referenced by analyze(), and endJob().

std::vector<DTLayerId> DTT0Calibration::layerIdWithWireHistos
private

Definition at line 101 of file DTT0Calibration.h.

Referenced by analyze().

std::map<DTWireId,double> DTT0Calibration::mK
private

Definition at line 109 of file DTT0Calibration.h.

Referenced by analyze().

std::map<DTWireId,double> DTT0Calibration::mK_ref
private

Definition at line 110 of file DTT0Calibration.h.

Referenced by analyze().

std::map<DTWireId,int> DTT0Calibration::nDigiPerWire
private

Definition at line 107 of file DTT0Calibration.h.

Referenced by analyze(), and endJob().

std::map<DTWireId,int> DTT0Calibration::nDigiPerWire_ref
private

Definition at line 108 of file DTT0Calibration.h.

Referenced by analyze().

unsigned int DTT0Calibration::nevents
private

Definition at line 70 of file DTT0Calibration.h.

Referenced by analyze(), and endJob().

std::map<DTWireId,double> DTT0Calibration::qK
private

Definition at line 111 of file DTT0Calibration.h.

Referenced by analyze(), and endJob().

unsigned int DTT0Calibration::rejectDigiFromPeak
private

Definition at line 83 of file DTT0Calibration.h.

Referenced by analyze().

int DTT0Calibration::selSector
private

Definition at line 89 of file DTT0Calibration.h.

Referenced by analyze(), and DTT0Calibration().

int DTT0Calibration::selWheel
private

Definition at line 87 of file DTT0Calibration.h.

Referenced by analyze(), and DTT0Calibration().

TSpectrum DTT0Calibration::spectrum
private

Definition at line 97 of file DTT0Calibration.h.

Referenced by analyze().

std::map<DTWireId,double> DTT0Calibration::theAbsoluteT0PerWire
private

Definition at line 104 of file DTT0Calibration.h.

Referenced by analyze(), and endJob().

std::string DTT0Calibration::theCalibSector
private

Definition at line 88 of file DTT0Calibration.h.

Referenced by analyze(), and DTT0Calibration().

std::string DTT0Calibration::theCalibWheel
private

Definition at line 86 of file DTT0Calibration.h.

Referenced by analyze(), and DTT0Calibration().

std::map<DTChamberId,int> DTT0Calibration::theCountT0ByChamber
private

Definition at line 120 of file DTT0Calibration.h.

TFile DTT0Calibration::theFile
private

Definition at line 67 of file DTT0Calibration.h.

Referenced by endJob(), and ~DTT0Calibration().

std::map<DTLayerId, TH1I> DTT0Calibration::theHistoLayerMap
private

Definition at line 92 of file DTT0Calibration.h.

Referenced by analyze(), and endJob().

std::map<DTWireId,TH1I> DTT0Calibration::theHistoWireMap
private

Definition at line 113 of file DTT0Calibration.h.

Referenced by analyze(), and endJob().

std::map<DTChamberId,double> DTT0Calibration::theMeanT0ByChamber
private

Definition at line 122 of file DTT0Calibration.h.

std::map<DTChamberId,double> DTT0Calibration::theRefT0ByChamber
private

Definition at line 123 of file DTT0Calibration.h.

std::map<DTWireId,double> DTT0Calibration::theRelativeT0PerWire
private

Definition at line 105 of file DTT0Calibration.h.

Referenced by endJob().

std::map<DTChamberId,double> DTT0Calibration::theSigmaT0ByChamber
private

Definition at line 121 of file DTT0Calibration.h.

std::map<std::string,double> DTT0Calibration::theSigmaT0LayerMap
private

Definition at line 116 of file DTT0Calibration.h.

std::map<DTWireId,double> DTT0Calibration::theSigmaT0PerWire
private

Definition at line 106 of file DTT0Calibration.h.

Referenced by endJob().

std::map<DTChamberId,double> DTT0Calibration::theSumT0ByChamber
private

Definition at line 119 of file DTT0Calibration.h.

std::map<std::string,double> DTT0Calibration::theT0LayerMap
private

Definition at line 115 of file DTT0Calibration.h.

std::map<DTLayerId,double> DTT0Calibration::theTPPeakMap
private

Definition at line 117 of file DTT0Calibration.h.

Referenced by analyze().

double DTT0Calibration::tpPeakWidth
private

Definition at line 77 of file DTT0Calibration.h.

Referenced by analyze().

double DTT0Calibration::tpPeakWidthPerLayer
private

Definition at line 80 of file DTT0Calibration.h.

Referenced by analyze().

std::vector<DTWireId> DTT0Calibration::wireIdWithHistos
private

Definition at line 100 of file DTT0Calibration.h.

Referenced by analyze(), and DTT0Calibration().