CMS 3D CMS Logo

TrackerOfflineValidation.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: TrackerOfflineValidation
4 // Class: TrackerOfflineValidation
5 //
13 //
14 // Original Author: Erik Butz
15 // Created: Tue Dec 11 14:03:05 CET 2007
16 // $Id: TrackerOfflineValidation.cc,v 1.55 2012/09/28 20:48:06 flucke Exp $
17 //
18 //
19 
20 // system include files
21 #include <memory>
22 #include <map>
23 #include <sstream>
24 #include <cmath>
25 #include <tuple>
26 #include <utility>
27 #include <vector>
28 #include <iostream>
29 
30 // ROOT includes
31 #include "TH1.h"
32 #include "TH2.h"
33 #include "TProfile.h"
34 #include "TFile.h"
35 #include "TTree.h"
36 #include "TF1.h"
37 #include "TMath.h"
38 
39 // user include files
49 
55 
58 
63 
66 
72 
75 
76 //
77 // class declaration
78 //
80 public:
82  ~TrackerOfflineValidation() override;
83 
85  YResidual, /*NormYResidual, */
89 
90 private:
91 
92  struct ModuleHistos{
93  ModuleHistos() : ResHisto(), NormResHisto(), ResYHisto(), /*NormResYHisto(),*/
98  LocalX(), LocalY() {}
99  TH1* ResHisto;
101  TH1* ResYHisto;
102  /* TH1* NormResYHisto; */
107 
108  TProfile* ResXvsXProfile;
109  TProfile* ResXvsYProfile;
110  TProfile* ResYvsXProfile;
111  TProfile* ResYvsYProfile;
112 
113  TH1* LocalX;
114  TH1* LocalY;
115  };
116 
117  // container struct to organize collection of histograms during endJob
119  SummaryContainer() : sumXResiduals_(), summaryXResiduals_(),
120  sumNormXResiduals_(), summaryNormXResiduals_(),
121  sumYResiduals_(), summaryYResiduals_(),
122  sumNormYResiduals_(), summaryNormYResiduals_(),
123  sumResXvsXProfile_(), sumResXvsYProfile_(),
124  sumResYvsXProfile_(), sumResYvsYProfile_() {}
125 
134 
139  };
140 
141 
143  DirectoryWrapper(const DirectoryWrapper& upDir,const std::string& newDir,
144  const std::string& basedir,bool useDqmMode)
145  : tfd(nullptr),
146  dqmMode(useDqmMode),
147  theDbe(nullptr) {
148  if (newDir.length()!=0){
149  if(upDir.directoryString.length()!=0)directoryString=upDir.directoryString+"/"+newDir;
150  else directoryString = newDir;
151  }
152  else
153  directoryString=upDir.directoryString;
154 
155  if (!dqmMode){
156  if (newDir.length()==0) tfd.reset(&(*upDir.tfd));
157  else
158  tfd.reset(new TFileDirectory(upDir.tfd->mkdir(newDir)));
159  }
160  else {
161  theDbe=edm::Service<DQMStore>().operator->();
162  }
163  }
164 
165  DirectoryWrapper(const std::string& newDir,const std::string& basedir,bool useDqmMode)
166  : tfd(nullptr),
167  dqmMode(useDqmMode),
168  theDbe(nullptr) {
169  if (!dqmMode){
171  if (newDir.length()==0){
172  tfd.reset(new TFileDirectory(fs->tFileDirectory()));
173  }
174  else {
175  tfd.reset(new TFileDirectory(fs->mkdir(newDir)));
176  directoryString=newDir;
177  }
178  }
179  else {
180  if (newDir.length()!=0){
181  if(basedir.length()!=0)directoryString=basedir+"/"+newDir;
182  else directoryString = newDir;
183  }
184  else directoryString=basedir;
185  theDbe=edm::Service<DQMStore>().operator->();
186  }
187  }
188  // Generalization of Histogram Booking; allows switch between TFileService and DQMStore
189  template <typename T> TH1* make(const char* name,const char* title,int nBinX,double minBinX,double maxBinX);
190  template <typename T> TH1* make(const char* name,const char* title,int nBinX,double *xBins);//variable bin size in x for profile histo
191  template <typename T> TH1* make(const char* name,const char* title,int nBinX,double minBinX,double maxBinX,int nBinY,double minBinY,double maxBinY);
192  template <typename T> TH1* make(const char* name,const char* title,int nBinX,double minBinX,double maxBinX,double minBinY,double maxBinY); // at present not used
193 
194  std::unique_ptr<TFileDirectory> tfd;
196  const bool dqmMode;
198  };
199 
200 
201  //
202  // ------------- private member function -------------
203  //
204  void analyze(const edm::Event&, const edm::EventSetup&) override;
205  void endJob() override;
206 
207  virtual void checkBookHists(const edm::EventSetup& setup);
208 
210  void bookDirHists(DirectoryWrapper& tfd, const Alignable& ali, const TrackerTopology* tTopo);
211  void bookHists(DirectoryWrapper& tfd, const Alignable& ali, const TrackerTopology* tTopo, align::StructureType type, int i);
212 
213  void prepareSummaryHists( DirectoryWrapper& tfd, const Alignable& ali,
214  std::vector<TrackerOfflineValidation::SummaryContainer>& vLevelProfiles);
215  void collateSummaryHists();
216 
217  void setUpTreeMembers(const std::map<int, TrackerOfflineValidation::ModuleHistos>& moduleHist_,
218  const TrackerGeometry& tkgeom, const TrackerTopology* tTopo);
219  void fillTree(TTree& tree, TkOffTreeVariables &treeMem, const std::map<int, TrackerOfflineValidation::ModuleHistos>& moduleHist_);
220 
222  const Alignable& ali,
223  align::StructureType type, int i);
224 
225  ModuleHistos& getHistStructFromMap(const DetId& detid);
226 
227  bool isBarrel(uint32_t subDetId);
228  bool isEndCap(uint32_t subDetId);
229  bool isPixel(uint32_t subDetId);
231 
232  TH1* bookTH1F(bool isTransient, DirectoryWrapper& tfd, const char* histName, const char* histTitle,
233  int nBinsX, double lowX, double highX);
234 
235  TProfile* bookTProfile(bool isTransient, DirectoryWrapper& tfd, const char* histName, const char* histTitle,
236  int nBinsX, double lowX, double highX);
237 
238  TProfile* bookTProfile(bool isTransient, DirectoryWrapper& tfd, const char* histName, const char* histTitle,
239  int nBinsX, double lowX, double highX, double lowY, double highY);
240 
241  void getBinning(uint32_t subDetId, TrackerOfflineValidation::HistogramType residualtype,
242  int& nBinsX, double& lowerBoundX, double& upperBoundX);
243 
244  void summarizeBinInContainer(int bin, SummaryContainer& targetContainer,
245  SummaryContainer& sourceContainer);
246 
247  void summarizeBinInContainer(int bin, uint32_t subDetId, SummaryContainer& targetContainer,
248  ModuleHistos& sourceContainer);
249 
250  void setSummaryBin(int bin, TH1* targetHist, TH1* sourceHist);
251 
252  float Fwhm(const TH1* hist) const;
253  std::pair<float,float> fitResiduals(TH1* hist) const; //, float meantmp, float rmstmp);
254  float getMedian( const TH1* hist) const;
255 
256  // From MillePedeAlignmentMonitor: Get Index for Arbitary vector<class> by name
257  template <class OBJECT_TYPE> int GetIndex(const std::vector<OBJECT_TYPE*>& vec, const TString& name);
258 
259 
260  // ---------- member data ---------------------------
261 
264  const TrackerGeometry *bareTkGeomPtr_; // ugly hack to book hists only once, but check
265  std::unique_ptr<AlignableTracker> alignableTracker_;
266 
267  // parameters from cfg to steer
268  const bool lCoorHistOn_;
271  const bool stripYResiduals_;
272  const bool useFwhm_;
273  const bool useFit_;
274  const bool useOverflowForRMS_;
275  const bool dqmMode_;
277 
278  const int chargeCut_;
279 
280  // a vector to keep track which pointers should be deleted at the very end
281  std::vector<TH1*> vDeleteObjects_;
282 
283  std::vector<TH1*> vTrackHistos_;
284  std::vector<TH1*> vTrackProfiles_;
285  std::vector<TH1*> vTrack2DHistos_;
286 
287  std::map<int,TrackerOfflineValidation::ModuleHistos> mPxbResiduals_;
288  std::map<int,TrackerOfflineValidation::ModuleHistos> mPxeResiduals_;
289  std::map<int,TrackerOfflineValidation::ModuleHistos> mTibResiduals_;
290  std::map<int,TrackerOfflineValidation::ModuleHistos> mTidResiduals_;
291  std::map<int,TrackerOfflineValidation::ModuleHistos> mTobResiduals_;
292  std::map<int,TrackerOfflineValidation::ModuleHistos> mTecResiduals_;
293 
294  std::map<int,TkOffTreeVariables> mTreeMembers_;
295 
296  //There are two types of summary histograms. The first contains, for each component, a bin per subcomponent.
297  //These are set up through summarizeBinInContainer(). The second type is just the sum of the lower level histograms.
298  //Prepare the filling of both types at the beginning, when the tracker topology is available through the eventsetup.
299  //They are not actually filled until the end, but at that time eventsetup is no longer accessible.
300 
301  //To fill the summary hists, store the arguments of setSummaryBin()
302  //At the end, call the function
303  std::vector<std::tuple<int,TH1*,TH1*> > summaryBins_;
304  //To fill the sum hists, just store pairs of TH1*. At the end, first->Add(second).
305  std::vector<std::pair<TH1*,TH1*> > sumHistStructure_;
306  //sum hists are fit at the end using fitResiduals()
307  std::vector<TH1*> toFit_;
308 
309  unsigned long long nTracks_;
310  const unsigned long long maxTracks_;
311 
313 };
314 
315 
316 //
317 // constants, enums and typedefs
318 //
319 
320 //
321 // static data member definitions
322 //
323 
324 template <class OBJECT_TYPE>
325 int TrackerOfflineValidation::GetIndex(const std::vector<OBJECT_TYPE*> &vec, const TString &name)
326 {
327  int result = 0;
328  for (typename std::vector<OBJECT_TYPE*>::const_iterator iter = vec.begin(), iterEnd = vec.end();
329  iter != iterEnd; ++iter, ++result) {
330  if (*iter && (*iter)->GetName() == name) return result;
331  }
332  edm::LogError("Alignment") << "@SUB=TrackerOfflineValidation::GetIndex" << " could not find " << name;
333  return -1;
334 }
335 
336 
337 template <> TH1* TrackerOfflineValidation::DirectoryWrapper::make<TH1F>(const char* name,const char* title,int nBinX,double minBinX,double maxBinX){
338  if(dqmMode){theDbe->setCurrentFolder(directoryString); return theDbe->book1D(name,title,nBinX,minBinX,maxBinX)->getTH1();}
339  else{return tfd->make<TH1F>(name,title,nBinX,minBinX,maxBinX);}
340 }
341 
342 template <> TH1* TrackerOfflineValidation::DirectoryWrapper::make<TProfile>(const char* name,const char* title,int nBinX,double *xBins){
343  if(dqmMode){
344  theDbe->setCurrentFolder(directoryString);
345  //DQM profile requires y-bins for construction... using TProfile creator by hand...
346  TProfile *tmpProfile=new TProfile(name,title,nBinX,xBins);
347  tmpProfile->SetDirectory(nullptr);
348  return theDbe->bookProfile(name,tmpProfile)->getTH1();
349  }
350  else{return tfd->make<TProfile>(name,title,nBinX,xBins);}
351 }
352 
353 template <> TH1* TrackerOfflineValidation::DirectoryWrapper::make<TProfile>(const char* name,const char* title,int nBinX,double minBinX,double maxBinX){
354  if(dqmMode){
355  theDbe->setCurrentFolder(directoryString);
356  //DQM profile requires y-bins for construction... using TProfile creator by hand...
357  TProfile *tmpProfile=new TProfile(name,title,nBinX,minBinX,maxBinX);
358  tmpProfile->SetDirectory(nullptr);
359  return theDbe->bookProfile(name,tmpProfile)->getTH1();
360  }
361  else{return tfd->make<TProfile>(name,title,nBinX,minBinX,maxBinX);}
362 }
363 
364 template <> TH1* TrackerOfflineValidation::DirectoryWrapper::make<TProfile>(const char* name ,const char* title,int nbinX,double minX ,double maxX,double minY,double maxY){
365  if(dqmMode){
366  theDbe->setCurrentFolder(directoryString);
367  int dummy(0); // DQMProfile wants Y channels... does not use them!
368  return (theDbe->bookProfile(name,title,nbinX,minX,maxX,dummy,minY,maxY)->getTH1());
369  }
370  else{
371  return tfd->make<TProfile>(name,title,nbinX,minX,maxX,minY,maxY);
372  }
373 }
374 
375 template <> TH1* TrackerOfflineValidation::DirectoryWrapper::make<TH2F>(const char* name,const char* title,int nBinX,double minBinX,double maxBinX,int nBinY,double minBinY,double maxBinY){
376  if(dqmMode){theDbe->setCurrentFolder(directoryString); return theDbe->book2D(name,title,nBinX,minBinX,maxBinX,nBinY,minBinY,maxBinY)->getTH1();}
377  else{return tfd->make<TH2F>(name,title,nBinX,minBinX,maxBinX,nBinY,minBinY,maxBinY);}
378 }
379 
380 
381 //
382 // constructors and destructor
383 //
385  : parSet_(iConfig), bareTkGeomPtr_(nullptr), lCoorHistOn_(parSet_.getParameter<bool>("localCoorHistosOn")),
386  moduleLevelHistsTransient_(parSet_.getParameter<bool>("moduleLevelHistsTransient")),
387  moduleLevelProfiles_(parSet_.getParameter<bool>("moduleLevelProfiles")),
388  stripYResiduals_(parSet_.getParameter<bool>("stripYResiduals")),
389  useFwhm_(parSet_.getParameter<bool>("useFwhm")),
390  useFit_(parSet_.getParameter<bool>("useFit")),
391  useOverflowForRMS_(parSet_.getParameter<bool>("useOverflowForRMS")),
392  dqmMode_(parSet_.getParameter<bool>("useInDqmMode")),
393  moduleDirectory_(parSet_.getParameter<std::string>("moduleDirectoryInOutput")),
394  chargeCut_(parSet_.getParameter<int>("chargeCut")),
395  nTracks_(0),
396  maxTracks_(parSet_.getParameter<unsigned long long>("maxTracks")),
397  avalidator_(iConfig, consumesCollector())
398 {
399 }
400 
401 
403 {
404  // do anything here that needs to be done at desctruction time
405  // (e.g. close files, deallocate resources etc.)
406  for( std::vector<TH1*>::const_iterator it = vDeleteObjects_.begin(), itEnd = vDeleteObjects_.end();
407  it != itEnd;
408  ++it) delete *it;
409 }
410 
411 
412 //
413 // member functions
414 //
415 
416 
417 // ------------ method called once each job just before starting event loop ------------
418 void
420 {
422  const TrackerGeometry *newBareTkGeomPtr = &(*tkGeom_);
423  if (newBareTkGeomPtr == bareTkGeomPtr_) return; // already booked hists, nothing changed
424 
425  if (!bareTkGeomPtr_) { // pointer not yet set: called the first time => book hists
426 
427  //Retrieve tracker topology from geometry
428  edm::ESHandle<TrackerTopology> tTopoHandle;
429  es.get<TrackerTopologyRcd>().get(tTopoHandle);
430  const TrackerTopology* const tTopo = tTopoHandle.product();
431 
432  // construct alignable tracker to get access to alignable hierarchy
433  alignableTracker_ = std::make_unique<AlignableTracker>(&(*tkGeom_), tTopo);
434 
435  edm::LogInfo("TrackerOfflineValidation") << "There are " << newBareTkGeomPtr->detIds().size()
436  << " dets in the Geometry record.\n"
437  << "Out of these "<<newBareTkGeomPtr->detUnitIds().size()
438  <<" are detUnits";
439 
440  // Book histograms for global track quantities
441  std::string globDir("GlobalTrackVariables");
442  DirectoryWrapper trackglobal(globDir,moduleDirectory_,dqmMode_);
443  this->bookGlobalHists(trackglobal);
444 
445  // recursively book histograms on lowest level
447  this->bookDirHists(tfdw, *alignableTracker_, tTopo);
448  // and prepare the higher level histograms
449  std::vector<TrackerOfflineValidation::SummaryContainer> vTrackerprofiles;
450  this->prepareSummaryHists(tfdw, *alignableTracker_, vTrackerprofiles);
451 
452  setUpTreeMembers(mPxbResiduals_, *newBareTkGeomPtr, tTopo);
453  setUpTreeMembers(mPxeResiduals_, *newBareTkGeomPtr, tTopo);
454  setUpTreeMembers(mTibResiduals_, *newBareTkGeomPtr, tTopo);
455  setUpTreeMembers(mTidResiduals_, *newBareTkGeomPtr, tTopo);
456  setUpTreeMembers(mTobResiduals_, *newBareTkGeomPtr, tTopo);
457  setUpTreeMembers(mTecResiduals_, *newBareTkGeomPtr, tTopo);
458  }
459  else { // histograms booked, but changed TrackerGeometry?
460  edm::LogWarning("GeometryChange") << "@SUB=checkBookHists"
461  << "TrackerGeometry changed, but will not re-book hists!";
462  }
463  bareTkGeomPtr_ = newBareTkGeomPtr;
464 }
465 
466 
467 void
469 {
470 
471  vTrackHistos_.push_back(tfd.make<TH1F>("h_tracketa",
472  "Track #eta;#eta_{Track};Number of Tracks",
473  90,-3.,3.));
474  vTrackHistos_.push_back(tfd.make<TH1F>("h_trackphi",
475  "Track #phi;#phi_{Track};Number of Tracks",
476  90,-3.15,3.15));
477  vTrackHistos_.push_back(tfd.make<TH1F>("h_trackNumberOfValidHits",
478  "Track # of valid hits;# of valid hits _{Track};Number of Tracks",
479  40,0.,40.));
480  vTrackHistos_.push_back(tfd.make<TH1F>("h_trackNumberOfLostHits",
481  "Track # of lost hits;# of lost hits _{Track};Number of Tracks",
482  10,0.,10.));
483  vTrackHistos_.push_back(tfd.make<TH1F>("h_curvature",
484  "Curvature #kappa;#kappa_{Track};Number of Tracks",
485  100,-.05,.05));
486  vTrackHistos_.push_back(tfd.make<TH1F>("h_curvature_pos",
487  "Curvature |#kappa| Positive Tracks;|#kappa_{pos Track}|;Number of Tracks",
488  100,.0,.05));
489  vTrackHistos_.push_back(tfd.make<TH1F>("h_curvature_neg",
490  "Curvature |#kappa| Negative Tracks;|#kappa_{neg Track}|;Number of Tracks",
491  100,.0,.05));
492  vTrackHistos_.push_back(tfd.make<TH1F>("h_diff_curvature",
493  "Curvature |#kappa| Tracks Difference;|#kappa_{Track}|;# Pos Tracks - # Neg Tracks",
494  100,.0,.05));
495  vTrackHistos_.push_back(tfd.make<TH1F>("h_chi2",
496  "#chi^{2};#chi^{2}_{Track};Number of Tracks",
497  500,-0.01,500.));
498  vTrackHistos_.push_back(tfd.make<TH1F>("h_chi2Prob",
499  "#chi^{2} probability;#chi^{2}prob_{Track};Number of Tracks",
500  100,0.0,1.));
501  vTrackHistos_.push_back(tfd.make<TH1F>("h_normchi2",
502  "#chi^{2}/ndof;#chi^{2}/ndof;Number of Tracks",
503  100,-0.01,10.));
504  vTrackHistos_.push_back(tfd.make<TH1F>("h_pt",
505  "p_{T}^{track};p_{T}^{track} [GeV];Number of Tracks",
506  250,0.,250));
507  vTrackHistos_.push_back(tfd.make<TH1F>("h_ptResolution",
508  "#delta_{p_{T}}/p_{T}^{track};#delta_{p_{T}}/p_{T}^{track};Number of Tracks",
509  100,0.,0.5));
510  vTrackProfiles_.push_back(tfd.make<TProfile>("p_d0_vs_phi",
511  "Transverse Impact Parameter vs. #phi;#phi_{Track};#LT d_{0} #GT [cm]",
512  100,-3.15,3.15));
513  vTrackProfiles_.push_back(tfd.make<TProfile>("p_dz_vs_phi",
514  "Longitudinal Impact Parameter vs. #phi;#phi_{Track};#LT d_{z} #GT [cm]",
515  100,-3.15,3.15));
516  vTrackProfiles_.push_back(tfd.make<TProfile>("p_d0_vs_eta",
517  "Transverse Impact Parameter vs. #eta;#eta_{Track};#LT d_{0} #GT [cm]",
518  100,-3.15,3.15));
519  vTrackProfiles_.push_back(tfd.make<TProfile>("p_dz_vs_eta",
520  "Longitudinal Impact Parameter vs. #eta;#eta_{Track};#LT d_{z} #GT [cm]",
521  100,-3.15,3.15));
522  vTrackProfiles_.push_back(tfd.make<TProfile>("p_chi2_vs_phi",
523  "#chi^{2} vs. #phi;#phi_{Track};#LT #chi^{2} #GT",
524  100,-3.15,3.15));
525  vTrackProfiles_.push_back(tfd.make<TProfile>("p_chi2Prob_vs_phi",
526  "#chi^{2} probablility vs. #phi;#phi_{Track};#LT #chi^{2} probability#GT",
527  100,-3.15,3.15));
528  vTrackProfiles_.push_back(tfd.make<TProfile>("p_chi2Prob_vs_d0",
529  "#chi^{2} probablility vs. |d_{0}|;|d_{0}|[cm];#LT #chi^{2} probability#GT",
530  100,0,80));
531  vTrackProfiles_.push_back(tfd.make<TProfile>("p_normchi2_vs_phi",
532  "#chi^{2}/ndof vs. #phi;#phi_{Track};#LT #chi^{2}/ndof #GT",
533  100,-3.15,3.15));
534  vTrackProfiles_.push_back(tfd.make<TProfile>("p_chi2_vs_eta",
535  "#chi^{2} vs. #eta;#eta_{Track};#LT #chi^{2} #GT",
536  100,-3.15,3.15));
537  //variable binning for chi2/ndof vs. pT
538  double xBins[19]={0.,0.15,0.5,1.,1.5,2.,2.5,3.,3.5,4.,4.5,5.,7.,10.,15.,25.,40.,100.,200.};
539  vTrackProfiles_.push_back(tfd.make<TProfile>("p_normchi2_vs_pt",
540  "norm #chi^{2} vs. p_{T}_{Track}; p_{T}_{Track};#LT #chi^{2}/ndof #GT",
541  18,xBins));
542 
543  vTrackProfiles_.push_back(tfd.make<TProfile>("p_normchi2_vs_p",
544  "#chi^{2}/ndof vs. p_{Track};p_{Track};#LT #chi^{2}/ndof #GT",
545  18,xBins));
546  vTrackProfiles_.push_back(tfd.make<TProfile>("p_chi2Prob_vs_eta",
547  "#chi^{2} probability vs. #eta;#eta_{Track};#LT #chi^{2} probability #GT",
548  100,-3.15,3.15));
549  vTrackProfiles_.push_back(tfd.make<TProfile>("p_normchi2_vs_eta",
550  "#chi^{2}/ndof vs. #eta;#eta_{Track};#LT #chi^{2}/ndof #GT",
551  100,-3.15,3.15));
552  vTrackProfiles_.push_back(tfd.make<TProfile>("p_kappa_vs_phi",
553  "#kappa vs. #phi;#phi_{Track};#kappa",
554  100,-3.15,3.15));
555  vTrackProfiles_.push_back(tfd.make<TProfile>("p_kappa_vs_eta",
556  "#kappa vs. #eta;#eta_{Track};#kappa",
557  100,-3.15,3.15));
558  vTrackProfiles_.push_back(tfd.make<TProfile>("p_ptResolution_vs_phi",
559  "#delta_{p_{T}}/p_{T}^{track};#phi^{track};#delta_{p_{T}}/p_{T}^{track}",
560  100, -3.15,3.15));
561  vTrackProfiles_.push_back(tfd.make<TProfile>("p_ptResolution_vs_eta",
562  "#delta_{p_{T}}/p_{T}^{track};#eta^{track};#delta_{p_{T}}/p_{T}^{track}",
563  100, -3.15,3.15));
564 
565  vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_d0_vs_phi",
566  "Transverse Impact Parameter vs. #phi;#phi_{Track};d_{0} [cm]",
567  100, -3.15, 3.15, 100,-1.,1.) );
568  vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_dz_vs_phi",
569  "Longitudinal Impact Parameter vs. #phi;#phi_{Track};d_{z} [cm]",
570  100, -3.15, 3.15, 100,-100.,100.));
571  vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_d0_vs_eta",
572  "Transverse Impact Parameter vs. #eta;#eta_{Track};d_{0} [cm]",
573  100, -3.15, 3.15, 100,-1.,1.));
574  vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_dz_vs_eta",
575  "Longitudinal Impact Parameter vs. #eta;#eta_{Track};d_{z} [cm]",
576  100, -3.15, 3.15, 100,-100.,100.));
577  vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_chi2_vs_phi",
578  "#chi^{2} vs. #phi;#phi_{Track};#chi^{2}",
579  100, -3.15, 3.15, 500, 0., 500.));
580  vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_chi2Prob_vs_phi",
581  "#chi^{2} probability vs. #phi;#phi_{Track};#chi^{2} probability",
582  100, -3.15, 3.15, 100, 0., 1.));
583  vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_chi2Prob_vs_d0",
584  "#chi^{2} probability vs. |d_{0}|;|d_{0}| [cm];#chi^{2} probability",
585  100, 0, 80, 100, 0., 1.));
586  vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_normchi2_vs_phi",
587  "#chi^{2}/ndof vs. #phi;#phi_{Track};#chi^{2}/ndof",
588  100, -3.15, 3.15, 100, 0., 10.));
589  vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_chi2_vs_eta",
590  "#chi^{2} vs. #eta;#eta_{Track};#chi^{2}",
591  100, -3.15, 3.15, 500, 0., 500.));
592  vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_chi2Prob_vs_eta",
593  "#chi^{2} probaility vs. #eta;#eta_{Track};#chi^{2} probability",
594  100, -3.15, 3.15, 100, 0., 1.));
595  vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_normchi2_vs_eta",
596  "#chi^{2}/ndof vs. #eta;#eta_{Track};#chi^{2}/ndof",
597  100,-3.15,3.15, 100, 0., 10.));
598  vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_kappa_vs_phi",
599  "#kappa vs. #phi;#phi_{Track};#kappa",
600  100,-3.15,3.15, 100, .0,.05));
601  vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_kappa_vs_eta",
602  "#kappa vs. #eta;#eta_{Track};#kappa",
603  100,-3.15,3.15, 100, .0,.05));
604  vTrack2DHistos_.push_back(tfd.make<TH2F>("h2_normchi2_vs_kappa",
605  "#kappa vs. #chi^{2}/ndof;#chi^{2}/ndof;#kappa",
606  100,0.,10, 100,-.03,.03));
607 
608  /****************** Definition of 2-D Histos of ResX vs momenta ****************************/
609  vTrack2DHistos_.push_back(tfd.make<TH2F>("p_vs_resXprime_pixB",
610  "res_{x'} vs momentum in BPix;p [GeV]; res_{x'}",
611  15,0.,15., 200, -0.1,0.1));
612  vTrack2DHistos_.push_back(tfd.make<TH2F>("p_vs_resXprime_pixE",
613  "res_{x'} vs momentum in FPix;p [GeV]; res_{x'}",
614  15,0.,15., 200, -0.1,0.1));
615  vTrack2DHistos_.push_back(tfd.make<TH2F>("p_vs_resXprime_TIB",
616  "res_{x'} vs momentum in TIB;p [GeV]; res_{x'}",
617  15,0.,15., 200, -0.1,0.1));
618  vTrack2DHistos_.push_back(tfd.make<TH2F>("p_vs_resXprime_TID",
619  "res_{x'} vs momentum in TID;p [GeV]; res_{x'}",
620  15,0.,15., 200, -0.1,0.1));
621  vTrack2DHistos_.push_back(tfd.make<TH2F>("p_vs_resXprime_TOB",
622  "res_{x'} vs momentum in TOB;p [GeV]; res_{x'}",
623  15,0.,15., 200, -0.1,0.1));
624  vTrack2DHistos_.push_back(tfd.make<TH2F>("p_vs_resXprime_TEC",
625  "res_{x'} vs momentum in TEC;p [GeV]; res_{x'}",
626  15,0.,15., 200, -0.1,0.1));
627 
628  /****************** Definition of 2-D Histos of ResY vs momenta ****************************/
629  vTrack2DHistos_.push_back(tfd.make<TH2F>("p_vs_resYprime_pixB",
630  "res_{y'} vs momentum in BPix;p [GeV]; res_{y'}",
631  15,0.,15., 200, -0.1,0.1));
632  vTrack2DHistos_.push_back(tfd.make<TH2F>("p_vs_resYprime_pixE",
633  "res_{y'} vs momentum in FPix;p [GeV]; res_{y'}",
634  15,0.,15., 200, -0.1,0.1));
635 
636 }
637 
638 
639 void
641 {
642  const auto& alivec = ali.components();
643  for(int i=0, iEnd = ali.components().size();i < iEnd; ++i) {
644  std::string structurename = alignableTracker_->objectIdProvider().idToString((alivec)[i]->alignableObjectId());
645  LogDebug("TrackerOfflineValidation") << "StructureName = " << structurename;
646  std::stringstream dirname;
647  dirname << structurename;
648  // add no suffix counter to Strip and Pixel, just aesthetics
649  if (structurename != "Strip" && structurename != "Pixel") dirname << "_" << i+1;
650 
651  if (structurename.find("Endcap",0) != std::string::npos ) {
652  DirectoryWrapper f(tfd,dirname.str(),moduleDirectory_,dqmMode_);
653  bookHists(f, *(alivec)[i], tTopo, ali.alignableObjectId() , i);
654  bookDirHists( f, *(alivec)[i], tTopo);
655  } else if( !(this->isDetOrDetUnit( (alivec)[i]->alignableObjectId()) )
656  || alivec[i]->components().size() > 1) {
657  DirectoryWrapper f(tfd,dirname.str(),moduleDirectory_,dqmMode_);
658  bookHists(tfd, *(alivec)[i], tTopo, ali.alignableObjectId() , i);
659  bookDirHists( f, *(alivec)[i], tTopo);
660  } else {
661  bookHists(tfd, *(alivec)[i], tTopo, ali.alignableObjectId() , i);
662  }
663  }
664 }
665 
666 
667 void
669 {
670  TrackerAlignableId aliid;
671  const DetId id = ali.id();
672 
673  // comparing subdetandlayer to subdetIds gives a warning at compile time
674  // -> subdetandlayer could also be pair<uint,uint> but this has to be adapted
675  // in AlignableObjId
676  std::pair<int,int> subdetandlayer = aliid.typeAndLayerFromDetId(id, tTopo);
677 
679 
680  // are we on or just above det, detunit level respectively?
681  if (type == align::AlignableDetUnit )subtype = type;
682  else if( this->isDetOrDetUnit(ali.alignableObjectId()) ) subtype = ali.alignableObjectId();
683 
684  // construct histogram title and name
685  std::stringstream histoname, histotitle, normhistoname, normhistotitle,
686  yhistoname, yhistotitle,
687  xprimehistoname, xprimehistotitle, normxprimehistoname, normxprimehistotitle,
688  yprimehistoname, yprimehistotitle, normyprimehistoname, normyprimehistotitle,
689  localxname, localxtitle, localyname, localytitle,
690  resxvsxprofilename, resxvsxprofiletitle, resyvsxprofilename, resyvsxprofiletitle,
691  resxvsyprofilename, resxvsyprofiletitle, resyvsyprofilename, resyvsyprofiletitle;
692 
693  std::string wheel_or_layer;
694 
695  if( this->isEndCap(static_cast<uint32_t>(subdetandlayer.first)) ) wheel_or_layer = "_wheel_";
696  else if ( this->isBarrel(static_cast<uint32_t>(subdetandlayer.first)) ) wheel_or_layer = "_layer_";
697  else edm::LogWarning("TrackerOfflineValidation") << "@SUB=TrackerOfflineValidation::bookHists"
698  << "Unknown subdetid: " << subdetandlayer.first;
699 
700  histoname << "h_residuals_subdet_" << subdetandlayer.first
701  << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
702  yhistoname << "h_y_residuals_subdet_" << subdetandlayer.first
703  << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
704  xprimehistoname << "h_xprime_residuals_subdet_" << subdetandlayer.first
705  << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
706  yprimehistoname << "h_yprime_residuals_subdet_" << subdetandlayer.first
707  << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
708  normhistoname << "h_normresiduals_subdet_" << subdetandlayer.first
709  << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
710  normxprimehistoname << "h_normxprimeresiduals_subdet_" << subdetandlayer.first
711  << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
712  normyprimehistoname << "h_normyprimeresiduals_subdet_" << subdetandlayer.first
713  << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
714  histotitle << "X Residual for module " << id.rawId() << ";x_{tr} - x_{hit} [cm]";
715  yhistotitle << "Y Residual for module " << id.rawId() << ";y_{tr} - y_{hit} [cm]";
716  normhistotitle << "Normalized Residual for module " << id.rawId() << ";x_{tr} - x_{hit}/#sigma";
717  xprimehistotitle << "X' Residual for module " << id.rawId() << ";(x_{tr} - x_{hit})' [cm]";
718  normxprimehistotitle << "Normalized X' Residual for module " << id.rawId() << ";(x_{tr} - x_{hit})'/#sigma";
719  yprimehistotitle << "Y' Residual for module " << id.rawId() << ";(y_{tr} - y_{hit})' [cm]";
720  normyprimehistotitle << "Normalized Y' Residual for module " << id.rawId() << ";(y_{tr} - y_{hit})'/#sigma";
721 
722  if ( moduleLevelProfiles_ ) {
723  localxname << "h_localx_subdet_" << subdetandlayer.first
724  << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
725  localyname << "h_localy_subdet_" << subdetandlayer.first
726  << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
727  localxtitle << "u local for module " << id.rawId() << "; u_{tr,r}";
728  localytitle << "v local for module " << id.rawId() << "; v_{tr,r}";
729 
730  resxvsxprofilename << "p_residuals_x_vs_x_subdet_" << subdetandlayer.first
731  << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
732  resyvsxprofilename << "p_residuals_y_vs_x_subdet_" << subdetandlayer.first
733  << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
734  resxvsyprofilename << "p_residuals_x_vs_y_subdet_" << subdetandlayer.first
735  << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
736  resyvsyprofilename << "p_residuals_y_vs_y_subdet_" << subdetandlayer.first
737  << wheel_or_layer << subdetandlayer.second << "_module_" << id.rawId();
738  resxvsxprofiletitle << "U Residual vs u for module " << id.rawId() << "; u_{tr,r} ;(u_{tr} - u_{hit})/tan#alpha [cm]";
739  resyvsxprofiletitle << "V Residual vs u for module " << id.rawId() << "; u_{tr,r} ;(v_{tr} - v_{hit})/tan#beta [cm]";
740  resxvsyprofiletitle << "U Residual vs v for module " << id.rawId() << "; v_{tr,r} ;(u_{tr} - u_{hit})/tan#alpha [cm]";
741  resyvsyprofiletitle << "V Residual vs v for module " << id.rawId() << "; v_{tr,r} ;(v_{tr} - v_{hit})/tan#beta [cm]";
742  }
743 
744  if( this->isDetOrDetUnit( subtype ) ) {
745  ModuleHistos &histStruct = this->getHistStructFromMap(id);
746  int nbins = 0;
747  double xmin = 0., xmax = 0.;
748  double ymin = -0.1, ymax = 0.1;
749 
750  // do not allow transient hists in DQM mode
752  if (dqmMode_) moduleLevelHistsTransient = false;
753 
754  // decide via cfg if hists in local coordinates should be booked
755  if(lCoorHistOn_) {
756  this->getBinning(id.subdetId(), XResidual, nbins, xmin, xmax);
757  histStruct.ResHisto = this->bookTH1F(moduleLevelHistsTransient, tfd,
758  histoname.str().c_str(),histotitle.str().c_str(),
759  nbins, xmin, xmax);
760  this->getBinning(id.subdetId(), NormXResidual, nbins, xmin, xmax);
761  histStruct.NormResHisto = this->bookTH1F(moduleLevelHistsTransient, tfd,
762  normhistoname.str().c_str(),normhistotitle.str().c_str(),
763  nbins, xmin, xmax);
764  }
765  this->getBinning(id.subdetId(), XprimeResidual, nbins, xmin, xmax);
766  histStruct.ResXprimeHisto = this->bookTH1F(moduleLevelHistsTransient, tfd,
767  xprimehistoname.str().c_str(),xprimehistotitle.str().c_str(),
768  nbins, xmin, xmax);
769  this->getBinning(id.subdetId(), NormXprimeResidual, nbins, xmin, xmax);
770  histStruct.NormResXprimeHisto = this->bookTH1F(moduleLevelHistsTransient, tfd,
771  normxprimehistoname.str().c_str(),normxprimehistotitle.str().c_str(),
772  nbins, xmin, xmax);
773 
774  if ( moduleLevelProfiles_ ) {
775  this->getBinning(id.subdetId(), XResidualProfile, nbins, xmin, xmax);
776 
777  histStruct.LocalX = this->bookTH1F(moduleLevelHistsTransient, tfd,
778  localxname.str().c_str(),localxtitle.str().c_str(),
779  nbins, xmin, xmax);
780  histStruct.LocalY = this->bookTH1F(moduleLevelHistsTransient, tfd,
781  localyname.str().c_str(),localytitle.str().c_str(),
782  nbins, xmin, xmax);
783  histStruct.ResXvsXProfile = this->bookTProfile(moduleLevelHistsTransient, tfd,
784  resxvsxprofilename.str().c_str(),resxvsxprofiletitle.str().c_str(),
785  nbins, xmin, xmax, ymin, ymax);
786  histStruct.ResXvsXProfile->Sumw2(); // to be filled with weights, so uncertainties need sum of square of weights
787  histStruct.ResXvsYProfile = this->bookTProfile(moduleLevelHistsTransient, tfd,
788  resxvsyprofilename.str().c_str(),resxvsyprofiletitle.str().c_str(),
789  nbins, xmin, xmax, ymin, ymax);
790  histStruct.ResXvsYProfile->Sumw2(); // to be filled with weights, so uncertainties need sum of square of weights
791  }
792 
793  if( this->isPixel(subdetandlayer.first) || stripYResiduals_ ) {
794  this->getBinning(id.subdetId(), YprimeResidual, nbins, xmin, xmax);
795  histStruct.ResYprimeHisto = this->bookTH1F(moduleLevelHistsTransient, tfd,
796  yprimehistoname.str().c_str(),yprimehistotitle.str().c_str(),
797  nbins, xmin, xmax);
798  if (lCoorHistOn_) { // un-primed y-residual
799  this->getBinning(id.subdetId(), YResidual, nbins, xmin, xmax);
800  histStruct.ResYHisto = this->bookTH1F(moduleLevelHistsTransient, tfd,
801  yhistoname.str().c_str(), yhistotitle.str().c_str(),
802  nbins, xmin, xmax);
803  }
804  this->getBinning(id.subdetId(), NormYprimeResidual, nbins, xmin, xmax);
805  histStruct.NormResYprimeHisto = this->bookTH1F(moduleLevelHistsTransient, tfd,
806  normyprimehistoname.str().c_str(),normyprimehistotitle.str().c_str(),
807  nbins, xmin, xmax);
808  // Here we could add un-primed normalised y-residuals if(lCoorHistOn_)...
809  if ( moduleLevelProfiles_ ) {
810  this->getBinning(id.subdetId(), YResidualProfile, nbins, xmin, xmax);
811 
812  histStruct.ResYvsXProfile = this->bookTProfile(moduleLevelHistsTransient, tfd,
813  resyvsxprofilename.str().c_str(),resyvsxprofiletitle.str().c_str(),
814  nbins, xmin, xmax, ymin, ymax);
815  histStruct.ResYvsXProfile->Sumw2(); // to be filled with weights, so uncertainties need sum of square of weights
816  histStruct.ResYvsYProfile = this->bookTProfile(moduleLevelHistsTransient, tfd,
817  resyvsyprofilename.str().c_str(),resyvsyprofiletitle.str().c_str(),
818  nbins, xmin, xmax, ymin, ymax);
819  histStruct.ResYvsYProfile->Sumw2(); // to be filled with weights, so uncertainties need sum of square of weights
820  }
821  }
822  }
823 }
824 
825 
826 TH1* TrackerOfflineValidation::bookTH1F(bool isTransient, DirectoryWrapper& tfd, const char* histName, const char* histTitle,
827  int nBinsX, double lowX, double highX)
828 {
829  if (isTransient) {
830  vDeleteObjects_.push_back(new TH1F(histName, histTitle, nBinsX, lowX, highX));
831  return vDeleteObjects_.back(); // return last element of vector
832  }
833  else
834  return tfd.make<TH1F>(histName, histTitle, nBinsX, lowX, highX);
835 }
836 
837 TProfile* TrackerOfflineValidation::bookTProfile(bool isTransient, DirectoryWrapper& tfd, const char* histName, const char* histTitle,
838  int nBinsX, double lowX, double highX)
839 {
840  if (isTransient) {
841  TProfile * profile = new TProfile(histName, histTitle, nBinsX, lowX, highX);
842  vDeleteObjects_.push_back(profile);
843  return profile;
844  }
845  else
846  return (TProfile*)tfd.make<TProfile>(histName, histTitle, nBinsX, lowX, highX);
847 }
848 
849 
850 TProfile* TrackerOfflineValidation::bookTProfile(bool isTransient, DirectoryWrapper& tfd, const char* histName, const char* histTitle,
851  int nBinsX, double lowX, double highX, double lowY, double highY)
852 {
853  if (isTransient) {
854  TProfile * profile = new TProfile(histName, histTitle, nBinsX, lowX, highX, lowY, highY);
855  vDeleteObjects_.push_back(profile);
856  return profile;
857  }
858  else
859  return (TProfile*)tfd.make<TProfile>(histName, histTitle, nBinsX, lowX, highX, lowY, highY);
860 }
861 
863 {
864  return (subDetId == StripSubdetector::TIB ||
865  subDetId == StripSubdetector::TOB ||
866  subDetId == PixelSubdetector::PixelBarrel );
867 }
868 
869 
871 {
872  return ( subDetId == StripSubdetector::TID ||
873  subDetId == StripSubdetector::TEC ||
874  subDetId == PixelSubdetector::PixelEndcap );
875 }
876 
877 
879 {
880  return (subDetId == PixelSubdetector::PixelBarrel ||
881  subDetId == PixelSubdetector::PixelEndcap );
882 }
883 
884 
886 {
887  return ( type == align::AlignableDet ||
888  type == align::AlignableDetUnit );
889 }
890 
891 
892 void
895  int& nBinsX, double& lowerBoundX, double& upperBoundX)
896 {
897  // determine if
898  const bool isPixel = this->isPixel(subDetId);
899 
900  edm::ParameterSet binningPSet;
901 
902  switch(residualType)
903  {
904  case XResidual :
905  if(isPixel) binningPSet = parSet_.getParameter<edm::ParameterSet>("TH1XResPixelModules");
906  else binningPSet = parSet_.getParameter<edm::ParameterSet>("TH1XResStripModules");
907  break;
908  case NormXResidual :
909  if(isPixel) binningPSet = parSet_.getParameter<edm::ParameterSet>("TH1NormXResPixelModules");
910  else binningPSet = parSet_.getParameter<edm::ParameterSet>("TH1NormXResStripModules");
911  break;
912  case XprimeResidual :
913  if(isPixel) binningPSet = parSet_.getParameter<edm::ParameterSet>("TH1XprimeResPixelModules");
914  else binningPSet = parSet_.getParameter<edm::ParameterSet>("TH1XprimeResStripModules");
915  break;
916  case NormXprimeResidual :
917  if(isPixel) binningPSet = parSet_.getParameter<edm::ParameterSet>("TH1NormXprimeResPixelModules");
918  else binningPSet = parSet_.getParameter<edm::ParameterSet>("TH1NormXprimeResStripModules");
919  break;
920  case YResidual : // borrow y-residual binning from yprime
921  case YprimeResidual :
922  if(isPixel) binningPSet = parSet_.getParameter<edm::ParameterSet>("TH1YResPixelModules");
923  else binningPSet = parSet_.getParameter<edm::ParameterSet>("TH1YResStripModules");
924  break;
925  /* case NormYResidual :*/
926  case NormYprimeResidual :
927  if(isPixel) binningPSet = parSet_.getParameter<edm::ParameterSet>("TH1NormYResPixelModules");
928  else binningPSet = parSet_.getParameter<edm::ParameterSet>("TH1NormYResStripModules");
929  break;
930  case XResidualProfile :
931  if(isPixel) binningPSet = parSet_.getParameter<edm::ParameterSet>("TProfileXResPixelModules");
932  else binningPSet = parSet_.getParameter<edm::ParameterSet>("TProfileXResStripModules");
933  break;
934  case YResidualProfile :
935  if(isPixel) binningPSet = parSet_.getParameter<edm::ParameterSet>("TProfileYResPixelModules");
936  else binningPSet = parSet_.getParameter<edm::ParameterSet>("TProfileYResStripModules");
937  break;
938  }
939  nBinsX = binningPSet.getParameter<int32_t>("Nbinx");
940  lowerBoundX = binningPSet.getParameter<double>("xmin");
941  upperBoundX = binningPSet.getParameter<double>("xmax");
942 }
943 
944 
945 void
946 TrackerOfflineValidation::setSummaryBin(int bin, TH1* targetHist, TH1* sourceHist)
947 {
948  if(targetHist && sourceHist) {
949  targetHist->SetBinContent(bin, sourceHist->GetMean(1));
950  if(useFwhm_) targetHist->SetBinError(bin, Fwhm(sourceHist)/2.);
951  else targetHist->SetBinError(bin, sourceHist->GetRMS(1) );
952  }
953  else return;
954 }
955 
956 
957 void
959  SummaryContainer& sourceContainer)
960 {
961  summaryBins_.emplace_back(bin, targetContainer.summaryXResiduals_, sourceContainer.sumXResiduals_);
962  summaryBins_.emplace_back(bin, targetContainer.summaryNormXResiduals_, sourceContainer.sumNormXResiduals_);
963  // If no y-residual hists, just returns:
964  summaryBins_.emplace_back(bin, targetContainer.summaryYResiduals_, sourceContainer.sumYResiduals_);
965  summaryBins_.emplace_back(bin, targetContainer.summaryNormYResiduals_, sourceContainer.sumNormYResiduals_);
966 }
967 
968 
969 void
971  SummaryContainer& targetContainer,
972  ModuleHistos& sourceContainer)
973 {
974  // takes two summary Containers and sets summaryBins for all histograms
975  summaryBins_.emplace_back(bin, targetContainer.summaryXResiduals_, sourceContainer.ResXprimeHisto);
976  summaryBins_.emplace_back(bin, targetContainer.summaryNormXResiduals_, sourceContainer.NormResXprimeHisto);
977  if( this->isPixel(subDetId) || stripYResiduals_ ) {
978  summaryBins_.emplace_back(bin, targetContainer.summaryYResiduals_, sourceContainer.ResYprimeHisto);
979  summaryBins_.emplace_back(bin, targetContainer.summaryNormYResiduals_, sourceContainer.NormResYprimeHisto);
980  }
981 }
982 
983 
986 {
987  // get a struct with histograms from the respective map
988  // if no object exist, the reference is automatically created by the map
989  // throw exception if non-tracker id is passed
990  uint subdetid = detid.subdetId();
991  if(subdetid == PixelSubdetector::PixelBarrel ) {
992  return mPxbResiduals_[detid.rawId()];
993  } else if (subdetid == PixelSubdetector::PixelEndcap) {
994  return mPxeResiduals_[detid.rawId()];
995  } else if(subdetid == StripSubdetector::TIB) {
996  return mTibResiduals_[detid.rawId()];
997  } else if(subdetid == StripSubdetector::TID) {
998  return mTidResiduals_[detid.rawId()];
999  } else if(subdetid == StripSubdetector::TOB) {
1000  return mTobResiduals_[detid.rawId()];
1001  } else if(subdetid == StripSubdetector::TEC) {
1002  return mTecResiduals_[detid.rawId()];
1003  } else {
1004  throw cms::Exception("Geometry Error")
1005  << "[TrackerOfflineValidation] Error, tried to get reference for non-tracker subdet " << subdetid
1006  << " from detector " << detid.det();
1007  return mPxbResiduals_[0];
1008  }
1009 }
1010 
1011 
1012 // ------------ method called to for each event ------------
1013 void
1015 {
1016  if (maxTracks_ > 0 && nTracks_ >= maxTracks_) return; //don't do anything after hitting the max number of tracks
1017  //(could just rely on break below, but this way saves fillTrackQuantities)
1018 
1019  if (useOverflowForRMS_)TH1::StatOverflows(kTRUE);
1020  this->checkBookHists(iSetup); // check whether hists are booked and do so if not yet done
1021 
1022  std::vector<TrackerValidationVariables::AVTrackStruct> vTrackstruct;
1023  avalidator_.fillTrackQuantities(iEvent, iSetup, vTrackstruct);
1024 
1025  for (std::vector<TrackerValidationVariables::AVTrackStruct>::const_iterator itT = vTrackstruct.begin();
1026  itT != vTrackstruct.end();
1027  ++itT) {
1028 
1029  if (itT->charge * chargeCut_ < 0) continue;
1030 
1031  if (maxTracks_ > 0 && nTracks_++ >= maxTracks_) break; //exit the loop after hitting the max number of tracks
1032  // Fill 1D track histos
1033  static const int etaindex = this->GetIndex(vTrackHistos_,"h_tracketa");
1034  vTrackHistos_[etaindex]->Fill(itT->eta);
1035  static const int phiindex = this->GetIndex(vTrackHistos_,"h_trackphi");
1036  vTrackHistos_[phiindex]->Fill(itT->phi);
1037  static const int numOfValidHitsindex = this->GetIndex(vTrackHistos_,"h_trackNumberOfValidHits");
1038  vTrackHistos_[numOfValidHitsindex]->Fill(itT->numberOfValidHits);
1039  static const int numOfLostHitsindex = this->GetIndex(vTrackHistos_,"h_trackNumberOfLostHits");
1040  vTrackHistos_[numOfLostHitsindex]->Fill(itT->numberOfLostHits);
1041  static const int kappaindex = this->GetIndex(vTrackHistos_,"h_curvature");
1042  vTrackHistos_[kappaindex]->Fill(itT->kappa);
1043  static const int kappaposindex = this->GetIndex(vTrackHistos_,"h_curvature_pos");
1044  if (itT->charge > 0)
1045  vTrackHistos_[kappaposindex]->Fill(fabs(itT->kappa));
1046  static const int kappanegindex = this->GetIndex(vTrackHistos_,"h_curvature_neg");
1047  if (itT->charge < 0)
1048  vTrackHistos_[kappanegindex]->Fill(fabs(itT->kappa));
1049  static const int normchi2index = this->GetIndex(vTrackHistos_,"h_normchi2");
1050  vTrackHistos_[normchi2index]->Fill(itT->normchi2);
1051  static const int chi2index = this->GetIndex(vTrackHistos_,"h_chi2");
1052  vTrackHistos_[chi2index]->Fill(itT->chi2);
1053  static const int chi2Probindex = this->GetIndex(vTrackHistos_,"h_chi2Prob");
1054  vTrackHistos_[chi2Probindex]->Fill(itT->chi2Prob);
1055  static const int ptindex = this->GetIndex(vTrackHistos_,"h_pt");
1056  vTrackHistos_[ptindex]->Fill(itT->pt);
1057  if (itT->ptError != 0.) {
1058  static const int ptResolutionindex = this->GetIndex(vTrackHistos_,"h_ptResolution");
1059  vTrackHistos_[ptResolutionindex]->Fill(itT->ptError/itT->pt);
1060  }
1061  // Fill track profiles
1062  static const int d0phiindex = this->GetIndex(vTrackProfiles_,"p_d0_vs_phi");
1063  vTrackProfiles_[d0phiindex]->Fill(itT->phi,itT->d0);
1064  static const int dzphiindex = this->GetIndex(vTrackProfiles_,"p_dz_vs_phi");
1065  vTrackProfiles_[dzphiindex]->Fill(itT->phi,itT->dz);
1066  static const int d0etaindex = this->GetIndex(vTrackProfiles_,"p_d0_vs_eta");
1067  vTrackProfiles_[d0etaindex]->Fill(itT->eta,itT->d0);
1068  static const int dzetaindex = this->GetIndex(vTrackProfiles_,"p_dz_vs_eta");
1069  vTrackProfiles_[dzetaindex]->Fill(itT->eta,itT->dz);
1070  static const int chiphiindex = this->GetIndex(vTrackProfiles_,"p_chi2_vs_phi");
1071  vTrackProfiles_[chiphiindex]->Fill(itT->phi,itT->chi2);
1072  static const int chiProbphiindex = this->GetIndex(vTrackProfiles_,"p_chi2Prob_vs_phi");
1073  vTrackProfiles_[chiProbphiindex]->Fill(itT->phi,itT->chi2Prob);
1074  static const int chiProbabsd0index = this->GetIndex(vTrackProfiles_,"p_chi2Prob_vs_d0");
1075  vTrackProfiles_[chiProbabsd0index]->Fill(fabs(itT->d0),itT->chi2Prob);
1076  static const int normchiphiindex = this->GetIndex(vTrackProfiles_,"p_normchi2_vs_phi");
1077  vTrackProfiles_[normchiphiindex]->Fill(itT->phi,itT->normchi2);
1078  static const int chietaindex = this->GetIndex(vTrackProfiles_,"p_chi2_vs_eta");
1079  vTrackProfiles_[chietaindex]->Fill(itT->eta,itT->chi2);
1080  static const int normchiptindex = this->GetIndex(vTrackProfiles_,"p_normchi2_vs_pt");
1081  vTrackProfiles_[normchiptindex]->Fill(itT->pt,itT->normchi2);
1082  static const int normchipindex = this->GetIndex(vTrackProfiles_,"p_normchi2_vs_p");
1083  vTrackProfiles_[normchipindex]->Fill(itT->p,itT->normchi2);
1084  static const int chiProbetaindex = this->GetIndex(vTrackProfiles_,"p_chi2Prob_vs_eta");
1085  vTrackProfiles_[chiProbetaindex]->Fill(itT->eta,itT->chi2Prob);
1086  static const int normchietaindex = this->GetIndex(vTrackProfiles_,"p_normchi2_vs_eta");
1087  vTrackProfiles_[normchietaindex]->Fill(itT->eta,itT->normchi2);
1088  static const int kappaphiindex = this->GetIndex(vTrackProfiles_,"p_kappa_vs_phi");
1089  vTrackProfiles_[kappaphiindex]->Fill(itT->phi,itT->kappa);
1090  static const int kappaetaindex = this->GetIndex(vTrackProfiles_,"p_kappa_vs_eta");
1091  vTrackProfiles_[kappaetaindex]->Fill(itT->eta,itT->kappa);
1092  static const int ptResphiindex = this->GetIndex(vTrackProfiles_,"p_ptResolution_vs_phi");
1093  vTrackProfiles_[ptResphiindex]->Fill(itT->phi,itT->ptError/itT->pt);
1094  static const int ptResetaindex = this->GetIndex(vTrackProfiles_,"p_ptResolution_vs_eta");
1095  vTrackProfiles_[ptResetaindex]->Fill(itT->eta,itT->ptError/itT->pt);
1096 
1097  // Fill 2D track histos
1098  static const int d0phiindex_2d = this->GetIndex(vTrack2DHistos_,"h2_d0_vs_phi");
1099  vTrack2DHistos_[d0phiindex_2d]->Fill(itT->phi,itT->d0);
1100  static const int dzphiindex_2d = this->GetIndex(vTrack2DHistos_,"h2_dz_vs_phi");
1101  vTrack2DHistos_[dzphiindex_2d]->Fill(itT->phi,itT->dz);
1102  static const int d0etaindex_2d = this->GetIndex(vTrack2DHistos_,"h2_d0_vs_eta");
1103  vTrack2DHistos_[d0etaindex_2d]->Fill(itT->eta,itT->d0);
1104  static const int dzetaindex_2d = this->GetIndex(vTrack2DHistos_,"h2_dz_vs_eta");
1105  vTrack2DHistos_[dzetaindex_2d]->Fill(itT->eta,itT->dz);
1106  static const int chiphiindex_2d = this->GetIndex(vTrack2DHistos_,"h2_chi2_vs_phi");
1107  vTrack2DHistos_[chiphiindex_2d]->Fill(itT->phi,itT->chi2);
1108  static const int chiProbphiindex_2d = this->GetIndex(vTrack2DHistos_,"h2_chi2Prob_vs_phi");
1109  vTrack2DHistos_[chiProbphiindex_2d]->Fill(itT->phi,itT->chi2Prob);
1110  static const int chiProbabsd0index_2d = this->GetIndex(vTrack2DHistos_,"h2_chi2Prob_vs_d0");
1111  vTrack2DHistos_[chiProbabsd0index_2d]->Fill(fabs(itT->d0),itT->chi2Prob);
1112  static const int normchiphiindex_2d = this->GetIndex(vTrack2DHistos_,"h2_normchi2_vs_phi");
1113  vTrack2DHistos_[normchiphiindex_2d]->Fill(itT->phi,itT->normchi2);
1114  static const int chietaindex_2d = this->GetIndex(vTrack2DHistos_,"h2_chi2_vs_eta");
1115  vTrack2DHistos_[chietaindex_2d]->Fill(itT->eta,itT->chi2);
1116  static const int chiProbetaindex_2d = this->GetIndex(vTrack2DHistos_,"h2_chi2Prob_vs_eta");
1117  vTrack2DHistos_[chiProbetaindex_2d]->Fill(itT->eta,itT->chi2Prob);
1118  static const int normchietaindex_2d = this->GetIndex(vTrack2DHistos_,"h2_normchi2_vs_eta");
1119  vTrack2DHistos_[normchietaindex_2d]->Fill(itT->eta,itT->normchi2);
1120  static const int kappaphiindex_2d = this->GetIndex(vTrack2DHistos_,"h2_kappa_vs_phi");
1121  vTrack2DHistos_[kappaphiindex_2d]->Fill(itT->phi,itT->kappa);
1122  static const int kappaetaindex_2d = this->GetIndex(vTrack2DHistos_,"h2_kappa_vs_eta");
1123  vTrack2DHistos_[kappaetaindex_2d]->Fill(itT->eta,itT->kappa);
1124  static const int normchi2kappa_2d = this->GetIndex(vTrack2DHistos_,"h2_normchi2_vs_kappa");
1125  vTrack2DHistos_[normchi2kappa_2d]->Fill(itT->normchi2,itT->kappa);
1126 
1127  // hit quantities: residuals, normalized residuals
1128  for (std::vector<TrackerValidationVariables::AVHitStruct>::const_iterator itH = itT->hits.begin();
1129  itH != itT->hits.end();
1130  ++itH) {
1131 
1132  DetId detid(itH->rawDetId);
1133  ModuleHistos &histStruct = this->getHistStructFromMap(detid);
1134 
1135  // fill histos in local coordinates if set in cf
1136  if (lCoorHistOn_) {
1137  histStruct.ResHisto->Fill(itH->resX);
1138  if(itH->resErrX != 0) histStruct.NormResHisto->Fill(itH->resX/itH->resErrX);
1139  if (this->isPixel(detid.subdetId()) || stripYResiduals_ ) {
1140  histStruct.ResYHisto->Fill(itH->resY);
1141  // here add un-primed normalised y-residuals if wanted
1142  }
1143  }
1144  if (itH->resXprime != -999.) {
1145  histStruct.ResXprimeHisto->Fill(itH->resXprime);
1146 
1147  /******************************* Fill 2-D histo ResX vs momenta *****************************/
1148  if (detid.subdetId() == PixelSubdetector::PixelBarrel) {
1149  static const int resXvsPindex_2d = this->GetIndex(vTrack2DHistos_,"p_vs_resXprime_pixB");
1150  vTrack2DHistos_[resXvsPindex_2d]->Fill(itT->p,itH->resXprime);
1151  }
1152  if (detid.subdetId() == PixelSubdetector::PixelEndcap) {
1153  static const int resXvsPindex_2d = this->GetIndex(vTrack2DHistos_,"p_vs_resXprime_pixE");
1154  vTrack2DHistos_[resXvsPindex_2d]->Fill(itT->p,itH->resXprime);
1155  }
1156  if (detid.subdetId() == StripSubdetector::TIB) {
1157  static const int resXvsPindex_2d = this->GetIndex(vTrack2DHistos_,"p_vs_resXprime_TIB");
1158  vTrack2DHistos_[resXvsPindex_2d]->Fill(itT->p,itH->resXprime);
1159  }
1160  if (detid.subdetId() == StripSubdetector::TID) {
1161  static const int resXvsPindex_2d = this->GetIndex(vTrack2DHistos_,"p_vs_resXprime_TID");
1162  vTrack2DHistos_[resXvsPindex_2d]->Fill(itT->p,itH->resXprime);
1163  }
1164  if (detid.subdetId() == StripSubdetector::TOB) {
1165  static const int resXvsPindex_2d = this->GetIndex(vTrack2DHistos_,"p_vs_resXprime_TOB");
1166  vTrack2DHistos_[resXvsPindex_2d]->Fill(itT->p,itH->resXprime);
1167  }
1168  if (detid.subdetId() == StripSubdetector::TEC) {
1169  static const int resXvsPindex_2d = this->GetIndex(vTrack2DHistos_,"p_vs_resXprime_TEC");
1170  vTrack2DHistos_[resXvsPindex_2d]->Fill(itT->p,itH->resXprime);
1171  }
1172  /******************************************/
1173 
1174  if ( moduleLevelProfiles_ && itH->inside ) {
1175  float tgalpha = tan(itH->localAlpha);
1176  if ( fabs(tgalpha)!=0 ){
1177  histStruct.LocalX->Fill(itH->localXnorm, tgalpha*tgalpha);
1178  histStruct.LocalY->Fill(itH->localYnorm, tgalpha*tgalpha);
1179 /* if (this->isEndCap(detid.subdetId()) && !this->isPixel(detid.subdetId())) {
1180  if((itH->resX)*(itH->resXprime)>0){
1181  histStruct.ResXvsXProfile->Fill(itH->localXnorm, itH->resXatTrkY/tgalpha, tgalpha*tgalpha);
1182  histStruct.ResXvsYProfile->Fill(itH->localYnorm, itH->resXatTrkY/tgalpha, tgalpha*tgalpha);
1183  } else {
1184  histStruct.ResXvsXProfile->Fill(itH->localXnorm, (-1)*itH->resXatTrkY/tgalpha, tgalpha*tgalpha);
1185  histStruct.ResXvsYProfile->Fill(itH->localYnorm, (-1)*itH->resXatTrkY/tgalpha, tgalpha*tgalpha);
1186  }
1187 
1188  }else {
1189 */
1190  histStruct.ResXvsXProfile->Fill(itH->localXnorm, itH->resXatTrkY/tgalpha, tgalpha*tgalpha);
1191  histStruct.ResXvsYProfile->Fill(itH->localYnorm, itH->resXatTrkY/tgalpha, tgalpha*tgalpha);
1192 
1193 // }
1194 
1195  }
1196  }
1197 
1198  if(itH->resXprimeErr != 0 && itH->resXprimeErr != -999 ) {
1199  histStruct.NormResXprimeHisto->Fill(itH->resXprime/itH->resXprimeErr);
1200  }
1201  }
1202 
1203  if (itH->resYprime != -999.) {
1204  if (this->isPixel(detid.subdetId()) || stripYResiduals_ ) {
1205  histStruct.ResYprimeHisto->Fill(itH->resYprime);
1206 
1207  /******************************* Fill 2-D histo ResY vs momenta *****************************/
1208  if (detid.subdetId() == PixelSubdetector::PixelBarrel) {
1209  static const int resYvsPindex_2d = this->GetIndex(vTrack2DHistos_,"p_vs_resYprime_pixB");
1210  vTrack2DHistos_[resYvsPindex_2d]->Fill(itT->p,itH->resYprime);
1211  }
1212  if (detid.subdetId() == PixelSubdetector::PixelEndcap) {
1213  static const int resYvsPindex_2d = this->GetIndex(vTrack2DHistos_,"p_vs_resYprime_pixE");
1214  vTrack2DHistos_[resYvsPindex_2d]->Fill(itT->p,itH->resYprime);
1215  }
1216  /******************************************/
1217 
1218  if ( moduleLevelProfiles_ && itH->inside ) {
1219  float tgbeta = tan(itH->localBeta);
1220  if ( fabs(tgbeta)!=0 ){
1221 /* if (this->isEndCap(detid.subdetId()) && !this->isPixel(detid.subdetId())) {
1222 
1223  if((itH->resY)*(itH->resYprime)>0){
1224  histStruct.ResYvsXProfile->Fill(itH->localXnorm, itH->resYprime/tgbeta, tgbeta*tgbeta);
1225  histStruct.ResYvsYProfile->Fill(itH->localYnorm, itH->resYprime/tgbeta, tgbeta*tgbeta);
1226  } else {
1227  histStruct.ResYvsXProfile->Fill(itH->localXnorm, (-1)*itH->resYprime/tgbeta, tgbeta*tgbeta);
1228  histStruct.ResYvsYProfile->Fill(itH->localYnorm, (-1)*itH->resYprime/tgbeta, tgbeta*tgbeta);
1229  }
1230 
1231  }else {
1232 */
1233  histStruct.ResYvsXProfile->Fill(itH->localXnorm, itH->resY/tgbeta, tgbeta*tgbeta);
1234  histStruct.ResYvsYProfile->Fill(itH->localYnorm, itH->resY/tgbeta, tgbeta*tgbeta);
1235 // }
1236  }
1237  }
1238 
1239  if (itH->resYprimeErr != 0 && itH->resYprimeErr != -999. ) {
1240  histStruct.NormResYprimeHisto->Fill(itH->resYprime/itH->resYprimeErr);
1241  }
1242  }
1243  }
1244 
1245  } // finish loop over hit quantities
1246  } // finish loop over track quantities
1247 
1248  if (useOverflowForRMS_) TH1::StatOverflows(kFALSE);
1249 }
1250 
1251 
1252 // ------------ method called once each job just after ending the event loop ------------
1253 void
1255 {
1256  if (!tkGeom_.product()) return;
1257 
1258  static const int kappadiffindex = this->GetIndex(vTrackHistos_,"h_diff_curvature");
1259  vTrackHistos_[kappadiffindex]->Add(vTrackHistos_[this->GetIndex(vTrackHistos_,"h_curvature_neg")],
1260  vTrackHistos_[this->GetIndex(vTrackHistos_,"h_curvature_pos")],-1,1);
1261 
1262  // Collate Information for Subdetectors
1263  // create summary histograms recursively
1264  this->collateSummaryHists();
1265 
1266  if (dqmMode_) return;
1267  // Should be excluded in dqmMode, since TTree is not usable
1268  // In dqmMode tree operations are are sourced out to the additional module TrackerOfflineValidationSummary
1269 
1271  TTree *tree = fs->make<TTree>("TkOffVal","TkOffVal");
1272 
1273  TkOffTreeVariables *treeMemPtr = new TkOffTreeVariables;
1274  // We create branches for all members of 'TkOffTreeVariables' (even if not needed).
1275  // This works because we have a dictionary for 'TkOffTreeVariables'
1276  // (see src/classes_def.xml and src/classes.h):
1277  tree->Branch("TkOffTreeVariables", &treeMemPtr); // address of pointer!
1278 
1279  this->fillTree(*tree, *treeMemPtr, mPxbResiduals_);
1280  this->fillTree(*tree, *treeMemPtr, mPxeResiduals_);
1281  this->fillTree(*tree, *treeMemPtr, mTibResiduals_);
1282  this->fillTree(*tree, *treeMemPtr, mTidResiduals_);
1283  this->fillTree(*tree, *treeMemPtr, mTobResiduals_);
1284  this->fillTree(*tree, *treeMemPtr, mTecResiduals_);
1285 
1286  delete treeMemPtr; treeMemPtr = nullptr;
1287 }
1288 
1289 
1290 void
1292  std::vector<TrackerOfflineValidation::SummaryContainer>& vLevelProfiles)
1293 {
1294  const auto& alivec = ali.components();
1295  if( this->isDetOrDetUnit((alivec)[0]->alignableObjectId()) ) return;
1296 
1297  for(int iComp=0, iCompEnd = ali.components().size();iComp < iCompEnd; ++iComp) {
1298  std::vector< TrackerOfflineValidation::SummaryContainer > vProfiles;
1299  std::string structurename = alignableTracker_->objectIdProvider().idToString((alivec)[iComp]->alignableObjectId());
1300 
1301  LogDebug("TrackerOfflineValidation") << "StructureName = " << structurename;
1302  std::stringstream dirname;
1303  dirname << structurename;
1304 
1305  // add no suffix counter to strip and pixel -> just aesthetics
1306  if (structurename != "Strip" && structurename != "Pixel") dirname << "_" << iComp+1;
1307 
1308  if( !(this->isDetOrDetUnit( (alivec)[iComp]->alignableObjectId()) )
1309  || (alivec)[0]->components().size() > 1 ) {
1310  DirectoryWrapper f(tfd,dirname.str(),moduleDirectory_,dqmMode_);
1311  this->prepareSummaryHists( f, *(alivec)[iComp], vProfiles);
1312  vLevelProfiles.push_back(this->bookSummaryHists(tfd, *(alivec[iComp]), ali.alignableObjectId(), iComp+1));
1313  TH1 *hX = vLevelProfiles[iComp].sumXResiduals_;
1314  TH1 *hNormX = vLevelProfiles[iComp].sumNormXResiduals_;
1315  TH1 *hY = vLevelProfiles[iComp].sumYResiduals_;
1316  TH1 *hNormY = vLevelProfiles[iComp].sumNormYResiduals_;
1317  TH1 *pXX = vLevelProfiles[iComp].sumResXvsXProfile_;
1318  TH1 *pXY = vLevelProfiles[iComp].sumResXvsYProfile_;
1319  TH1 *pYX = vLevelProfiles[iComp].sumResYvsXProfile_;
1320  TH1 *pYY = vLevelProfiles[iComp].sumResYvsYProfile_;
1321  for(uint n = 0; n < vProfiles.size(); ++n) {
1322  this->summarizeBinInContainer(n+1, vLevelProfiles[iComp], vProfiles[n]);
1323  sumHistStructure_.emplace_back(hX, vProfiles[n].sumXResiduals_);
1324  sumHistStructure_.emplace_back(hNormX, vProfiles[n].sumNormXResiduals_);
1325  if (hY) sumHistStructure_.emplace_back(hY, vProfiles[n].sumYResiduals_); // only if existing
1326  if (hNormY) sumHistStructure_.emplace_back(hNormY, vProfiles[n].sumNormYResiduals_); // ditto (pxl, stripYResiduals_)
1327  if (pXX) sumHistStructure_.emplace_back(pXX, vProfiles[n].sumResXvsXProfile_);
1328  if (pXY) sumHistStructure_.emplace_back(pXY, vProfiles[n].sumResXvsYProfile_);
1329  if (pYX) sumHistStructure_.emplace_back(pYX, vProfiles[n].sumResYvsXProfile_);
1330  if (pYY) sumHistStructure_.emplace_back(pYY, vProfiles[n].sumResYvsYProfile_);
1331  }
1332  if(dqmMode_)continue; // No fits in dqmMode
1333  //add fit values to stat box
1334  toFit_.push_back(vLevelProfiles[iComp].sumXResiduals_);
1335  toFit_.push_back(vLevelProfiles[iComp].sumNormXResiduals_);
1336  if (hY) toFit_.push_back(hY); // only if existing (pixel or stripYResiduals_)
1337  if (hNormY) toFit_.push_back(hNormY); // ditto
1338  } else {
1339  // nothing to be done for det or detunits
1340  continue;
1341  }
1342  }
1343 }
1344 
1345 void
1347 {
1348  for (std::vector<std::pair<TH1*,TH1*> >::const_iterator it = sumHistStructure_.begin();
1349  it != sumHistStructure_.end();
1350  ++it)
1351  it->first->Add(it->second);
1352 
1353  for (std::vector<std::tuple<int,TH1*,TH1*> >::const_iterator it = summaryBins_.begin();
1354  it != summaryBins_.end();
1355  ++it)
1356  setSummaryBin(std::get<0>(*it), std::get<1>(*it), std::get<2>(*it));
1357 
1358  for (std::vector<TH1*>::const_iterator it = toFit_.begin();
1359  it != toFit_.end();
1360  ++it)
1361  fitResiduals(*it);
1362 }
1363 
1364 
1367  align::StructureType type, int i)
1368 {
1369  const uint aliSize = ali.components().size();
1370  const align::StructureType alitype = ali.alignableObjectId();
1371  const align::StructureType subtype = ali.components()[0]->alignableObjectId();
1372  const char *aliTypeName = alignableTracker_->objectIdProvider().idToString(alitype); // lifetime of char* OK
1373  const char *aliSubtypeName = alignableTracker_->objectIdProvider().idToString(subtype);
1374  const char *typeName = alignableTracker_->objectIdProvider().idToString(type);
1375 
1376  const DetId aliDetId = ali.id();
1377  // y residuals only if pixel or specially requested for strip:
1378  const bool bookResidY = this->isPixel(aliDetId.subdetId()) || stripYResiduals_;
1379 
1380  SummaryContainer sumContainer;
1381 
1382  // Book summary hists with one bin per component,
1383  // but special case for Det with two DetUnit that we want to summarize one level up
1384  // (e.g. in TOBRods with 12 bins for 6 stereo and 6 rphi DetUnit.)
1385  // component of ali is not Det or Det with just one components
1386  const uint subcompSize = ali.components()[0]->components().size();
1387  if (subtype != align::AlignableDet || subcompSize == 1) { // Det with 1 comp. should not exist anymore...
1388  const TString title(Form("Summary for substructures in %s %d;%s;",aliTypeName,i,aliSubtypeName));
1389 
1390  sumContainer.summaryXResiduals_ = tfd.make<TH1F>(Form("h_summaryX%s_%d",aliTypeName,i),
1391  title + "#LT #Delta x' #GT",
1392  aliSize, 0.5, aliSize+0.5);
1393  sumContainer.summaryNormXResiduals_ = tfd.make<TH1F>(Form("h_summaryNormX%s_%d",aliTypeName,i),
1394  title + "#LT #Delta x'/#sigma #GT",
1395  aliSize,0.5,aliSize+0.5);
1396 
1397  if (bookResidY) {
1398  sumContainer.summaryYResiduals_ = tfd.make<TH1F>(Form("h_summaryY%s_%d",aliTypeName,i),
1399  title + "#LT #Delta y' #GT",
1400  aliSize, 0.5, aliSize+0.5);
1401  sumContainer.summaryNormYResiduals_ = tfd.make<TH1F>(Form("h_summaryNormY%s_%d",aliTypeName,i),
1402  title + "#LT #Delta y'/#sigma #GT",
1403  aliSize,0.5,aliSize+0.5);
1404  }
1405 
1406  } else if (subtype == align::AlignableDet && subcompSize > 1) { // fixed: was aliSize before
1407  if (subcompSize != 2) { // strange... expect only 2 DetUnits in DS layers
1408  // this 2 is hardcoded factor 2 in binning below and also assumed later on
1409  edm::LogError("Alignment") << "@SUB=bookSummaryHists"
1410  << "Det with " << subcompSize << " components";
1411  }
1412  // title contains x-title
1413  const TString title(Form("Summary for substructures in %s %d;%s;", aliTypeName, i,
1414  alignableTracker_->objectIdProvider().idToString(ali.components()[0]->components()[0]->alignableObjectId())));
1415 
1416  sumContainer.summaryXResiduals_
1417  = tfd.make<TH1F>(Form("h_summaryX%s_%d", aliTypeName, i),
1418  title + "#LT #Delta x' #GT", (2*aliSize), 0.5, 2*aliSize+0.5);
1419  sumContainer.summaryNormXResiduals_
1420  = tfd.make<TH1F>(Form("h_summaryNormX%s_%d", aliTypeName, i),
1421  title + "#LT #Delta x'/#sigma #GT", (2*aliSize), 0.5, 2*aliSize+0.5);
1422 
1423  if (bookResidY) {
1424  sumContainer.summaryYResiduals_
1425  = tfd.make<TH1F>(Form("h_summaryY%s_%d", aliTypeName, i),
1426  title + "#LT #Delta y' #GT", (2*aliSize), 0.5, 2*aliSize+0.5);
1427  sumContainer.summaryNormYResiduals_
1428  = tfd.make<TH1F>(Form("h_summaryNormY%s_%d", aliTypeName, i),
1429  title + "#LT #Delta y'/#sigma #GT", (2*aliSize), 0.5, 2*aliSize+0.5);
1430  }
1431 
1432  } else {
1433  edm::LogError("TrackerOfflineValidation") << "@SUB=TrackerOfflineValidation::bookSummaryHists"
1434  << "No summary histogram for hierarchy level "
1435  << aliTypeName << " in subdet " << aliDetId.subdetId();
1436  }
1437 
1438  // Now book hists that just sum up the residual histograms from lower levels.
1439  // Axis title is copied from lowest level module of structure.
1440  // Should be safe that y-hists are only touched if non-null pointers...
1441  int nbins = 0;
1442  double xmin = 0., xmax = 0.;
1443  const TString sumTitle(Form("Residual for %s %d in %s;", aliTypeName, i, typeName));
1444  const ModuleHistos &xTitHists = this->getHistStructFromMap(aliDetId); // for x-axis titles
1445  this->getBinning(aliDetId.subdetId(), XprimeResidual, nbins, xmin, xmax);
1446 
1447  sumContainer.sumXResiduals_ = tfd.make<TH1F>(Form("h_Xprime_%s_%d", aliTypeName, i),
1448  sumTitle + xTitHists.ResXprimeHisto->GetXaxis()->GetTitle(),
1449  nbins, xmin, xmax);
1450 
1451  this->getBinning(aliDetId.subdetId(), NormXprimeResidual, nbins, xmin, xmax);
1452  sumContainer.sumNormXResiduals_ = tfd.make<TH1F>(Form("h_NormXprime_%s_%d",aliTypeName,i),
1453  sumTitle + xTitHists.NormResXprimeHisto->GetXaxis()->GetTitle(),
1454  nbins, xmin, xmax);
1455 
1456  if ( moduleLevelProfiles_ ) {
1457  this->getBinning(aliDetId.subdetId(), XResidualProfile, nbins, xmin, xmax);
1458  sumContainer.sumResXvsXProfile_ = tfd.make<TProfile>(Form("p_resXX_%s_%d",aliTypeName,i),
1459  sumTitle + xTitHists.ResXvsXProfile->GetXaxis()->GetTitle()
1460  + ";" + xTitHists.ResXvsXProfile->GetYaxis()->GetTitle(),
1461  nbins, xmin, xmax);
1462  sumContainer.sumResXvsXProfile_->Sumw2();
1463  sumContainer.sumResXvsYProfile_ = tfd.make<TProfile>(Form("p_resXY_%s_%d",aliTypeName,i),
1464  sumTitle + xTitHists.ResXvsYProfile->GetXaxis()->GetTitle()
1465  + ";" + xTitHists.ResXvsYProfile->GetYaxis()->GetTitle(),
1466  nbins, xmin, xmax);
1467  sumContainer.sumResXvsYProfile_->Sumw2();
1468  }
1469 
1470  if (bookResidY) {
1471  this->getBinning(aliDetId.subdetId(), YprimeResidual, nbins, xmin, xmax);
1472  sumContainer.sumYResiduals_ = tfd.make<TH1F>(Form("h_Yprime_%s_%d",aliTypeName,i),
1473  sumTitle + xTitHists.ResYprimeHisto->GetXaxis()->GetTitle(),
1474  nbins, xmin, xmax);
1475 
1476  this->getBinning(aliDetId.subdetId(), NormYprimeResidual, nbins, xmin, xmax);
1477  sumContainer.sumNormYResiduals_ = tfd.make<TH1F>(Form("h_NormYprime_%s_%d",aliTypeName,i),
1478  sumTitle + xTitHists.NormResYprimeHisto->GetXaxis()->GetTitle(),
1479  nbins, xmin, xmax);
1480 
1481  if ( moduleLevelProfiles_ ) {
1482  this->getBinning(aliDetId.subdetId(), YResidualProfile, nbins, xmin, xmax);
1483  sumContainer.sumResYvsXProfile_ = tfd.make<TProfile>(Form("p_resYX_%s_%d",aliTypeName,i),
1484  sumTitle + xTitHists.ResYvsXProfile->GetXaxis()->GetTitle()
1485  + ";" + xTitHists.ResYvsXProfile->GetYaxis()->GetTitle(),
1486  nbins, xmin, xmax);
1487  sumContainer.sumResYvsXProfile_->Sumw2();
1488  sumContainer.sumResYvsYProfile_ = tfd.make<TProfile>(Form("p_resYY_%s_%d",aliTypeName,i),
1489  sumTitle + xTitHists.ResYvsYProfile->GetXaxis()->GetTitle()
1490  + ";" + xTitHists.ResYvsYProfile->GetYaxis()->GetTitle(),
1491  nbins, xmin, xmax);
1492  sumContainer.sumResYvsYProfile_->Sumw2();
1493  }
1494  }
1495 
1496  // If we are at the lowest level, we already sum up and fill the summary.
1497 
1498  // special case I: For DetUnits and Dets with only one subcomponent start filling summary histos
1499  if( ( subtype == align::AlignableDet && subcompSize == 1) || subtype == align::AlignableDetUnit ) {
1500  for(uint k = 0; k < aliSize; ++k) {
1501  DetId detid = ali.components()[k]->id();
1502  ModuleHistos &histStruct = this->getHistStructFromMap(detid);
1503  this->summarizeBinInContainer(k+1, detid.subdetId(), sumContainer, histStruct);
1504  sumHistStructure_.emplace_back(sumContainer.sumXResiduals_, histStruct.ResXprimeHisto);
1505  sumHistStructure_.emplace_back(sumContainer.sumNormXResiduals_, histStruct.NormResXprimeHisto);
1506  if ( moduleLevelProfiles_ ) {
1507  sumHistStructure_.emplace_back(sumContainer.sumResXvsXProfile_, histStruct.ResXvsXProfile);
1508  sumHistStructure_.emplace_back(sumContainer.sumResXvsYProfile_, histStruct.ResXvsYProfile);
1509  }
1510  if( this->isPixel(detid.subdetId()) || stripYResiduals_ ) {
1511  sumHistStructure_.emplace_back(sumContainer.sumYResiduals_, histStruct.ResYprimeHisto);
1512  sumHistStructure_.emplace_back(sumContainer.sumNormYResiduals_, histStruct.NormResYprimeHisto);
1513  if ( moduleLevelProfiles_ ) {
1514  sumHistStructure_.emplace_back(sumContainer.sumResYvsXProfile_, histStruct.ResYvsXProfile);
1515  sumHistStructure_.emplace_back(sumContainer.sumResYvsYProfile_, histStruct.ResYvsYProfile);
1516  }
1517  }
1518  }
1519  } else if( subtype == align::AlignableDet && subcompSize > 1) { // fixed: was aliSize before
1520  // special case II: Fill summary histos for dets with two detunits
1521  for(uint k = 0; k < aliSize; ++k) {
1522  for(uint j = 0; j < subcompSize; ++j) { // assumes all have same size (as binning does)
1523  DetId detid = ali.components()[k]->components()[j]->id();
1524  ModuleHistos &histStruct = this->getHistStructFromMap(detid);
1525  this->summarizeBinInContainer(2*k+j+1, detid.subdetId(), sumContainer, histStruct );
1526  sumHistStructure_.emplace_back(sumContainer.sumXResiduals_, histStruct.ResXprimeHisto);
1527  sumHistStructure_.emplace_back(sumContainer.sumNormXResiduals_, histStruct.NormResXprimeHisto);
1528  if ( moduleLevelProfiles_ ) {
1529  sumHistStructure_.emplace_back(sumContainer.sumResXvsXProfile_, histStruct.ResXvsXProfile);
1530  sumHistStructure_.emplace_back(sumContainer.sumResXvsYProfile_, histStruct.ResXvsYProfile);
1531  }
1532  if( this->isPixel(detid.subdetId()) || stripYResiduals_ ) {
1533  sumHistStructure_.emplace_back(sumContainer.sumYResiduals_, histStruct.ResYprimeHisto);
1534  sumHistStructure_.emplace_back(sumContainer.sumNormYResiduals_, histStruct.NormResYprimeHisto);
1535  if ( moduleLevelProfiles_ ) {
1536  sumHistStructure_.emplace_back(sumContainer.sumResYvsXProfile_, histStruct.ResYvsXProfile);
1537  sumHistStructure_.emplace_back(sumContainer.sumResYvsYProfile_, histStruct.ResYvsYProfile);
1538  }
1539  }
1540  }
1541  }
1542  }
1543  return sumContainer;
1544 }
1545 
1546 
1547 float
1549 {
1550  float max = hist->GetMaximum();
1551  int left = -1, right = -1;
1552  for(unsigned int i = 1, iEnd = hist->GetNbinsX(); i <= iEnd; ++i) {
1553  if(hist->GetBinContent(i) < max/2. && hist->GetBinContent(i+1) > max/2. && left == -1) {
1554  if(max/2. - hist->GetBinContent(i) < hist->GetBinContent(i+1) - max/2.) {
1555  left = i;
1556  ++i;
1557  } else {
1558  left = i+1;
1559  ++i;
1560  }
1561  }
1562  if(left != -1 && right == -1) {
1563  if(hist->GetBinContent(i) > max/2. && hist->GetBinContent(i+1) < max/2.) {
1564  if( hist->GetBinContent(i) - max/2. < max/2. - hist->GetBinContent(i+1)) {
1565  right = i;
1566  } else {
1567  right = i+1;
1568  }
1569 
1570  }
1571  }
1572  }
1573  return hist->GetXaxis()->GetBinCenter(right) - hist->GetXaxis()->GetBinCenter(left);
1574 }
1575 
1576 
1577 void
1578 TrackerOfflineValidation::setUpTreeMembers(const std::map<int, TrackerOfflineValidation::ModuleHistos>& moduleHist_,
1579  const TrackerGeometry& tkgeom, const TrackerTopology* tTopo)
1580 {
1581 
1582  for(std::map<int, TrackerOfflineValidation::ModuleHistos>::const_iterator it = moduleHist_.begin(),
1583  itEnd= moduleHist_.end(); it != itEnd;++it ) {
1584  TkOffTreeVariables &treeMem = mTreeMembers_[it->first];
1585 
1586  //variables concerning the tracker components/hierarchy levels
1587  DetId detId_ = it->first;
1588  treeMem.moduleId = detId_;
1589  treeMem.subDetId = detId_.subdetId();
1590  treeMem.isDoubleSide =false;
1591 
1592  if(treeMem.subDetId == PixelSubdetector::PixelBarrel){
1593  unsigned int whichHalfBarrel(1), rawId(detId_.rawId()); //DetId does not know about halfBarrels is PXB ...
1594  if( (rawId>=302056964 && rawId<302059300) || (rawId>=302123268 && rawId<302127140) ||
1595  (rawId>=302189572 && rawId<302194980) ) whichHalfBarrel=2;
1596  treeMem.layer = tTopo->pxbLayer(detId_);
1597  treeMem.half = whichHalfBarrel;
1598  treeMem.rod = tTopo->pxbLadder(detId_); // ... so, ladder is not per halfBarrel-Layer, but per barrel-layer!
1599  treeMem.module = tTopo->pxbModule(detId_);
1600  } else if(treeMem.subDetId == PixelSubdetector::PixelEndcap){
1601  unsigned int whichHalfCylinder(1), rawId(detId_.rawId()); //DetId does not kmow about halfCylinders in PXF
1602  if( (rawId>=352394500 && rawId<352406032) || (rawId>=352460036 && rawId<352471568) ||
1603  (rawId>=344005892 && rawId<344017424) || (rawId>=344071428 && rawId<344082960) ) whichHalfCylinder=2;
1604  treeMem.layer = tTopo->pxfDisk(detId_);
1605  treeMem.side = tTopo->pxfSide(detId_);
1606  treeMem.half = whichHalfCylinder;
1607  treeMem.blade = tTopo->pxfBlade(detId_);
1608  treeMem.panel = tTopo->pxfPanel(detId_);
1609  treeMem.module = tTopo->pxfModule(detId_);
1610  } else if(treeMem.subDetId == StripSubdetector::TIB){
1611  unsigned int whichHalfShell(1), rawId(detId_.rawId()); //DetId does not kmow about halfShells in TIB
1612  if ( (rawId>=369120484 && rawId<369120688) || (rawId>=369121540 && rawId<369121776) ||
1613  (rawId>=369136932 && rawId<369137200) || (rawId>=369137988 && rawId<369138288) ||
1614  (rawId>=369153396 && rawId<369153744) || (rawId>=369154436 && rawId<369154800) ||
1615  (rawId>=369169844 && rawId<369170256) || (rawId>=369170900 && rawId<369171344) ||
1616  (rawId>=369124580 && rawId<369124784) || (rawId>=369125636 && rawId<369125872) ||
1617  (rawId>=369141028 && rawId<369141296) || (rawId>=369142084 && rawId<369142384) ||
1618  (rawId>=369157492 && rawId<369157840) || (rawId>=369158532 && rawId<369158896) ||
1619  (rawId>=369173940 && rawId<369174352) || (rawId>=369174996 && rawId<369175440) ) whichHalfShell=2;
1620  treeMem.layer = tTopo->tibLayer(detId_);
1621  treeMem.side = tTopo->tibStringInfo(detId_)[0];
1622  treeMem.half = whichHalfShell;
1623  treeMem.rod = tTopo->tibStringInfo(detId_)[2];
1624  treeMem.outerInner = tTopo->tibStringInfo(detId_)[1];
1625  treeMem.module = tTopo->tibModule(detId_);
1626  treeMem.isStereo = tTopo->tibStereo(detId_);
1627  treeMem.isDoubleSide = tTopo->tibIsDoubleSide(detId_);
1628  } else if(treeMem.subDetId == StripSubdetector::TID){
1629  treeMem.layer = tTopo->tidWheel(detId_);
1630  treeMem.side = tTopo->tidSide(detId_);
1631  treeMem.ring = tTopo->tidRing(detId_);
1632  treeMem.outerInner = tTopo->tidModuleInfo(detId_)[0];
1633  treeMem.module = tTopo->tidModuleInfo(detId_)[1];
1634  treeMem.isStereo = tTopo->tidStereo(detId_);
1635  treeMem.isDoubleSide = tTopo->tidIsDoubleSide(detId_);
1636  } else if(treeMem.subDetId == StripSubdetector::TOB){
1637  treeMem.layer = tTopo->tobLayer(detId_);
1638  treeMem.side = tTopo->tobRodInfo(detId_)[0];
1639  treeMem.rod = tTopo->tobRodInfo(detId_)[1];
1640  treeMem.module = tTopo->tobModule(detId_);
1641  treeMem.isStereo = tTopo->tobStereo(detId_);
1642  treeMem.isDoubleSide = tTopo->tobIsDoubleSide(detId_);
1643  } else if(treeMem.subDetId == StripSubdetector::TEC) {
1644  treeMem.layer = tTopo->tecWheel(detId_);
1645  treeMem.side = tTopo->tecSide(detId_);
1646  treeMem.ring = tTopo->tecRing(detId_);
1647  treeMem.petal = tTopo->tecPetalInfo(detId_)[1];
1648  treeMem.outerInner = tTopo->tecPetalInfo(detId_)[0];
1649  treeMem.module = tTopo->tecModule(detId_);
1650  treeMem.isStereo = tTopo->tecStereo(detId_);
1651  treeMem.isDoubleSide = tTopo->tecIsDoubleSide(detId_);
1652  }
1653 
1654  //variables concerning the tracker geometry
1655  const Surface::PositionType &gPModule = tkgeom.idToDet(detId_)->position();
1656  treeMem.posPhi = gPModule.phi();
1657  treeMem.posEta = gPModule.eta();
1658  treeMem.posR = gPModule.perp();
1659  treeMem.posX = gPModule.x();
1660  treeMem.posY = gPModule.y();
1661  treeMem.posZ = gPModule.z();
1662 
1663  const Surface& surface = tkgeom.idToDet(detId_)->surface();
1664 
1665  //global Orientation of local coordinate system of dets/detUnits
1666  LocalPoint lUDirection(1.,0.,0.), lVDirection(0.,1.,0.), lWDirection(0.,0.,1.);
1667  GlobalPoint gUDirection = surface.toGlobal(lUDirection),
1668  gVDirection = surface.toGlobal(lVDirection),
1669  gWDirection = surface.toGlobal(lWDirection);
1670  double dR(999.), dPhi(999.), dZ(999.);
1672  dR = gWDirection.perp() - gPModule.perp();
1673  dPhi = deltaPhi(gUDirection.barePhi(),gPModule.barePhi());
1674  dZ = gVDirection.z() - gPModule.z();
1675  if(dZ>=0.)treeMem.rOrZDirection = 1; else treeMem.rOrZDirection = -1;
1676  }else if(treeMem.subDetId==PixelSubdetector::PixelEndcap){
1677  dR = gUDirection.perp() - gPModule.perp();
1678  dPhi = deltaPhi(gVDirection.barePhi(),gPModule.barePhi());
1679  dZ = gWDirection.z() - gPModule.z();
1680  if(dR>=0.)treeMem.rOrZDirection = 1; else treeMem.rOrZDirection = -1;
1681  }else if(treeMem.subDetId==StripSubdetector::TID || treeMem.subDetId==StripSubdetector::TEC){
1682  dR = gVDirection.perp() - gPModule.perp();
1683  dPhi = deltaPhi(gUDirection.barePhi(),gPModule.barePhi());
1684  dZ = gWDirection.z() - gPModule.z();
1685  if(dR>=0.)treeMem.rOrZDirection = 1; else treeMem.rOrZDirection = -1;
1686  }
1687  if(dR>=0.)treeMem.rDirection = 1; else treeMem.rDirection = -1;
1688  if(dPhi>=0.)treeMem.phiDirection = 1; else treeMem.phiDirection = -1;
1689  if(dZ>=0.)treeMem.zDirection = 1; else treeMem.zDirection = -1;
1690  }
1691 }
1692 
1693 void
1695  const std::map<int, TrackerOfflineValidation::ModuleHistos>& moduleHist_)
1696 {
1697  for(std::map<int, TrackerOfflineValidation::ModuleHistos>::const_iterator it = moduleHist_.begin(),
1698  itEnd= moduleHist_.end(); it != itEnd;++it ) {
1699  treeMem = mTreeMembers_[it->first];
1700 
1701  //mean and RMS values (extracted from histograms(Xprime on module level)
1702  treeMem.entries = static_cast<UInt_t>(it->second.ResXprimeHisto->GetEntries());
1703  treeMem.meanX = it->second.ResXprimeHisto->GetMean();
1704  treeMem.rmsX = it->second.ResXprimeHisto->GetRMS();
1705  //treeMem.sigmaX = Fwhm(it->second.ResXprimeHisto)/2.355;
1706 
1707  if (useFit_) {
1708  //call fit function which returns mean and sigma from the fit
1709  //for absolute residuals
1710  std::pair<float,float> fitResult1 = this->fitResiduals(it->second.ResXprimeHisto);
1711  treeMem.fitMeanX = fitResult1.first;
1712  treeMem.fitSigmaX = fitResult1.second;
1713  //for normalized residuals
1714  std::pair<float,float> fitResult2 = this->fitResiduals(it->second.NormResXprimeHisto);
1715  treeMem.fitMeanNormX = fitResult2.first;
1716  treeMem.fitSigmaNormX = fitResult2.second;
1717  }
1718 
1719  //get median for absolute residuals
1720  treeMem.medianX = this->getMedian(it->second.ResXprimeHisto);
1721 
1722  int numberOfBins=it->second.ResXprimeHisto->GetNbinsX();
1723  treeMem.numberOfUnderflows = it->second.ResXprimeHisto->GetBinContent(0);
1724  treeMem.numberOfOverflows = it->second.ResXprimeHisto->GetBinContent(numberOfBins+1);
1725  treeMem.numberOfOutliers = it->second.ResXprimeHisto->GetBinContent(0)+it->second.ResXprimeHisto->GetBinContent(numberOfBins+1);
1726 
1727  //mean and RMS values (extracted from histograms(normalized Xprime on module level)
1728  treeMem.meanNormX = it->second.NormResXprimeHisto->GetMean();
1729  treeMem.rmsNormX = it->second.NormResXprimeHisto->GetRMS();
1730 
1731  double stats[20];
1732  it->second.NormResXprimeHisto->GetStats(stats);
1733  // GF treeMem.chi2PerDofX = stats[3]/(stats[0]-1);
1734  if (stats[0]) treeMem.chi2PerDofX = stats[3]/stats[0];
1735 
1736  treeMem.sigmaNormX = Fwhm(it->second.NormResXprimeHisto)/2.355;
1737  treeMem.histNameX = it->second.ResXprimeHisto->GetName();
1738  treeMem.histNameNormX = it->second.NormResXprimeHisto->GetName();
1739 
1740  // fill tree variables in local coordinates if set in cfg
1741  if(lCoorHistOn_) {
1742  treeMem.meanLocalX = it->second.ResHisto->GetMean();
1743  treeMem.rmsLocalX = it->second.ResHisto->GetRMS();
1744  treeMem.meanNormLocalX = it->second.NormResHisto->GetMean();
1745  treeMem.rmsNormLocalX = it->second.NormResHisto->GetRMS();
1746 
1747  treeMem.histNameLocalX = it->second.ResHisto->GetName();
1748  treeMem.histNameNormLocalX = it->second.NormResHisto->GetName();
1749  if (it->second.ResYHisto) treeMem.histNameLocalY = it->second.ResYHisto->GetName();
1750  }
1751 
1752  // mean and RMS values in local y (extracted from histograms(normalized Yprime on module level)
1753  // might exist in pixel only
1754  if (it->second.ResYprimeHisto) {//(stripYResiduals_)
1755  TH1 *h = it->second.ResYprimeHisto;
1756  treeMem.meanY = h->GetMean();
1757  treeMem.rmsY = h->GetRMS();
1758 
1759  if (useFit_) { // fit function which returns mean and sigma from the fit
1760  std::pair<float,float> fitMeanSigma = this->fitResiduals(h);
1761  treeMem.fitMeanY = fitMeanSigma.first;
1762  treeMem.fitSigmaY = fitMeanSigma.second;
1763  }
1764 
1765  //get median for absolute residuals
1766  treeMem.medianY = this->getMedian(h);
1767 
1768  treeMem.histNameY = h->GetName();
1769  }
1770  if (it->second.NormResYprimeHisto) {
1771  TH1 *h = it->second.NormResYprimeHisto;
1772  treeMem.meanNormY = h->GetMean();
1773  treeMem.rmsNormY = h->GetRMS();
1774  h->GetStats(stats); // stats buffer defined above
1775  if (stats[0]) treeMem.chi2PerDofY = stats[3]/stats[0];
1776 
1777  if (useFit_) { // fit function which returns mean and sigma from the fit
1778  std::pair<float,float> fitMeanSigma = this->fitResiduals(h);
1779  treeMem.fitMeanNormY = fitMeanSigma.first;
1780  treeMem.fitSigmaNormY = fitMeanSigma.second;
1781  }
1782  treeMem.histNameNormY = h->GetName();
1783  }
1784 
1785  if (moduleLevelProfiles_) {
1786  if (it->second.ResXvsXProfile) {
1787  TH1 *h = it->second.ResXvsXProfile;
1788  treeMem.meanResXvsX = h->GetMean();
1789  treeMem.rmsResXvsX = h->GetRMS();
1790  treeMem.profileNameResXvsX = h->GetName();
1791  }
1792  if (it->second.ResXvsYProfile) {
1793  TH1 *h = it->second.ResXvsYProfile;
1794  treeMem.meanResXvsY = h->GetMean();
1795  treeMem.rmsResXvsY = h->GetRMS();
1796  treeMem.profileNameResXvsY = h->GetName();
1797  }
1798  if (it->second.ResYvsXProfile) {
1799  TH1 *h = it->second.ResYvsXProfile;
1800  treeMem.meanResYvsX = h->GetMean();
1801  treeMem.rmsResYvsX = h->GetRMS();
1802  treeMem.profileNameResYvsX = h->GetName();
1803  }
1804  if (it->second.ResYvsYProfile) {
1805  TH1 *h = it->second.ResYvsYProfile;
1806  treeMem.meanResYvsY = h->GetMean();
1807  treeMem.rmsResYvsY = h->GetRMS();
1808  treeMem.profileNameResYvsY = h->GetName();
1809  }
1810  }
1811 
1812  tree.Fill();
1813  }
1814 }
1815 
1816 
1817 std::pair<float,float>
1819 {
1820  std::pair<float,float> fitResult(9999., 9999.);
1821  if (!hist || hist->GetEntries() < 20) return fitResult;
1822 
1823  float mean = hist->GetMean();
1824  float sigma = hist->GetRMS();
1825 
1826  try { // for < CMSSW_2_2_0 since ROOT warnings from fit are converted to exceptions
1827  // Remove the try/catch for more recent CMSSW!
1828  // first fit: two RMS around mean
1829  TF1 func("tmp", "gaus", mean - 2.*sigma, mean + 2.*sigma);
1830  if (0 == hist->Fit(&func,"QNR")) { // N: do not blow up file by storing fit!
1831  mean = func.GetParameter(1);
1832  sigma = func.GetParameter(2);
1833  // second fit: three sigma of first fit around mean of first fit
1834  func.SetRange(mean - 3.*sigma, mean + 3.*sigma);
1835  // I: integral gives more correct results if binning is too wide
1836  // L: Likelihood can treat empty bins correctly (if hist not weighted...)
1837  if (0 == hist->Fit(&func, "Q0LR")) {
1838  if (hist->GetFunction(func.GetName())) { // Take care that it is later on drawn:
1839  hist->GetFunction(func.GetName())->ResetBit(TF1::kNotDraw);
1840  }
1841  fitResult.first = func.GetParameter(1);
1842  fitResult.second = func.GetParameter(2);
1843  }
1844  }
1845  } catch (cms::Exception const & e) {
1846  edm::LogWarning("Alignment") << "@SUB=TrackerOfflineValidation::fitResiduals"
1847  << "Caught this exception during ROOT fit: "
1848  << e.what();
1849  }
1850  return fitResult;
1851 }
1852 
1853 
1854 float
1856 {
1857  float median = 999;
1858  int nbins = histo->GetNbinsX();
1859 
1860  //extract median from histogram
1861  double *x = new double[nbins];
1862  double *y = new double[nbins];
1863  for (int j = 0; j < nbins; j++) {
1864  x[j] = histo->GetBinCenter(j+1);
1865  y[j] = histo->GetBinContent(j+1);
1866  }
1867  median = TMath::Median(nbins, x, y);
1868 
1869  delete[] x; x = nullptr;
1870  delete [] y; y = nullptr;
1871 
1872  return median;
1873 
1874 }
1875 //define this as a plug-in
#define LogDebug(id)
const TrackerGeometry * bareTkGeomPtr_
size
Write out results.
const DetIdContainer & detUnitIds() const override
Returm a vector of all GeomDetUnit DetIds.
type
Definition: HCALResponse.h:21
GlobalPoint toGlobal(const Point2DBase< Scalar, LocalTag > lp) const
Definition: Surface.h:106
T getParameter(std::string const &) const
align::ID id() const
Return the ID of Alignable, i.e. DetId of &#39;first&#39; component GeomDet(Unit).
Definition: Alignable.h:189
bool tecIsDoubleSide(const DetId &id) const
bool tobIsDoubleSide(const DetId &id) const
std::vector< TH1 * > vDeleteObjects_
std::map< int, TrackerOfflineValidation::ModuleHistos > mPxeResiduals_
bool tibIsDoubleSide(const DetId &id) const
T perp() const
Definition: PV3DBase.h:72
unsigned int tibLayer(const DetId &id) const
std::pair< int, int > typeAndLayerFromDetId(const DetId &detId, const TrackerTopology *tTopo) const
unsigned int tidRing(const DetId &id) const
const unsigned long long maxTracks_
TH1 * make(const char *name, const char *title, int nBinX, double minBinX, double maxBinX)
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
bool isPixel(uint32_t subDetId)
std::vector< unsigned int > tidModuleInfo(const DetId &id) const
std::vector< TH1 * > vTrack2DHistos_
TH1 * bookTH1F(bool isTransient, DirectoryWrapper &tfd, const char *histName, const char *histTitle, int nBinsX, double lowX, double highX)
std::unique_ptr< AlignableTracker > alignableTracker_
std::map< int, TrackerOfflineValidation::ModuleHistos > mTecResiduals_
unsigned int pxfDisk(const DetId &id) const
container to hold data to be written into TTree
std::string profileNameResXvsX
void fillTree(TTree &tree, TkOffTreeVariables &treeMem, const std::map< int, TrackerOfflineValidation::ModuleHistos > &moduleHist_)
unsigned int tecRing(const DetId &id) const
ring id
#define nullptr
uint32_t tobStereo(const DetId &id) const
S make(const edm::ParameterSet &cfg)
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
unsigned int pxbLadder(const DetId &id) const
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:50
edm::ESHandle< TrackerGeometry > tkGeom_
T y() const
Definition: PV3DBase.h:63
int GetIndex(const std::vector< OBJECT_TYPE * > &vec, const TString &name)
def setup(process, global_tag, zero_tesla=False)
Definition: GeneralSetup.py:2
unsigned int tidWheel(const DetId &id) const
unsigned int pxbModule(const DetId &id) const
T * make(const Args &...args) const
make new ROOT object
Definition: TFileService.h:64
char const * what() const override
Definition: Exception.cc:103
virtual const Alignables & components() const =0
Return vector of all direct components.
float getMedian(const TH1 *hist) const
ModuleHistos & getHistStructFromMap(const DetId &detid)
void setSummaryBin(int bin, TH1 *targetHist, TH1 *sourceHist)
std::vector< unsigned int > tibStringInfo(const DetId &id) const
std::map< int, TrackerOfflineValidation::ModuleHistos > mTibResiduals_
TrackerOfflineValidation::SummaryContainer bookSummaryHists(DirectoryWrapper &tfd, const Alignable &ali, align::StructureType type, int i)
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:42
std::vector< std::tuple< int, TH1 *, TH1 * > > summaryBins_
std::string profileNameResYvsX
std::map< int, TrackerOfflineValidation::ModuleHistos > mTidResiduals_
T barePhi() const
Definition: PV3DBase.h:68
std::vector< std::pair< TH1 *, TH1 * > > sumHistStructure_
TFileDirectory & tFileDirectory()
Definition: TFileService.h:42
unsigned int subDetId[21]
int iEvent
Definition: GenABIO.cc:224
std::vector< unsigned int > tecPetalInfo(const DetId &id) const
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
const Surface::PositionType & position() const
The position (origin of the R.F.)
Definition: GeomDet.h:48
unsigned int tidSide(const DetId &id) const
virtual StructureType alignableObjectId() const =0
Return the alignable type identifier.
void setUpTreeMembers(const std::map< int, TrackerOfflineValidation::ModuleHistos > &moduleHist_, const TrackerGeometry &tkgeom, const TrackerTopology *tTopo)
uint32_t tidStereo(const DetId &id) const
std::vector< unsigned int > tobRodInfo(const DetId &id) const
ConsumesCollector consumesCollector()
Use a ConsumesCollector to gather consumes information from helper functions.
T z() const
Definition: PV3DBase.h:64
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:41
const DetIdContainer & detIds() const override
Returm a vector of all GeomDet DetIds (including those of GeomDetUnits)
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
void getBinning(uint32_t subDetId, TrackerOfflineValidation::HistogramType residualtype, int &nBinsX, double &lowerBoundX, double &upperBoundX)
virtual void checkBookHists(const edm::EventSetup &setup)
TProfile * bookTProfile(bool isTransient, DirectoryWrapper &tfd, const char *histName, const char *histTitle, int nBinsX, double lowX, double highX)
double f[11][100]
void prepareSummaryHists(DirectoryWrapper &tfd, const Alignable &ali, std::vector< TrackerOfflineValidation::SummaryContainer > &vLevelProfiles)
std::string histNameLocalY
std::string histNameNormLocalX
unsigned int tibModule(const DetId &id) const
unsigned int pxfModule(const DetId &id) const
int k[5][pyjets_maxn]
bin
set the eta bin as selection string.
bool isDetOrDetUnit(align::StructureType type)
std::map< int, TrackerOfflineValidation::ModuleHistos > mTobResiduals_
unsigned int pxbLayer(const DetId &id) const
unsigned int tecModule(const DetId &id) const
DirectoryWrapper(const std::string &newDir, const std::string &basedir, bool useDqmMode)
Definition: DetId.h:18
void fillTrackQuantities(const edm::Event &, const edm::EventSetup &, std::vector< AVTrackStruct > &v_avtrackout)
TFileDirectory mkdir(const std::string &dir, const std::string &descr="")
create a new subdirectory
Definition: TFileService.h:69
std::pair< float, float > fitResiduals(TH1 *hist) const
std::string histNameLocalX
bool tidIsDoubleSide(const DetId &id) const
def uint(string)
void summarizeBinInContainer(int bin, SummaryContainer &targetContainer, SummaryContainer &sourceContainer)
bool isEndCap(uint32_t subDetId)
unsigned int tobModule(const DetId &id) const
std::string profileNameResXvsY
T eta() const
Definition: PV3DBase.h:76
void bookGlobalHists(DirectoryWrapper &tfd)
DirectoryWrapper(const DirectoryWrapper &upDir, const std::string &newDir, const std::string &basedir, bool useDqmMode)
TrackerValidationVariables avalidator_
std::map< int, TkOffTreeVariables > mTreeMembers_
T get() const
Definition: EventSetup.h:71
uint32_t tecStereo(const DetId &id) const
const TrackerGeomDet * idToDet(DetId) const override
std::vector< TH1 * > vTrackProfiles_
unsigned int pxfSide(const DetId &id) const
void bookDirHists(DirectoryWrapper &tfd, const Alignable &ali, const TrackerTopology *tTopo)
Definition: tree.py:1
std::map< int, TrackerOfflineValidation::ModuleHistos > mPxbResiduals_
uint32_t tibStereo(const DetId &id) const
const edm::ParameterSet parSet_
TrackerOfflineValidation(const edm::ParameterSet &)
T x() const
Definition: PV3DBase.h:62
float Fwhm(const TH1 *hist) const
unsigned int tecWheel(const DetId &id) const
T const * product() const
Definition: ESHandle.h:86
unsigned int pxfPanel(const DetId &id) const
unsigned int pxfBlade(const DetId &id) const
void analyze(const edm::Event &, const edm::EventSetup &) override
std::string profileNameResYvsY
unsigned int tobLayer(const DetId &id) const
void bookHists(DirectoryWrapper &tfd, const Alignable &ali, const TrackerTopology *tTopo, align::StructureType type, int i)
unsigned int tecSide(const DetId &id) const
constexpr Detector det() const
get the detector field from this detid
Definition: DetId.h:39
bool isBarrel(uint32_t subDetId)