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