/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Alignment/APEEstimation/plugins/ApeEstimator.cc
2 687 строк
126 KB
Shahzad Malik Muzaffar
[ALCA-DB] Drop Geometry/CommonDetUnit package
28 май 2026, 12:57
28 май 2026, 12:57
993d9d5
Код
Авторство
О чём код?
// -*- C++ -*- // // Package: ApeEstimator // Class: ApeEstimator // /**\class ApeEstimator ApeEstimator.cc Alignment/APEEstimation/src/ApeEstimator.cc Description: <one line class summary> Implementation: <Notes on implementation> */ // // Original Author: Johannes Hauk // Created: Tue Jan 6 15:02:09 CET 2009 // Modified by: Christian Schomakers (RWTH Aachen) // $Id: ApeEstimator.cc,v 1.27 2012/06/26 09:42:33 hauk Exp $ // // // system include files #include <memory> #include <sstream> #include <fstream> // user include files #include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/Framework/interface/one/EDAnalyzer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/EventSetup.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/ServiceRegistry/interface/Service.h" #include "FWCore/Utilities/interface/InputTag.h" #include "FWCore/Utilities/interface/EDGetToken.h" #include "CommonTools/UtilAlgos/interface/TFileService.h" #include "CommonTools/Utils/interface/TFileDirectory.h" #include "DataFormats/Common/interface/Handle.h" #include "DataFormats/TrackReco/interface/Track.h" #include "DataFormats/TrackReco/interface/HitPattern.h" #include "DataFormats/TrackingRecHit/interface/TrackingRecHit.h" #include "DataFormats/DetId/interface/DetId.h" #include "DataFormats/TrackerRecHit2D/interface/SiStripRecHit1D.h" #include "DataFormats/TrackerRecHit2D/interface/SiStripRecHit2D.h" #include "DataFormats/TrackerRecHit2D/interface/SiStripMatchedRecHit2D.h" #include "DataFormats/TrackerRecHit2D/interface/ProjectedSiStripRecHit2D.h" #include "DataFormats/TrackerRecHit2D/interface/SiPixelRecHit.h" #include "DataFormats/GeometryVector/interface/LocalPoint.h" #include "DataFormats/GeometrySurface/interface/LocalError.h" #include "DataFormats/GeometryCommonDetAlgo/interface/MeasurementPoint.h" #include "DataFormats/GeometryCommonDetAlgo/interface/MeasurementError.h" #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h" #include "DataFormats/SiStripDetId/interface/StripSubdetector.h" #include "DataFormats/SiStripDetId/interface/SiStripDetId.h" #include "DataFormats/SiPixelCluster/interface/SiPixelCluster.h" #include "DataFormats/SiStripCluster/interface/SiStripCluster.h" #include "TrackingTools/PatternTools/interface/Trajectory.h" #include "TrackingTools/PatternTools/interface/TrajTrackAssociation.h" #include "TrackingTools/PatternTools/interface/TrajectoryMeasurement.h" #include "TrackingTools/PatternTools/interface/MeasurementExtractor.h" #include "TrackingTools/TrackFitters/interface/TrajectoryStateCombiner.h" #include "TrackingTools/TransientTrackingRecHit/interface/TransientTrackingRecHit.h" #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h" #include "Geometry/CommonTopologies/interface/GeomDet.h" #include "Geometry/CommonTopologies/interface/GeomDetType.h" #include "Geometry/CommonTopologies/interface/RadialStripTopology.h" //added by Ajay 6Nov 2014 //....................... #include "Geometry/CommonTopologies/interface/PixelTopology.h" #include "Geometry/CommonTopologies/interface/PixelGeomDetUnit.h" #include "CondFormats/AlignmentRecord/interface/TrackerAlignmentErrorExtendedRcd.h" //............... // ////..................... #include "Geometry/TrackerGeometryBuilder/interface/StripGeomDetUnit.h" #include "CondFormats/Alignment/interface/Definitions.h" #include "RecoLocalTracker/SiStripClusterizer/interface/SiStripClusterInfo.h" #include "Alignment/APEEstimation/interface/TrackerSectorStruct.h" #include "Alignment/APEEstimation/interface/TrackerDetectorStruct.h" #include "Alignment/APEEstimation/interface/EventVariables.h" #include "Alignment/APEEstimation/interface/ReducedTrackerTreeVariables.h" #include "TH1.h" #include "TH2.h" #include "TProfile.h" #include "TFile.h" #include "TTree.h" #include "TF1.h" #include "TString.h" #include "TMath.h" #include "RecoLocalTracker/SiStripRecHitConverter/interface/StripCPE.h" #include "Geometry/CommonTopologies/interface/StripTopology.h" #include "MagneticField/Engine/interface/MagneticField.h" #include "CondFormats/SiStripObjects/interface/SiStripLorentzAngle.h" //ADDED BY LOIC QUERTENMONT #include "FWCore/Framework/interface/DependentRecordImplementation.h" #include "CalibTracker/Records/interface/SiStripDependentRecords.h" ///////// #include "DataFormats/GeometryVector/interface/LocalVector.h" #include "DataFormats/GeometrySurface/interface/Bounds.h" #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" #include "CondFormats/DataRecord/interface/SiStripLorentzAngleRcd.h" #include "DataFormats/BeamSpot/interface/BeamSpot.h" #include "DataFormats/Math/interface/Point3D.h" #include "FWCore/Utilities/interface/EDMException.h" // // class decleration // class ApeEstimator : public edm::one::EDAnalyzer<> { public: explicit ApeEstimator(const edm::ParameterSet&); ~ApeEstimator() override; private: struct PositionAndError2 { PositionAndError2() : posX(-999.F), posY(-999.F), errX2(-999.F), errY2(-999.F) {} PositionAndError2(float x, float y, float eX, float eY) : posX(x), posY(y), errX2(eX), errY2(eY) {} float posX; float posY; float errX2; float errY2; }; typedef std::pair<TrackStruct::HitState, PositionAndError2> StatePositionAndError2; void beginJob() override; void analyze(const edm::Event&, const edm::EventSetup&) override; void endJob() override; bool isHit2D(const TrackingRecHit&) const; void sectorBuilder(); bool checkIntervalsForSectors(const unsigned int sectorCounter, const std::vector<double>&) const; bool checkModuleIds(const unsigned int, const std::vector<unsigned int>&) const; bool checkModuleBools(const bool, const std::vector<unsigned int>&) const; bool checkModuleDirections(const int, const std::vector<int>&) const; bool checkModulePositions(const float, const std::vector<double>&) const; void statistics(const TrackerSectorStruct&, const int) const; void residualErrorBinning(); void bookSectorHistsForAnalyzerMode(); void bookSectorHistsForApeCalculation(); void bookTrackHists(); TrackStruct::TrackParameterStruct fillTrackVariables(const reco::Track&, const Trajectory&, const reco::BeamSpot&); TrackStruct::HitParameterStruct fillHitVariables(const TrajectoryMeasurement&, const edm::EventSetup&); StatePositionAndError2 positionAndError2(const LocalPoint&, const LocalError&, const TransientTrackingRecHit&); PositionAndError2 rectangularPositionAndError2(const LocalPoint&, const LocalError&); PositionAndError2 radialPositionAndError2(const LocalPoint&, const LocalError&, const RadialStripTopology&); void hitSelection(); void setHitSelectionMap(const std::string&); void setHitSelectionMapUInt(const std::string&); bool hitSelected(TrackStruct::HitParameterStruct&) const; bool inDoubleInterval(const std::vector<double>&, const float) const; bool inUintInterval(const std::vector<unsigned int>&, const unsigned int, const unsigned int = 999) const; void fillHistsForAnalyzerMode(const TrackStruct&); void fillHitHistsXForAnalyzerMode(const TrackStruct::HitParameterStruct&, TrackerSectorStruct&); void fillHitHistsYForAnalyzerMode(const TrackStruct::HitParameterStruct&, TrackerSectorStruct&); void fillHistsForApeCalculation(const TrackStruct&); void calculateAPE(); // ----------member data --------------------------- const edm::ParameterSet parameterSet_; const edm::ESGetToken<MagneticField, IdealMagneticFieldRecord> magFieldToken_; const edm::ESGetToken<SiStripLorentzAngle, SiStripLorentzAngleDepRcd> lorentzAngleToken_; std::map<unsigned int, TrackerSectorStruct> m_tkSector_; TrackerDetectorStruct tkDetector_; SiStripClusterInfo siStripClusterInfo_; edm::EDGetTokenT<TrajTrackAssociationCollection> tjTagToken_; edm::EDGetTokenT<reco::BeamSpot> offlinebeamSpot_; std::map<unsigned int, std::pair<double, double> > m_resErrBins_; std::map<unsigned int, ReducedTrackerTreeVariables> m_tkTreeVar_; std::map<std::string, std::vector<double> > m_hitSelection_; std::map<std::string, std::vector<unsigned int> > m_hitSelectionUInt_; bool trackCut_; const unsigned int maxTracksPerEvent_; const unsigned int minGoodHitsPerTrack_; const bool analyzerMode_; const bool calculateApe_; unsigned int counter1, counter2, counter3, counter4, counter5, counter6; }; // // constants, enums and typedefs // // // static data member definitions // // // constructors and destructor // ApeEstimator::ApeEstimator(const edm::ParameterSet& iConfig) : parameterSet_(iConfig), magFieldToken_(esConsumes()), lorentzAngleToken_(esConsumes()), siStripClusterInfo_(consumesCollector(), std::string("")), tjTagToken_( consumes<TrajTrackAssociationCollection>(parameterSet_.getParameter<edm::InputTag>("tjTkAssociationMapTag"))), offlinebeamSpot_(consumes<reco::BeamSpot>(edm::InputTag("offlineBeamSpot"))), trackCut_(false), maxTracksPerEvent_(parameterSet_.getParameter<unsigned int>("maxTracksPerEvent")), minGoodHitsPerTrack_(parameterSet_.getParameter<unsigned int>("minGoodHitsPerTrack")), analyzerMode_(parameterSet_.getParameter<bool>("analyzerMode")), calculateApe_(parameterSet_.getParameter<bool>("calculateApe")) { counter1 = counter2 = counter3 = counter4 = counter5 = counter6 = 0; } ApeEstimator::~ApeEstimator() {} // // member functions // // ----------------------------------------------------------------------------------------------------------- void ApeEstimator::sectorBuilder() { TFile* tkTreeFile(TFile::Open((parameterSet_.getParameter<std::string>("TrackerTreeFile")).c_str())); if (tkTreeFile) { edm::LogInfo("SectorBuilder") << "TrackerTreeFile OK"; } else { edm::LogError("SectorBuilder") << "TrackerTreeFile not found"; return; } TTree* tkTree(nullptr); tkTreeFile->GetObject("TrackerTreeGenerator/TrackerTree/TrackerTree", tkTree); if (tkTree) { edm::LogInfo("SectorBuilder") << "TrackerTree OK"; } else { edm::LogError("SectorBuilder") << "TrackerTree not found in file"; return; } unsigned int rawId(999), subdetId(999), layer(999), side(999), half(999), rod(999), ring(999), petal(999), blade(999), panel(999), outerInner(999), module(999), nStrips(999); bool isDoubleSide(false), isRPhi(false), isStereo(false); int uDirection(999), vDirection(999), wDirection(999); float posR(999.F), posPhi(999.F), posEta(999.F), posX(999.F), posY(999.F), posZ(999.F); tkTree->SetBranchAddress("RawId", &rawId); tkTree->SetBranchAddress("SubdetId", &subdetId); tkTree->SetBranchAddress("Layer", &layer); tkTree->SetBranchAddress("Side", &side); tkTree->SetBranchAddress("Half", &half); tkTree->SetBranchAddress("Rod", &rod); tkTree->SetBranchAddress("Ring", &ring); tkTree->SetBranchAddress("Petal", &petal); tkTree->SetBranchAddress("Blade", &blade); tkTree->SetBranchAddress("Panel", &panel); tkTree->SetBranchAddress("OuterInner", &outerInner); tkTree->SetBranchAddress("Module", &module); tkTree->SetBranchAddress("NStrips", &nStrips); tkTree->SetBranchAddress("IsDoubleSide", &isDoubleSide); tkTree->SetBranchAddress("IsRPhi", &isRPhi); tkTree->SetBranchAddress("IsStereo", &isStereo); tkTree->SetBranchAddress("UDirection", &uDirection); tkTree->SetBranchAddress("VDirection", &vDirection); tkTree->SetBranchAddress("WDirection", &wDirection); tkTree->SetBranchAddress("PosR", &posR); tkTree->SetBranchAddress("PosPhi", &posPhi); tkTree->SetBranchAddress("PosEta", &posEta); tkTree->SetBranchAddress("PosX", &posX); tkTree->SetBranchAddress("PosY", &posY); tkTree->SetBranchAddress("PosZ", &posZ); int nModules(tkTree->GetEntries()); TrackerSectorStruct allSectors; //Loop over all Sectors unsigned int sectorCounter(0); std::vector<edm::ParameterSet> v_sectorDef(parameterSet_.getParameter<std::vector<edm::ParameterSet> >("Sectors")); edm::LogInfo("SectorBuilder") << "There are " << v_sectorDef.size() << " Sectors definded"; for (auto const& parSet : v_sectorDef) { ++sectorCounter; const std::string& sectorName(parSet.getParameter<std::string>("name")); std::vector<unsigned int> v_rawId(parSet.getParameter<std::vector<unsigned int> >("rawId")), v_subdetId(parSet.getParameter<std::vector<unsigned int> >("subdetId")), v_layer(parSet.getParameter<std::vector<unsigned int> >("layer")), v_side(parSet.getParameter<std::vector<unsigned int> >("side")), v_half(parSet.getParameter<std::vector<unsigned int> >("half")), v_rod(parSet.getParameter<std::vector<unsigned int> >("rod")), v_ring(parSet.getParameter<std::vector<unsigned int> >("ring")), v_petal(parSet.getParameter<std::vector<unsigned int> >("petal")), v_blade(parSet.getParameter<std::vector<unsigned int> >("blade")), v_panel(parSet.getParameter<std::vector<unsigned int> >("panel")), v_outerInner(parSet.getParameter<std::vector<unsigned int> >("outerInner")), v_module(parSet.getParameter<std::vector<unsigned int> >("module")), v_nStrips(parSet.getParameter<std::vector<unsigned int> >("nStrips")), v_isDoubleSide(parSet.getParameter<std::vector<unsigned int> >("isDoubleSide")), v_isRPhi(parSet.getParameter<std::vector<unsigned int> >("isRPhi")), v_isStereo(parSet.getParameter<std::vector<unsigned int> >("isStereo")); std::vector<int> v_uDirection(parSet.getParameter<std::vector<int> >("uDirection")), v_vDirection(parSet.getParameter<std::vector<int> >("vDirection")), v_wDirection(parSet.getParameter<std::vector<int> >("wDirection")); std::vector<double> v_posR(parSet.getParameter<std::vector<double> >("posR")), v_posPhi(parSet.getParameter<std::vector<double> >("posPhi")), v_posEta(parSet.getParameter<std::vector<double> >("posEta")), v_posX(parSet.getParameter<std::vector<double> >("posX")), v_posY(parSet.getParameter<std::vector<double> >("posY")), v_posZ(parSet.getParameter<std::vector<double> >("posZ")); if (!this->checkIntervalsForSectors(sectorCounter, v_posR) || !this->checkIntervalsForSectors(sectorCounter, v_posPhi) || !this->checkIntervalsForSectors(sectorCounter, v_posEta) || !this->checkIntervalsForSectors(sectorCounter, v_posX) || !this->checkIntervalsForSectors(sectorCounter, v_posY) || !this->checkIntervalsForSectors(sectorCounter, v_posZ)) continue; TrackerSectorStruct tkSector; tkSector.name = sectorName; ReducedTrackerTreeVariables tkTreeVar; //Loop over all Modules for (int module = 0; module < nModules; ++module) { tkTree->GetEntry(module); if (sectorCounter == 1) { tkTreeVar.subdetId = subdetId; tkTreeVar.nStrips = nStrips; tkTreeVar.uDirection = uDirection; tkTreeVar.vDirection = vDirection; tkTreeVar.wDirection = wDirection; m_tkTreeVar_[rawId] = tkTreeVar; } if (!this->checkModuleIds(rawId, v_rawId)) continue; if (!this->checkModuleIds(subdetId, v_subdetId)) continue; if (!this->checkModuleIds(layer, v_layer)) continue; if (!this->checkModuleIds(side, v_side)) continue; if (!this->checkModuleIds(half, v_half)) continue; if (!this->checkModuleIds(rod, v_rod)) continue; if (!this->checkModuleIds(ring, v_ring)) continue; if (!this->checkModuleIds(petal, v_petal)) continue; if (!this->checkModuleIds(blade, v_blade)) continue; if (!this->checkModuleIds(panel, v_panel)) continue; if (!this->checkModuleIds(outerInner, v_outerInner)) continue; if (!this->checkModuleIds(module, v_module)) continue; if (!this->checkModuleIds(nStrips, v_nStrips)) continue; if (!this->checkModuleBools(isDoubleSide, v_isDoubleSide)) continue; if (!this->checkModuleBools(isRPhi, v_isRPhi)) continue; if (!this->checkModuleBools(isStereo, v_isStereo)) continue; if (!this->checkModuleDirections(uDirection, v_uDirection)) continue; if (!this->checkModuleDirections(vDirection, v_vDirection)) continue; if (!this->checkModuleDirections(wDirection, v_wDirection)) continue; if (!this->checkModulePositions(posR, v_posR)) continue; if (!this->checkModulePositions(posPhi, v_posPhi)) continue; if (!this->checkModulePositions(posEta, v_posEta)) continue; if (!this->checkModulePositions(posX, v_posX)) continue; if (!this->checkModulePositions(posY, v_posY)) continue; if (!this->checkModulePositions(posZ, v_posZ)) continue; tkSector.v_rawId.push_back(rawId); bool moduleSelected(false); for (auto const& i_rawId : allSectors.v_rawId) { if (rawId == i_rawId) moduleSelected = true; } if (!moduleSelected) allSectors.v_rawId.push_back(rawId); } bool isPixel(false); bool isStrip(false); for (auto const& i_rawId : tkSector.v_rawId) { switch (m_tkTreeVar_[i_rawId].subdetId) { case PixelSubdetector::PixelBarrel: case PixelSubdetector::PixelEndcap: isPixel = true; break; case StripSubdetector::TIB: case StripSubdetector::TOB: case StripSubdetector::TID: case StripSubdetector::TEC: isStrip = true; break; } } if (isPixel && isStrip) { edm::LogError("SectorBuilder") << "Incorrect Sector Definition: there are pixel and strip modules within one sector" << "\n... sector selection is not applied, sector " << sectorCounter << " is not built"; continue; } tkSector.isPixel = isPixel; m_tkSector_[sectorCounter] = tkSector; edm::LogInfo("SectorBuilder") << "There are " << tkSector.v_rawId.size() << " Modules in Sector " << sectorCounter; } this->statistics(allSectors, nModules); return; } // ----------------------------------------------------------------------------------------------------------- bool ApeEstimator::checkIntervalsForSectors(const unsigned int sectorCounter, const std::vector<double>& v_id) const { if (v_id.empty()) return true; if (v_id.size() % 2 == 1) { edm::LogError("SectorBuilder") << "Incorrect Sector Definition: Position Vectors need even number of arguments (Intervals)" << "\n... sector selection is not applied, sector " << sectorCounter << " is not built"; return false; } int entry(0); double intervalBegin(999.); for (auto const& i_id : v_id) { ++entry; if (entry % 2 == 1) intervalBegin = i_id; if (entry % 2 == 0 && intervalBegin > i_id) { edm::LogError("SectorBuilder") << "Incorrect Sector Definition (Position Vector Intervals): \t" << intervalBegin << " is bigger than " << i_id << " but is expected to be smaller" << "\n... sector selection is not applied, sector " << sectorCounter << " is not built"; return false; } } return true; } bool ApeEstimator::checkModuleIds(const unsigned int id, const std::vector<unsigned int>& v_id) const { if (v_id.empty()) return true; for (auto const& i_id : v_id) { if (id == i_id) return true; } return false; } bool ApeEstimator::checkModuleBools(const bool id, const std::vector<unsigned int>& v_id) const { if (v_id.empty()) return true; for (auto const& i_id : v_id) { if (1 == i_id && id) return true; if (2 == i_id && !id) return true; } return false; } bool ApeEstimator::checkModuleDirections(const int id, const std::vector<int>& v_id) const { if (v_id.empty()) return true; for (auto const& i_id : v_id) { if (id == i_id) return true; } return false; } bool ApeEstimator::checkModulePositions(const float id, const std::vector<double>& v_id) const { if (v_id.empty()) return true; int entry(0); double intervalBegin(999.); for (auto const& i_id : v_id) { ++entry; if (entry % 2 == 1) intervalBegin = i_id; if (entry % 2 == 0 && id >= intervalBegin && id < i_id) return true; } return false; } void ApeEstimator::statistics(const TrackerSectorStruct& allSectors, const int nModules) const { bool commonModules(false); for (std::map<unsigned int, TrackerSectorStruct>::const_iterator i_sector = m_tkSector_.begin(); i_sector != m_tkSector_.end(); ++i_sector) { std::map<unsigned int, TrackerSectorStruct>::const_iterator i_sector2(i_sector); for (++i_sector2; i_sector2 != m_tkSector_.end(); ++i_sector2) { unsigned int nCommonModules(0); for (auto const& i_module : (*i_sector).second.v_rawId) { for (auto const& i_module2 : (*i_sector2).second.v_rawId) { if (i_module2 == i_module) ++nCommonModules; } } if (nCommonModules == 0) ; //edm::LogInfo("SectorBuilder")<<"Sector "<<(*i_sector).first<<" and Sector "<<(*i_sector2).first<< " have ZERO Modules in common"; else { edm::LogError("SectorBuilder") << "Sector " << (*i_sector).first << " and Sector " << (*i_sector2).first << " have " << nCommonModules << " Modules in common"; commonModules = true; } } } if (static_cast<int>(allSectors.v_rawId.size()) == nModules) edm::LogInfo("SectorBuilder") << "ALL Tracker Modules are contained in the Sectors"; else edm::LogWarning("SectorBuilder") << "There are " << allSectors.v_rawId.size() << " Modules in all Sectors" << " out of " << nModules << " Tracker Modules"; if (!commonModules) edm::LogInfo("SectorBuilder") << "There are ZERO modules associated to different sectors, no ambiguities exist"; else edm::LogError("SectorBuilder") << "There are modules associated to different sectors, APE value cannot be assigned reasonably"; } // ----------------------------------------------------------------------------------------------------------- void ApeEstimator::residualErrorBinning() { std::vector<double> v_residualErrorBinning(parameterSet_.getParameter<std::vector<double> >("residualErrorBinning")); if (v_residualErrorBinning.size() == 1) { edm::LogError("ResidualErrorBinning") << "Incorrect selection of Residual Error Bins (used for APE calculation): \t" << "Only one argument passed, so no interval is specified" << "\n... delete whole bin selection"; //m_resErrBins_ remains empty return; } double xMin(0.), xMax(0.); unsigned int binCounter(-1); for (auto const& i_binning : v_residualErrorBinning) { ++binCounter; if (binCounter == 0) { xMin = i_binning; continue; } xMax = i_binning; if (xMax <= xMin) { edm::LogError("ResidualErrorBinning") << "Incorrect selection of Residual Error Bins (used for APE calculation): \t" << xMin << " is bigger than " << xMax << " but is expected to be smaller" << "\n... delete whole bin selection"; m_resErrBins_.clear(); return; } m_resErrBins_[binCounter].first = xMin; m_resErrBins_[binCounter].second = xMax; xMin = xMax; } edm::LogInfo("ResidualErrorBinning") << m_resErrBins_.size() << " Intervals of residual errors used for separate APE calculation sucessfully set"; } // ----------------------------------------------------------------------------------------------------------- void ApeEstimator::bookSectorHistsForAnalyzerMode() { std::vector<unsigned int> v_errHists(parameterSet_.getParameter<std::vector<unsigned int> >("vErrHists")); for (std::vector<unsigned int>::iterator i_errHists = v_errHists.begin(); i_errHists != v_errHists.end(); ++i_errHists) { for (std::vector<unsigned int>::iterator i_errHists2 = i_errHists; i_errHists2 != v_errHists.end();) { ++i_errHists2; if (*i_errHists == *i_errHists2) { edm::LogError("BookSectorHists") << "Value of vErrHists in config exists twice: " << *i_errHists << "\n... delete one of both"; v_errHists.erase(i_errHists2); } } } for (auto& i_sector : m_tkSector_) { bool zoomHists(parameterSet_.getParameter<bool>("zoomHists")); double widthMax = zoomHists ? 20. : 200.; double chargePixelMax = zoomHists ? 200000. : 2000000.; double chargeStripMax = zoomHists ? 1000. : 10000.; double sOverNMax = zoomHists ? 200. : 2000.; double logClusterProbMin = zoomHists ? -5. : -15.; double resXAbsMax = zoomHists ? 0.5 : 5.; double norResXAbsMax = zoomHists ? 10. : 50.; double probXMin = zoomHists ? -0.01 : -0.1; double probXMax = zoomHists ? 0.11 : 1.1; double sigmaXMin = zoomHists ? 0. : -0.05; double sigmaXMax = zoomHists ? 0.02 : 1.; double sigmaX2Max = sigmaXMax * sigmaXMax; double sigmaXHitMax = zoomHists ? 0.02 : 1.; double phiSensXMax = zoomHists ? 31. : 93.; double norChi2Max = zoomHists ? 5. : 1000.; double d0Max = zoomHists ? 0.02 : 40.; // cosmics: 100.|100. double dzMax = zoomHists ? 15. : 100.; // cosmics: 200.|600. double pMax = zoomHists ? 200. : 2000.; double invPMax = zoomHists ? 0.05 : 10.; //begins at 20GeV, 0.1GeV edm::Service<TFileService> fileService; if (!fileService) { throw edm::Exception(edm::errors::Configuration, "TFileService is not registered in cfg file"); } std::stringstream sector; sector << "Sector_" << i_sector.first; TFileDirectory secDir = fileService->mkdir(sector.str()); // Dummy histo containing the sector name as title i_sector.second.Name = secDir.make<TH1F>("z_name", i_sector.second.name.c_str(), 1, 0, 1); // Do not book histos for empty sectors if (i_sector.second.v_rawId.empty()) { continue; } // Set parameters for correlationHists i_sector.second.setCorrHistParams(&secDir, norResXAbsMax, sigmaXHitMax, sigmaXMax); // Book pixel or strip specific hists const bool pixelSector(i_sector.second.isPixel); // Cluster Parameters i_sector.second.m_correlationHistsX["WidthX"] = i_sector.second.bookCorrHistsX("WidthX", "cluster width", "w_{cl,x}", "[# channels]", static_cast<int>(widthMax), static_cast<int>(widthMax), 0., widthMax, "nph"); i_sector.second.m_correlationHistsX["BaryStripX"] = i_sector.second.bookCorrHistsX( "BaryStripX", "barycenter of cluster charge", "b_{cl,x}", "[# channels]", 800, 100, -10., 790., "nph"); if (pixelSector) { i_sector.second.m_correlationHistsY["WidthY"] = i_sector.second.bookCorrHistsY("WidthY", "cluster width", "w_{cl,y}", "[# channels]", static_cast<int>(widthMax), static_cast<int>(widthMax), 0., widthMax, "nph"); i_sector.second.m_correlationHistsY["BaryStripY"] = i_sector.second.bookCorrHistsY( "BaryStripY", "barycenter of cluster charge", "b_{cl,y}", "[# channels]", 800, 100, -10., 790., "nph"); i_sector.second.m_correlationHistsX["ChargePixel"] = i_sector.second.bookCorrHistsX( "ChargePixel", "cluster charge", "c_{cl}", "[e]", 100, 50, 0., chargePixelMax, "nph"); i_sector.second.m_correlationHistsX["ClusterProbXY"] = i_sector.second.bookCorrHistsX( "ClusterProbXY", "cluster probability xy", "prob_{cl,xy}", "", 100, 50, 0., 1., "nph"); i_sector.second.m_correlationHistsX["ClusterProbQ"] = i_sector.second.bookCorrHistsX( "ClusterProbQ", "cluster probability q", "prob_{cl,q}", "", 100, 50, 0., 1., "nph"); i_sector.second.m_correlationHistsX["ClusterProbXYQ"] = i_sector.second.bookCorrHistsX( "ClusterProbXYQ", "cluster probability xyq", "prob_{cl,xyq}", "", 100, 50, 0., 1., "nph"); i_sector.second.m_correlationHistsX["LogClusterProb"] = i_sector.second.bookCorrHistsX( "LogClusterProb", "cluster probability xy", "log(prob_{cl,xy})", "", 60, 30, logClusterProbMin, 0., "nph"); i_sector.second.m_correlationHistsX["IsOnEdge"] = i_sector.second.bookCorrHistsX("IsOnEdge", "IsOnEdge", "isOnEdge", "", 2, 2, 0, 2, "nph"); i_sector.second.m_correlationHistsX["HasBadPixels"] = i_sector.second.bookCorrHistsX("HasBadPixels", "HasBadPixels", "hasBadPixels", "", 2, 2, 0, 2, "nph"); i_sector.second.m_correlationHistsX["SpansTwoRoc"] = i_sector.second.bookCorrHistsX("SpansTwoRoc", "SpansTwoRoc", "spansTwoRoc", "", 2, 2, 0, 2, "nph"); i_sector.second.m_correlationHistsX["QBin"] = i_sector.second.bookCorrHistsX("QBin", "q bin", "q bin", "", 8, 8, 0, 8, "nph"); i_sector.second.m_correlationHistsY["ChargePixel"] = i_sector.second.bookCorrHistsY( "ChargePixel", "cluster charge", "c_{cl}", "[e]", 100, 50, 0., chargePixelMax, "nph"); i_sector.second.m_correlationHistsY["ClusterProbXY"] = i_sector.second.bookCorrHistsY( "ClusterProbXY", "cluster probability xy", "prob_{cl,xy}", "", 100, 50, 0., 1., "nph"); i_sector.second.m_correlationHistsY["ClusterProbQ"] = i_sector.second.bookCorrHistsY( "ClusterProbQ", "cluster probability q", "prob_{cl,q}", "", 100, 50, 0., 1., "nph"); i_sector.second.m_correlationHistsY["ClusterProbXYQ"] = i_sector.second.bookCorrHistsY( "ClusterProbXYQ", "cluster probability xyq", "prob_{cl,xyq}", "", 100, 50, 0., 1., "nph"); i_sector.second.m_correlationHistsY["LogClusterProb"] = i_sector.second.bookCorrHistsY( "LogClusterProb", "cluster probability xy", "log(prob_{cl,xy})", "", 60, 30, logClusterProbMin, 0., "nph"); i_sector.second.m_correlationHistsY["IsOnEdge"] = i_sector.second.bookCorrHistsY("IsOnEdge", "IsOnEdge", "isOnEdge", "", 2, 2, 0, 2, "nph"); i_sector.second.m_correlationHistsY["HasBadPixels"] = i_sector.second.bookCorrHistsY("HasBadPixels", "HasBadPixels", "hasBadPixels", "", 2, 2, 0, 2, "nph"); i_sector.second.m_correlationHistsY["SpansTwoRoc"] = i_sector.second.bookCorrHistsY("SpansTwoRoc", "SpansTwoRoc", "spansTwoRoc", "", 2, 2, 0, 2, "nph"); i_sector.second.m_correlationHistsY["QBin"] = i_sector.second.bookCorrHistsY("QBin", "q bin", "q bin", "", 8, 8, 0, 8, "nph"); } else { i_sector.second.m_correlationHistsX["ChargeStrip"] = i_sector.second.bookCorrHistsX( "ChargeStrip", "cluster charge", "c_{cl}", "[APV counts]", 100, 50, 0., chargeStripMax, "nph"); i_sector.second.m_correlationHistsX["MaxStrip"] = i_sector.second.bookCorrHistsX( "MaxStrip", "strip with max. charge", "n_{cl,max}", "[# strips]", 800, 800, -10., 790., "npht"); i_sector.second.m_correlationHistsX["MaxCharge"] = i_sector.second.bookCorrHistsX( "MaxCharge", "charge of strip with max. charge", "c_{cl,max}", "[APV counts]", 300, 75, -10., 290., "nph"); i_sector.second.m_correlationHistsX["MaxIndex"] = i_sector.second.bookCorrHistsX( "MaxIndex", "cluster-index of strip with max. charge", "i_{cl,max}", "[# strips]", 10, 10, 0., 10., "nph"); i_sector.second.m_correlationHistsX["ChargeOnEdges"] = i_sector.second.bookCorrHistsX("ChargeOnEdges", "fraction of charge on edge strips", "(c_{st,L}+c_{st,R})/c_{cl}", "", 60, 60, -0.1, 1.1, "nph"); i_sector.second.m_correlationHistsX["ChargeAsymmetry"] = i_sector.second.bookCorrHistsX("ChargeAsymmetry", "asymmetry of charge on edge strips", "(c_{st,L}-c_{st,R})/c_{cl}", "", 110, 55, -1.1, 1.1, "nph"); i_sector.second.m_correlationHistsX["ChargeLRplus"] = i_sector.second.bookCorrHistsX("ChargeLRplus", "fraction of charge not on maxStrip", "(c_{cl,L}+c_{cl,R})/c_{cl}", "", 60, 60, -0.1, 1.1, "nph"); i_sector.second.m_correlationHistsX["ChargeLRminus"] = i_sector.second.bookCorrHistsX("ChargeLRminus", "asymmetry of charge L and R of maxStrip", "(c_{cl,L}-c_{cl,R})/c_{cl}", "", 110, 55, -1.1, 1.1, "nph"); i_sector.second.m_correlationHistsX["SOverN"] = i_sector.second.bookCorrHistsX("SOverN", "signal over noise", "s/N", "", 100, 50, 0, sOverNMax, "nph"); i_sector.second.m_correlationHistsX["WidthProj"] = i_sector.second.bookCorrHistsX( "WidthProj", "projected width", "w_{p}", "[# strips]", 200, 20, 0., widthMax, "nph"); i_sector.second.m_correlationHistsX["WidthDiff"] = i_sector.second.bookCorrHistsX("WidthDiff", "width difference", "w_{p} - w_{cl}", "[# strips]", 200, 20, -widthMax / 2., widthMax / 2., "nph"); i_sector.second.WidthVsWidthProjected = secDir.make<TH2F>("h2_widthVsWidthProj", "w_{cl} vs. w_{p};w_{p} [# strips];w_{cl} [# strips]", static_cast<int>(widthMax), 0, widthMax, static_cast<int>(widthMax), 0, widthMax); i_sector.second.PWidthVsWidthProjected = secDir.make<TProfile>("p_widthVsWidthProj", "w_{cl} vs. w_{p};w_{p} [# strips];w_{cl} [# strips]", static_cast<int>(widthMax), 0, widthMax); i_sector.second.WidthDiffVsMaxStrip = secDir.make<TH2F>("h2_widthDiffVsMaxStrip", "(w_{p} - w_{cl}) vs. n_{cl,max};n_{cl,max};w_{p} - w_{cl} [# strips]", 800, -10., 790., static_cast<int>(widthMax), -widthMax / 2., widthMax / 2.); i_sector.second.PWidthDiffVsMaxStrip = secDir.make<TProfile>("p_widthDiffVsMaxStrip", "(w_{p} - w_{cl}) vs. n_{cl,max};n_{cl,max};w_{p} - w_{cl} [# strips]", 800, -10., 790.); i_sector.second.WidthDiffVsSigmaXHit = secDir.make<TH2F>("h2_widthDiffVsSigmaXHit", "(w_{p} - w_{cl}) vs. #sigma_{hit,x};#sigma_{hit,x} [cm];w_{p} - w_{cl} [# strips]", 100, 0., sigmaXMax, 100, -10., 10.); i_sector.second.PWidthDiffVsSigmaXHit = secDir.make<TProfile>("p_widthDiffVsSigmaXHit", "(w_{p} - w_{cl}) vs. #sigma_{hit,x};#sigma_{hit,x} [cm];w_{p} - w_{cl} [# strips]", 100, 0., sigmaXMax); i_sector.second.WidthVsPhiSensX = secDir.make<TH2F>("h2_widthVsPhiSensX", "w_{cl} vs. #phi_{module,x};#phi_{module,x} [ ^{o}];w_{cl} [# strips]", 93, -93, 93, static_cast<int>(widthMax), 0, widthMax); i_sector.second.PWidthVsPhiSensX = secDir.make<TProfile>( "p_widthVsPhiSensX", "w_{cl} vs. #phi_{module,x};#phi_{module,x} [ ^{o}];w_{cl} [# strips]", 93, -93, 93); } // Hit Parameters (transform errors and residuals from [cm] in [mum]) i_sector.second.m_correlationHistsX["SigmaXHit"] = i_sector.second.bookCorrHistsX( "SigmaXHit", "hit error", "#sigma_{hit,x}", "[#mum]", 105, 20, sigmaXMin * 10000., sigmaXMax * 10000., "np"); i_sector.second.m_correlationHistsX["SigmaXTrk"] = i_sector.second.bookCorrHistsX( "SigmaXTrk", "track error", "#sigma_{trk,x}", "[#mum]", 105, 20, sigmaXMin * 10000., sigmaXMax * 10000., "np"); i_sector.second.m_correlationHistsX["SigmaX"] = i_sector.second.bookCorrHistsX( "SigmaX", "residual error", "#sigma_{r,x}", "[#mum]", 105, 20, sigmaXMin * 10000., sigmaXMax * 10000., "np"); i_sector.second.m_correlationHistsX["PhiSens"] = i_sector.second.bookCorrHistsX( "PhiSens", "track angle on sensor", "#phi_{module}", "[ ^{o}]", 96, 48, -3, 93, "nphtr"); i_sector.second.m_correlationHistsX["PhiSensX"] = i_sector.second.bookCorrHistsX( "PhiSensX", "track angle on sensor", "#phi_{module,x}", "[ ^{o}]", 186, 93, -phiSensXMax, phiSensXMax, "nphtr"); i_sector.second.m_correlationHistsX["PhiSensY"] = i_sector.second.bookCorrHistsX( "PhiSensY", "track angle on sensor", "#phi_{module,y}", "[ ^{o}]", 186, 93, -93, 93, "nphtr"); i_sector.second.XHit = secDir.make<TH1F>("h_XHit", " hit measurement x_{hit};x_{hit} [cm];# hits", 100, -20, 20); i_sector.second.XTrk = secDir.make<TH1F>("h_XTrk", "track prediction x_{trk};x_{trk} [cm];# hits", 100, -20, 20); i_sector.second.SigmaX2 = secDir.make<TH1F>("h_SigmaX2", "squared residual error #sigma_{r,x}^{2};#sigma_{r,x}^{2} [#mum^{2}];# hits", 105, sigmaXMin * 10000., sigmaX2Max * 10000. * 10000.); //no mistake ! i_sector.second.ResX = secDir.make<TH1F>( "h_ResX", "residual r_{x};x_{trk}-x_{hit} [#mum];# hits", 100, -resXAbsMax * 10000., resXAbsMax * 10000.); i_sector.second.NorResX = secDir.make<TH1F>("h_NorResX", "normalized residual r_{x}/#sigma_{r,x};(x_{trk}-x_{hit})/#sigma_{r,x};# hits", 100, -norResXAbsMax, norResXAbsMax); i_sector.second.ProbX = secDir.make<TH1F>( "h_ProbX", "residual probability;prob(r_{x}^{2}/#sigma_{r,x}^{2},1);# hits", 60, probXMin, probXMax); i_sector.second.PhiSensXVsBarycentreX = secDir.make<TH2F>("h2_phiSensXVsBarycentreX", "#phi_{module,x} vs. b_{cl,x};b_{cl,x} [# channels];#phi_{module,x} [ ^{o}]", 200, -10., 790., 93, -93, 93); i_sector.second.PPhiSensXVsBarycentreX = secDir.make<TProfile>("p_phiSensXVsBarycentreX", "#phi_{module,x} vs. b_{cl,x};b_{cl,x} [# channels];#phi_{module,x} [ ^{o}]", 200, -10., 790.); if (pixelSector) { i_sector.second.m_correlationHistsY["SigmaYHit"] = i_sector.second.bookCorrHistsY( "SigmaYHit", "hit error", "#sigma_{hit,y}", "[#mum]", 105, 20, sigmaXMin * 10000., sigmaXMax * 10000., "np"); i_sector.second.m_correlationHistsY["SigmaYTrk"] = i_sector.second.bookCorrHistsY( "SigmaYTrk", "track error", "#sigma_{trk,y}", "[#mum]", 105, 20, sigmaXMin * 10000., sigmaXMax * 10000., "np"); i_sector.second.m_correlationHistsY["SigmaY"] = i_sector.second.bookCorrHistsY( "SigmaY", "residual error", "#sigma_{r,y}", "[#mum]", 105, 20, sigmaXMin * 10000., sigmaXMax * 10000., "np"); i_sector.second.m_correlationHistsY["PhiSens"] = i_sector.second.bookCorrHistsY( "PhiSens", "track angle on sensor", "#phi_{module}", "[ ^{o}]", 96, 48, -3, 93, "nphtr"); i_sector.second.m_correlationHistsY["PhiSensX"] = i_sector.second.bookCorrHistsY("PhiSensX", "track angle on sensor", "#phi_{module,x}", "[ ^{o}]", 186, 93, -phiSensXMax, phiSensXMax, "nphtr"); i_sector.second.m_correlationHistsY["PhiSensY"] = i_sector.second.bookCorrHistsY( "PhiSensY", "track angle on sensor", "#phi_{module,y}", "[ ^{o}]", 186, 93, -93, 93, "nphtr"); i_sector.second.YHit = secDir.make<TH1F>("h_YHit", " hit measurement y_{hit};y_{hit} [cm];# hits", 100, -20, 20); i_sector.second.YTrk = secDir.make<TH1F>("h_YTrk", "track prediction y_{trk};y_{trk} [cm];# hits", 100, -20, 20); i_sector.second.SigmaY2 = secDir.make<TH1F>("h_SigmaY2", "squared residual error #sigma_{r,y}^{2};#sigma_{r,y}^{2} [#mum^{2}];# hits", 105, sigmaXMin * 10000., sigmaX2Max * 10000. * 10000.); //no mistake ! i_sector.second.ResY = secDir.make<TH1F>( "h_ResY", "residual r_{y};y_{trk}-y_{hit} [#mum];# hits", 100, -resXAbsMax * 10000., resXAbsMax * 10000.); i_sector.second.NorResY = secDir.make<TH1F>("h_NorResY", "normalized residual r_{y}/#sigma_{r,y};(y_{trk}-y_{hit})/#sigma_{r,y};# hits", 100, -norResXAbsMax, norResXAbsMax); i_sector.second.ProbY = secDir.make<TH1F>( "h_ProbY", "residual probability;prob(r_{y}^{2}/#sigma_{r,y}^{2},1);# hits", 60, probXMin, probXMax); i_sector.second.PhiSensYVsBarycentreY = secDir.make<TH2F>("h2_phiSensYVsBarycentreY", "#phi_{module,y} vs. b_{cl,y};b_{cl,y} [# channels];#phi_{module,y} [ ^{o}]", 200, -10., 790., 93, -93, 93); i_sector.second.PPhiSensYVsBarycentreY = secDir.make<TProfile>("p_phiSensYVsBarycentreY", "#phi_{module,y} vs. b_{cl,y};b_{cl,y} [# channels];#phi_{module,y} [ ^{o}]", 200, -10., 790.); } // Track Parameters i_sector.second.m_correlationHistsX["HitsValid"] = i_sector.second.bookCorrHistsX("HitsValid", "# hits", "[valid]", 50, 0, 50, "npt"); i_sector.second.m_correlationHistsX["HitsInvalid"] = i_sector.second.bookCorrHistsX("HitsInvalid", "# hits", "[invalid]", 20, 0, 20, "npt"); i_sector.second.m_correlationHistsX["Hits2D"] = i_sector.second.bookCorrHistsX("Hits2D", "# hits", "[2D]", 20, 0, 20, "npt"); i_sector.second.m_correlationHistsX["LayersMissed"] = i_sector.second.bookCorrHistsX("LayersMissed", "# layers", "[missed]", 10, 0, 10, "npt"); i_sector.second.m_correlationHistsX["HitsPixel"] = i_sector.second.bookCorrHistsX("HitsPixel", "# hits", "[pixel]", 10, 0, 10, "npt"); i_sector.second.m_correlationHistsX["HitsStrip"] = i_sector.second.bookCorrHistsX("HitsStrip", "# hits", "[strip]", 40, 0, 40, "npt"); i_sector.second.m_correlationHistsX["HitsGood"] = i_sector.second.bookCorrHistsX("HitsGood", "# hits", "[good]", 50, 0, 50, "npt"); i_sector.second.m_correlationHistsX["NorChi2"] = i_sector.second.bookCorrHistsX("NorChi2", "#chi^{2}/f", "", 50, 0, norChi2Max, "npr"); i_sector.second.m_correlationHistsX["Theta"] = i_sector.second.bookCorrHistsX("Theta", "#theta", "[ ^{o}]", 40, -10, 190, "npt"); i_sector.second.m_correlationHistsX["Phi"] = i_sector.second.bookCorrHistsX("Phi", "#phi", "[ ^{o}]", 76, -190, 190, "npt"); i_sector.second.m_correlationHistsX["D0Beamspot"] = i_sector.second.bookCorrHistsX("D0Beamspot", "d_{0, BS}", "[cm]", 40, -d0Max, d0Max, "npt"); i_sector.second.m_correlationHistsX["Dz"] = i_sector.second.bookCorrHistsX("Dz", "d_{z}", "[cm]", 40, -dzMax, dzMax, "npt"); i_sector.second.m_correlationHistsX["Pt"] = i_sector.second.bookCorrHistsX("Pt", "p_{t}", "[GeV]", 50, 0, pMax, "npt"); i_sector.second.m_correlationHistsX["P"] = i_sector.second.bookCorrHistsX("P", "|p|", "[GeV]", 50, 0, pMax, "npt"); i_sector.second.m_correlationHistsX["InvP"] = i_sector.second.bookCorrHistsX("InvP", "1/|p|", "[GeV^{-1}]", 25, 0, invPMax, "t"); i_sector.second.m_correlationHistsX["MeanAngle"] = i_sector.second.bookCorrHistsX("MeanAngle", "<#phi_{module}>", "[ ^{o}]", 25, -5, 95, "npt"); //i_sector.second.m_correlationHistsX[""] = i_sector.second.bookCorrHistsX("","","",,,,"nphtr"); if (pixelSector) { i_sector.second.m_correlationHistsY["HitsValid"] = i_sector.second.bookCorrHistsY("HitsValid", "# hits", "[valid]", 50, 0, 50, "npt"); i_sector.second.m_correlationHistsY["HitsInvalid"] = i_sector.second.bookCorrHistsY("HitsInvalid", "# hits", "[invalid]", 20, 0, 20, "npt"); i_sector.second.m_correlationHistsY["Hits2D"] = i_sector.second.bookCorrHistsY("Hits2D", "# hits", "[2D]", 20, 0, 20, "npt"); i_sector.second.m_correlationHistsY["LayersMissed"] = i_sector.second.bookCorrHistsY("LayersMissed", "# layers", "[missed]", 10, 0, 10, "npt"); i_sector.second.m_correlationHistsY["HitsPixel"] = i_sector.second.bookCorrHistsY("HitsPixel", "# hits", "[pixel]", 10, 0, 10, "npt"); i_sector.second.m_correlationHistsY["HitsStrip"] = i_sector.second.bookCorrHistsY("HitsStrip", "# hits", "[strip]", 40, 0, 40, "npt"); i_sector.second.m_correlationHistsY["HitsGood"] = i_sector.second.bookCorrHistsY("HitsGood", "# hits", "[good]", 50, 0, 50, "npt"); i_sector.second.m_correlationHistsY["NorChi2"] = i_sector.second.bookCorrHistsY("NorChi2", "#chi^{2}/f", "", 50, 0, norChi2Max, "npr"); i_sector.second.m_correlationHistsY["Theta"] = i_sector.second.bookCorrHistsY("Theta", "#theta", "[ ^{o}]", 40, -10, 190, "npt"); i_sector.second.m_correlationHistsY["Phi"] = i_sector.second.bookCorrHistsY("Phi", "#phi", "[ ^{o}]", 76, -190, 190, "npt"); i_sector.second.m_correlationHistsY["D0Beamspot"] = i_sector.second.bookCorrHistsY("D0Beamspot", "d_{0, BS}", "[cm]", 40, -d0Max, d0Max, "npt"); i_sector.second.m_correlationHistsY["Dz"] = i_sector.second.bookCorrHistsY("Dz", "d_{z}", "[cm]", 40, -dzMax, dzMax, "npt"); i_sector.second.m_correlationHistsY["Pt"] = i_sector.second.bookCorrHistsY("Pt", "p_{t}", "[GeV]", 50, 0, pMax, "npt"); i_sector.second.m_correlationHistsY["P"] = i_sector.second.bookCorrHistsY("P", "|p|", "[GeV]", 50, 0, pMax, "npt"); i_sector.second.m_correlationHistsY["InvP"] = i_sector.second.bookCorrHistsY("InvP", "1/|p|", "[GeV^{-1}]", 25, 0, invPMax, "t"); i_sector.second.m_correlationHistsY["MeanAngle"] = i_sector.second.bookCorrHistsY("MeanAngle", "<#phi_{module}>", "[ ^{o}]", 25, -5, 95, "npt"); } // (transform errors and residuals from [cm] in [mum]) for (auto const& i_errHists : v_errHists) { double xMin(0.01 * (i_errHists - 1)), xMax(0.01 * (i_errHists)); std::stringstream sigmaXHit, sigmaXTrk, sigmaX; sigmaXHit << "h_sigmaXHit_" << i_errHists; sigmaXTrk << "h_sigmaXTrk_" << i_errHists; sigmaX << "h_sigmaX_" << i_errHists; i_sector.second.m_sigmaX["sigmaXHit"].push_back( secDir.make<TH1F>(sigmaXHit.str().c_str(), "hit error #sigma_{hit,x};#sigma_{hit,x} [#mum];# hits", 100, xMin * 10000., xMax * 10000.)); i_sector.second.m_sigmaX["sigmaXTrk"].push_back( secDir.make<TH1F>(sigmaXTrk.str().c_str(), "track error #sigma_{trk,x};#sigma_{trk,x} [#mum];# hits", 100, xMin * 10000., xMax * 10000.)); i_sector.second.m_sigmaX["sigmaX"].push_back( secDir.make<TH1F>(sigmaX.str().c_str(), "residual error #sigma_{r,x};#sigma_{r,x} [#mum];# hits", 100, xMin * 10000., xMax * 10000.)); if (pixelSector) { std::stringstream sigmaYHit, sigmaYTrk, sigmaY; sigmaYHit << "h_sigmaYHit_" << i_errHists; sigmaYTrk << "h_sigmaYTrk_" << i_errHists; sigmaY << "h_sigmaY_" << i_errHists; i_sector.second.m_sigmaY["sigmaYHit"].push_back( secDir.make<TH1F>(sigmaYHit.str().c_str(), "hit error #sigma_{hit,y};#sigma_{hit,y} [#mum];# hits", 100, xMin * 10000., xMax * 10000.)); i_sector.second.m_sigmaY["sigmaYTrk"].push_back( secDir.make<TH1F>(sigmaYTrk.str().c_str(), "track error #sigma_{trk,y};#sigma_{trk,y} [#mum];# hits", 100, xMin * 10000., xMax * 10000.)); i_sector.second.m_sigmaY["sigmaY"].push_back( secDir.make<TH1F>(sigmaY.str().c_str(), "residual error #sigma_{r,y};#sigma_{r,y} [#mum];# hits", 100, xMin * 10000., xMax * 10000.)); } } } } void ApeEstimator::bookSectorHistsForApeCalculation() { std::vector<unsigned int> v_errHists(parameterSet_.getParameter<std::vector<unsigned int> >("vErrHists")); for (std::vector<unsigned int>::iterator i_errHists = v_errHists.begin(); i_errHists != v_errHists.end(); ++i_errHists) { for (std::vector<unsigned int>::iterator i_errHists2 = i_errHists; i_errHists2 != v_errHists.end();) { ++i_errHists2; if (*i_errHists == *i_errHists2) { edm::LogError("BookSectorHists") << "Value of vErrHists in config exists twice: " << *i_errHists << "\n... delete one of both"; v_errHists.erase(i_errHists2); } } } for (auto& i_sector : m_tkSector_) { edm::Service<TFileService> fileService; if (!fileService) { throw edm::Exception(edm::errors::Configuration, "TFileService is not registered in cfg file"); } std::stringstream sector; sector << "Sector_" << i_sector.first; TFileDirectory secDir = fileService->mkdir(sector.str()); // Dummy histo containing the sector name as title i_sector.second.Name = secDir.make<TH1F>("z_name", i_sector.second.name.c_str(), 1, 0, 1); // Do not book histos for empty sectors if (i_sector.second.v_rawId.empty()) { continue; } // Distributions in each interval (stay in [cm], to have all calculations in [cm]) if (m_resErrBins_ .empty()) { // default if no selection taken into account: calculate APE with one bin with residual error 0-100um m_resErrBins_[1].first = 0.; m_resErrBins_[1].second = 0.01; } for (auto const& i_errBins : m_resErrBins_) { std::stringstream interval; interval << "Interval_" << i_errBins.first; TFileDirectory intDir = secDir.mkdir(interval.str()); i_sector.second.m_binnedHists[i_errBins.first]["sigmaX"] = intDir.make<TH1F>("h_sigmaX", "residual resolution #sigma_{x};#sigma_{x} [cm];# hits", 100, 0., 0.01); i_sector.second.m_binnedHists[i_errBins.first]["norResX"] = intDir.make<TH1F>( "h_norResX", "normalized residual r_{x}/#sigma_{r,x};(x_{trk}-x_{hit})/#sigma_{r,x};# hits", 100, -10, 10); if (i_sector.second.isPixel) { i_sector.second.m_binnedHists[i_errBins.first]["sigmaY"] = intDir.make<TH1F>("h_sigmaY", "residual resolution #sigma_{y};#sigma_{y} [cm];# hits", 100, 0., 0.01); i_sector.second.m_binnedHists[i_errBins.first]["norResY"] = intDir.make<TH1F>( "h_norResY", "normalized residual r_{y}/#sigma_{r,y};(y_{trk}-y_{hit})/#sigma_{r,y};# hits", 100, -10, 10); } } TFileDirectory resDir = secDir.mkdir("Results"); // TTree containing rawIds of all modules in sector unsigned int rawId(0); i_sector.second.RawId = resDir.make<TTree>("rawIdTree", "Tree containing rawIds of all modules in sector"); i_sector.second.RawId->Branch("RawId", &rawId, "RawId/i"); for (auto const& i_rawId : i_sector.second.v_rawId) { rawId = i_rawId; i_sector.second.RawId->Fill(); } // Result plots (one hist per sector containing one bin per interval) // (transform errors and residuals from [cm] in [mum]) std::vector<double> v_binX(parameterSet_.getParameter<std::vector<double> >("residualErrorBinning")); for (auto& i_binX : v_binX) { i_binX *= 10000.; } i_sector.second.EntriesX = resDir.make<TH1F>("h_entriesX", "# hits used;#sigma_{x} [#mum];# hits", v_binX.size() - 1, &(v_binX[0])); if (i_sector.second.isPixel) { i_sector.second.EntriesY = resDir.make<TH1F>("h_entriesY", "# hits used;#sigma_{y} [#mum];# hits", v_binX.size() - 1, &(v_binX[0])); } // In fact these are un-needed Analyzer plots, but I want to have them always for every sector visible // (transform errors and residuals from [cm] in [mum]) i_sector.second.ResX = resDir.make<TH1F>( "h_ResX", "residual r_{x};x_{trk}-x_{hit} [#mum];# hits", 100, -0.03 * 10000., 0.03 * 10000.); i_sector.second.NorResX = resDir.make<TH1F>( "h_NorResX", "normalized residual r_{x}/#sigma_{r,x};(x_{trk}-x_{hit})/#sigma_{r,x};# hits", 100, -5., 5.); if (i_sector.second.isPixel) { i_sector.second.ResY = resDir.make<TH1F>( "h_ResY", "residual r_{y};y_{trk}-y_{hit} [#mum];# hits", 100, -0.03 * 10000., 0.03 * 10000.); i_sector.second.NorResY = resDir.make<TH1F>( "h_NorResY", "normalized residual r_{y}/#sigma_{r,y};(y_{trk}-y_{hit})/#sigma_{r,y};# hits", 100, -5., 5.); } } } // ----------------------------------------------------------------------------------------------------------- void ApeEstimator::bookTrackHists() { bool zoomHists(parameterSet_.getParameter<bool>("zoomHists")); int trackSizeBins = zoomHists ? 6 : 201; double trackSizeMax = trackSizeBins - 1; double chi2Max = zoomHists ? 100. : 2000.; double norChi2Max = zoomHists ? 5. : 1000.; double d0max = zoomHists ? 0.02 : 40.; // cosmics: 100.|100. double dzmax = zoomHists ? 15. : 100.; // cosmics: 200.|600. double pMax = zoomHists ? 200. : 2000.; edm::Service<TFileService> fileService; TFileDirectory evtDir = fileService->mkdir("EventVariables"); tkDetector_.TrkSize = evtDir.make<TH1F>("h_trackSize", "# tracks [all];# tracks;# events", trackSizeBins, -1, trackSizeMax); tkDetector_.TrkSizeGood = evtDir.make<TH1F>("h_trackSizeGood", "# tracks [good];# tracks;# events", trackSizeBins, -1, trackSizeMax); TFileDirectory trkDir = fileService->mkdir("TrackVariables"); tkDetector_.HitsSize = trkDir.make<TH1F>("h_hitsSize", "# hits;# hits;# tracks", 51, -1, 50); tkDetector_.HitsValid = trkDir.make<TH1F>("h_hitsValid", "# hits [valid];# hits [valid];# tracks", 51, -1, 50); tkDetector_.HitsInvalid = trkDir.make<TH1F>("h_hitsInvalid", "# hits [invalid];# hits [invalid];# tracks", 21, -1, 20); tkDetector_.Hits2D = trkDir.make<TH1F>("h_hits2D", "# hits [2D];# hits [2D];# tracks", 21, -1, 20); tkDetector_.LayersMissed = trkDir.make<TH1F>("h_layersMissed", "# layers [missed];# layers [missed];# tracks", 11, -1, 10); tkDetector_.HitsPixel = trkDir.make<TH1F>("h_hitsPixel", "# hits [pixel];# hits [pixel];# tracks", 11, -1, 10); tkDetector_.HitsStrip = trkDir.make<TH1F>("h_hitsStrip", "# hits [strip];# hits [strip];# tracks", 41, -1, 40); tkDetector_.Charge = trkDir.make<TH1F>("h_charge", "charge q;q [e];# tracks", 5, -2, 3); tkDetector_.Chi2 = trkDir.make<TH1F>("h_chi2", " #chi^{2};#chi^{2};# tracks", 100, 0, chi2Max); tkDetector_.Ndof = trkDir.make<TH1F>("h_ndof", "# degrees of freedom f;f;# tracks", 101, -1, 100); tkDetector_.NorChi2 = trkDir.make<TH1F>("h_norChi2", "normalized #chi^{2};#chi^{2}/f;# tracks", 200, 0, norChi2Max); tkDetector_.Prob = trkDir.make<TH1F>("h_prob", " #chi^{2} probability;prob(#chi^{2},f);# tracks", 50, 0, 1); tkDetector_.Eta = trkDir.make<TH1F>("h_eta", "pseudorapidity #eta;#eta;# tracks", 100, -5, 5); tkDetector_.EtaErr = trkDir.make<TH1F>("h_etaErr", "Error of #eta;#sigma(#eta);# tracks", 100, 0, 0.001); tkDetector_.EtaSig = trkDir.make<TH1F>("h_etaSig", "Significance of #eta;#eta/#sigma(#eta);# tracks", 100, -20000, 20000); tkDetector_.Theta = trkDir.make<TH1F>("h_theta", "polar angle #theta;#theta [ ^{o}];# tracks", 100, -10, 190); tkDetector_.Phi = trkDir.make<TH1F>("h_phi", "azimuth angle #phi;#phi [ ^{o}];# tracks", 190, -190, 190); tkDetector_.PhiErr = trkDir.make<TH1F>("h_phiErr", "Error of #phi;#sigma(#phi) [ ^{o}];# tracks", 100, 0, 0.04); tkDetector_.PhiSig = trkDir.make<TH1F>("h_phiSig", "Significance of #phi;#phi/#sigma(#phi) [ ^{o}];# tracks", 100, -50000, 50000); tkDetector_.D0Beamspot = trkDir.make<TH1F>( "h_d0Beamspot", "Closest approach d_{0} wrt. beamspot;d_{0, BS} [cm];# tracks", 200, -d0max, d0max); tkDetector_.D0BeamspotErr = trkDir.make<TH1F>("h_d0BeamspotErr", "Error of d_{0, BS};#sigma(d_{0, BS}) [cm];# tracks", 200, 0, 0.01); tkDetector_.D0BeamspotSig = trkDir.make<TH1F>( "h_d0BeamspotSig", "Significance of d_{0, BS};d_{0, BS}/#sigma(d_{0, BS});# tracks", 100, -5, 5); tkDetector_.Dz = trkDir.make<TH1F>("h_dz", "Closest approach d_{z};d_{z} [cm];# tracks", 200, -dzmax, dzmax); tkDetector_.DzErr = trkDir.make<TH1F>("h_dzErr", "Error of d_{z};#sigma(d_{z}) [cm];# tracks", 200, 0, 0.01); tkDetector_.DzSig = trkDir.make<TH1F>("h_dzSig", "Significance of d_{z};d_{z}/#sigma(d_{z});# tracks", 100, -10000, 10000); tkDetector_.Pt = trkDir.make<TH1F>("h_pt", "transverse momentum p_{t};p_{t} [GeV];# tracks", 100, 0, pMax); tkDetector_.PtErr = trkDir.make<TH1F>("h_ptErr", "Error of p_{t};#sigma(p_{t}) [GeV];# tracks", 100, 0, 1.6); tkDetector_.PtSig = trkDir.make<TH1F>("h_ptSig", "Significance of p_{t};p_{t}/#sigma(p_{t});# tracks", 100, 0, 200); tkDetector_.P = trkDir.make<TH1F>("h_p", "momentum magnitude |p|;|p| [GeV];# tracks", 100, 0, pMax); tkDetector_.MeanAngle = trkDir.make<TH1F>( "h_meanAngle", "mean angle on module <#phi_{module}>;<#phi_{module}> [ ^{o}];# tracks", 100, -5, 95); tkDetector_.HitsGood = trkDir.make<TH1F>("h_hitsGood", "# hits [good];# hits [good];# tracks", 51, -1, 50); tkDetector_.MeanAngleVsHits = trkDir.make<TH2F>( "h2_meanAngleVsHits", "<#phi_{module}> vs. # hits;# hits;<#phi_{module}> [ ^{o}]", 51, -1, 50, 50, -5, 95); tkDetector_.HitsGoodVsHitsValid = trkDir.make<TH2F>("h2_hitsGoodVsHitsValid", "# hits [good] vs. # hits [valid];# hits [valid];# hits [good]", 51, -1, 50, 51, -1, 50); tkDetector_.HitsPixelVsEta = trkDir.make<TH2F>("h2_hitsPixelVsEta", "# hits [pixel] vs. #eta;#eta;# hits [pixel]", 60, -3, 3, 11, -1, 10); tkDetector_.HitsPixelVsTheta = trkDir.make<TH2F>( "h2_hitsPixelVsTheta", "# hits [pixel] vs. #theta;#theta;# hits [pixel]", 100, -10, 190, 11, -1, 10); tkDetector_.HitsStripVsEta = trkDir.make<TH2F>("h2_hitsStripVsEta", "# hits [strip] vs. #eta;#eta;# hits [strip]", 60, -3, 3, 31, -1, 40); tkDetector_.HitsStripVsTheta = trkDir.make<TH2F>( "h2_hitsStripVsTheta", "# hits [strip] vs. #theta;#theta;# hits [strip]", 100, -10, 190, 31, -1, 40); tkDetector_.PtVsEta = trkDir.make<TH2F>("h2_ptVsEta", "p_{t} vs. #eta;#eta;p_{t} [GeV]", 60, -3, 3, 100, 0, pMax); tkDetector_.PtVsTheta = trkDir.make<TH2F>("h2_ptVsTheta", "p_{t} vs. #theta;#theta;p_{t} [GeV]", 100, -10, 190, 100, 0, pMax); tkDetector_.PMeanAngleVsHits = trkDir.make<TProfile>( "p_meanAngleVsHits", "<#phi_{module}> vs. # hits;# hits;<#phi_{module}> [ ^{o}]", 51, -1, 50); tkDetector_.PHitsGoodVsHitsValid = trkDir.make<TProfile>( "p_hitsGoodVsHitsValid", "# hits [good] vs. # hits [valid];# hits [valid];# hits [good]", 51, -1, 50); tkDetector_.PHitsPixelVsEta = trkDir.make<TProfile>("p_hitsPixelVsEta", "# hits [pixel] vs. #eta;#eta;# hits [pixel]", 60, -3, 3); tkDetector_.PHitsPixelVsTheta = trkDir.make<TProfile>("p_hitsPixelVsTheta", "# hits [pixel] vs. #theta;#theta;# hits [pixel]", 100, -10, 190); tkDetector_.PHitsStripVsEta = trkDir.make<TProfile>("p_hitsStripVsEta", "# hits [strip] vs. #eta;#eta;# hits [strip]", 60, -3, 3); tkDetector_.PHitsStripVsTheta = trkDir.make<TProfile>("p_hitsStripVsTheta", "# hits [strip] vs. #theta;#theta;# hits [strip]", 100, -10, 190); tkDetector_.PPtVsEta = trkDir.make<TProfile>("p_ptVsEta", "p_{t} vs. #eta;#eta;p_{t} [GeV]", 60, -3, 3); tkDetector_.PPtVsTheta = trkDir.make<TProfile>("p_ptVsTheta", "p_{t} vs. #theta;#theta;p_{t} [GeV]", 100, -10, 190); } // ----------------------------------------------------------------------------------------------------------- TrackStruct::TrackParameterStruct ApeEstimator::fillTrackVariables(const reco::Track& track, const Trajectory& traj, const reco::BeamSpot& beamSpot) { const math::XYZPoint beamPoint(beamSpot.x0(), beamSpot.y0(), beamSpot.z0()); double d0BeamspotErr = std::sqrt(track.d0Error() * track.d0Error() + 0.5 * beamSpot.BeamWidthX() * beamSpot.BeamWidthX() + 0.5 * beamSpot.BeamWidthY() * beamSpot.BeamWidthY()); const static TrajectoryStateCombiner tsoscomb; const reco::HitPattern& hitPattern(track.hitPattern()); TrackStruct::TrackParameterStruct trkParams; trkParams.hitsSize = track.recHitsSize(); trkParams.hitsValid = track.found(); // invalid is every hit from every single module that expects a hit trkParams.hitsInvalid = trkParams.hitsSize - trkParams.hitsValid; trkParams.layersMissed = track.lost(); // lost hit means, that a crossed layer doesn't contain a hit (can be more than one invalid hit) trkParams.hitsPixel = hitPattern.numberOfValidPixelHits(); trkParams.hitsStrip = hitPattern.numberOfValidStripHits(); trkParams.charge = track.charge(); trkParams.chi2 = track.chi2(); trkParams.ndof = track.ndof(); trkParams.norChi2 = trkParams.chi2 / trkParams.ndof; trkParams.prob = TMath::Prob(trkParams.chi2, trkParams.ndof); trkParams.eta = track.eta(); trkParams.etaErr = track.etaError(); trkParams.theta = track.theta(); trkParams.phi = track.phi(); trkParams.phiErr = track.phiError(); trkParams.d0 = track.d0(); trkParams.d0Beamspot = -1. * track.dxy(beamPoint); trkParams.d0BeamspotErr = d0BeamspotErr; trkParams.dz = track.dz(); trkParams.dzErr = track.dzError(); trkParams.dzBeamspot = track.dz(beamPoint); trkParams.p = track.p(); trkParams.pt = track.pt(); trkParams.ptErr = track.ptError(); const std::vector<TrajectoryMeasurement>& v_meas = traj.measurements(); int count2D(0); float meanPhiSensToNorm(0.F); for (auto const& i_meas : v_meas) { const TrajectoryMeasurement& meas = i_meas; const TransientTrackingRecHit& hit = *meas.recHit(); const TrackingRecHit& recHit = *hit.hit(); if (this->isHit2D(recHit)) ++count2D; TrajectoryStateOnSurface tsos = tsoscomb(meas.forwardPredictedState(), meas.backwardPredictedState()); const align::LocalVector mom(tsos.localDirection()); meanPhiSensToNorm += atan(fabs(sqrt(mom.x() * mom.x() + mom.y() * mom.y()) / mom.z())); } meanPhiSensToNorm *= (1. / static_cast<float>(trkParams.hitsSize)); trkParams.hits2D = count2D; trkParams.meanPhiSensToNorm = meanPhiSensToNorm; if (parameterSet_.getParameter<bool>("applyTrackCuts")) { trackCut_ = false; if (trkParams.hitsStrip < 11 || trkParams.hits2D < 2 || trkParams.hitsPixel < 2 || //trkParams.hitsInvalid>2 || trkParams.hitsStrip > 35 || trkParams.hitsPixel > 7 || trkParams.norChi2 > 5. || trkParams.pt < 25. || trkParams.pt > 150. || std::abs(trkParams.d0Beamspot) > 0.02 || std::abs(trkParams.dz) > 15.) trackCut_ = true; } else { trackCut_ = false; } return trkParams; } TrackStruct::HitParameterStruct ApeEstimator::fillHitVariables(const TrajectoryMeasurement& i_meas, const edm::EventSetup& iSetup) { TrackStruct::HitParameterStruct hitParams; const static TrajectoryStateCombiner tsoscomb; const TrajectoryMeasurement& meas = i_meas; const TransientTrackingRecHit& hit = *meas.recHit(); const TrackingRecHit& recHit = *hit.hit(); const TrajectoryStateOnSurface& tsos = tsoscomb(meas.forwardPredictedState(), meas.backwardPredictedState()); const DetId& detId(hit.geographicalId()); const DetId::Detector& detector = detId.det(); if (detector != DetId::Tracker) { hitParams.hitState = TrackStruct::notInTracker; return hitParams; } const uint32_t rawId(detId.rawId()); for (auto& i_sector : m_tkSector_) { for (auto const& i_rawId : i_sector.second.v_rawId) { if (rawId == i_rawId) { hitParams.v_sector.push_back(i_sector.first); break; } } } const align::LocalVector& mom(tsos.localDirection()); int xMomentum(0), yMomentum(0), zMomentum(0); xMomentum = mom.x() > 0. ? 1 : -1; yMomentum = mom.y() > 0. ? 1 : -1; zMomentum = mom.z() > 0. ? 1 : -1; float phiSensX = std::atan(std::fabs(mom.x() / mom.z())) * static_cast<float>( m_tkTreeVar_[rawId].vDirection); // check for orientation of E- and B- Field (thoughts for barrel) float phiSensY = std::atan(std::fabs(mom.y() / mom.z())) * static_cast<float>(m_tkTreeVar_[rawId].vDirection); hitParams.phiSens = std::atan(std::fabs(std::sqrt(mom.x() * mom.x() + mom.y() * mom.y()) / mom.z())); hitParams.phiSensX = (xMomentum == zMomentum ? phiSensX : -phiSensX); hitParams.phiSensY = (yMomentum == zMomentum ? phiSensY : -phiSensY); if (!hit.isValid()) { hitParams.hitState = TrackStruct::invalid; return hitParams; } // Get local positions and errors of hit and track const LocalPoint& lPHit = hit.localPosition(); const LocalPoint& lPTrk = tsos.localPosition(); // use APE also for the hit error, while APE is automatically included in tsos error // // no need to add APE to hitError anymore by Ajay 27 Oct 2014 const LocalError& errHitApe = hit.localPositionError(); // now sum of CPE+APE as said by MARCO? LocalError errorWithoutAPE; bool Pixel(false); bool Strip(false); if (m_tkTreeVar_[rawId].subdetId == PixelSubdetector::PixelBarrel || m_tkTreeVar_[rawId].subdetId == PixelSubdetector::PixelEndcap) { Pixel = true; } else if (m_tkTreeVar_[rawId].subdetId == StripSubdetector::TIB || m_tkTreeVar_[rawId].subdetId == StripSubdetector::TOB || m_tkTreeVar_[rawId].subdetId == StripSubdetector::TID || m_tkTreeVar_[rawId].subdetId == StripSubdetector::TEC) { Strip = true; } else { edm::LogWarning("FillHitVariables") << "cant identify wether hit is from pixel or strip"; hitParams.hitState = TrackStruct::invalid; return hitParams; } if (!hit.detUnit()) { hitParams.hitState = TrackStruct::invalid; return hitParams; } // is it a single physical module? const GeomDetUnit& detUnit = *hit.detUnit(); if (Pixel) { if (!dynamic_cast<const PixelTopology*>(&detUnit.type().topology())) { hitParams.hitState = TrackStruct::invalid; return hitParams; } const PixelGeomDetUnit* pixelDet = (const PixelGeomDetUnit*)(&detUnit); const LocalError& lape = pixelDet->localAlignmentError(); if (lape.valid()) { errorWithoutAPE = LocalError(errHitApe.xx() - lape.xx(), errHitApe.xy() - lape.xy(), errHitApe.yy() - lape.yy()); } } if (Strip) { if (!dynamic_cast<const StripTopology*>(&detUnit.type().topology())) { hitParams.hitState = TrackStruct::invalid; return hitParams; } const StripGeomDetUnit* stripDet = (const StripGeomDetUnit*)(&detUnit); const LocalError& lape = stripDet->localAlignmentError(); if (lape.valid()) { errorWithoutAPE = LocalError(errHitApe.xx() - lape.xx(), errHitApe.xy() - lape.xy(), errHitApe.yy() - lape.yy()); } } const LocalError& errHitWoApe = errorWithoutAPE; const LocalError& errTrk = tsos.localError().positionError(); const StatePositionAndError2 positionAndError2Hit = this->positionAndError2(lPHit, errHitApe, hit); const StatePositionAndError2 positionAndError2HitWoApe = this->positionAndError2(lPHit, errHitWoApe, hit); edm::LogInfo("CalculateAPE") << "errHitWoApe " << errHitWoApe << "errHitApe " << errHitApe; const StatePositionAndError2 positionAndError2Trk = this->positionAndError2(lPTrk, errTrk, hit); const TrackStruct::HitState& stateHit(positionAndError2Hit.first); const TrackStruct::HitState& stateHitWoApe(positionAndError2HitWoApe.first); const TrackStruct::HitState& stateTrk(positionAndError2Trk.first); if (stateHit == TrackStruct::invalid || stateHitWoApe == TrackStruct::invalid || stateTrk == TrackStruct::invalid) { hitParams.hitState = TrackStruct::invalid; return hitParams; } else if (stateHit == TrackStruct::negativeError || stateHitWoApe == TrackStruct::negativeError || stateTrk == TrackStruct::negativeError) { ++counter1; // Do not print error message by default //std::stringstream ss_error; //ss_error<<"Upper values belong to: "; //if(stateHit==TrackStruct::negativeError)ss_error<<"Hit without APE, "; //if(stateHitWoApe==TrackStruct::negativeError)ss_error<<"Hit with APE, "; //if(stateTrk==TrackStruct::negativeError)ss_error<<"Track,"; //edm::LogError("Negative error Value")<<"@SUB=ApeEstimator::fillHitVariables"<<ss_error.str(); hitParams.hitState = TrackStruct::negativeError; return hitParams; } // Calculate residuals const float xHit = positionAndError2Hit.second.posX; const float xTrk = positionAndError2Trk.second.posX; const float yHit = positionAndError2Hit.second.posY; const float yTrk = positionAndError2Trk.second.posY; const float errXHit2(positionAndError2Hit.second.errX2); const float errXHitWoApe2(positionAndError2HitWoApe.second.errX2); const float errXTrk2(positionAndError2Trk.second.errX2); const float errYHit2(positionAndError2Hit.second.errY2); const float errYHitWoApe2(positionAndError2HitWoApe.second.errY2); const float errYTrk2(positionAndError2Trk.second.errY2); const float errXHit = std::sqrt(positionAndError2Hit.second.errX2); const float errXHitWoApe = std::sqrt(positionAndError2HitWoApe.second.errX2); const float errXTrk = std::sqrt(positionAndError2Trk.second.errX2); const float errYHit = std::sqrt(positionAndError2Hit.second.errY2); const float errYHitWoApe = std::sqrt(positionAndError2HitWoApe.second.errY2); const float errYTrk = std::sqrt(positionAndError2Trk.second.errY2); const float resX = xTrk - xHit; const float resY = yTrk - yHit; const float errX = std::sqrt(errXHit2 + errXTrk2); const float errXWoApe2 = errXHitWoApe2 + errXTrk2; const float errXWoApe = std::sqrt(errXWoApe2); const float errY = std::sqrt(errYHit2 + errYTrk2); const float errYWoApe2 = errYHitWoApe2 + errYTrk2; const float errYWoApe = std::sqrt(errYWoApe2); const float norResX = resX / errX; const float norResY = resY / errY; // Take global orientation into account for residuals (sign is not important for errors) float resXprime(999.F), resYprime(999.F), norResXprime(999.F), norResYprime(999.F); if (m_tkTreeVar_[rawId].uDirection == 1) { resXprime = resX; norResXprime = norResX; } else if (m_tkTreeVar_[rawId].uDirection == -1) { resXprime = -resX; norResXprime = -norResX; } else { edm::LogError("FillHitVariables") << "Incorrect value of uDirection, which gives global module orientation"; hitParams.hitState = TrackStruct::invalid; return hitParams; } if (m_tkTreeVar_[rawId].vDirection == 1) { resYprime = resY; norResYprime = norResY; } else if (m_tkTreeVar_[rawId].vDirection == -1) { resYprime = -resY; norResYprime = -norResY; } else { edm::LogError("FillHitVariables") << "Incorrect value of vDirection, which gives global module orientation"; hitParams.hitState = TrackStruct::invalid; return hitParams; } hitParams.xHit = xHit; hitParams.xTrk = xTrk; hitParams.errXHit = errXHit; hitParams.errXHitWoApe = errXHitWoApe; hitParams.errXTrk = errXTrk; hitParams.errX2 = errX * errX; hitParams.errX = errX; hitParams.errXWoApe = errXWoApe; hitParams.resX = resXprime; hitParams.norResX = norResXprime; const float norResX2(norResXprime * norResXprime); hitParams.probX = TMath::Prob(norResX2, 1); hitParams.yHit = yHit; hitParams.yTrk = yTrk; hitParams.errYHit = errYHit; hitParams.errYHitWoApe = errYHitWoApe; hitParams.errYTrk = errYTrk; hitParams.errY2 = errY * errY; hitParams.errY = errY; hitParams.errYWoApe = errYWoApe; hitParams.resY = resYprime; hitParams.norResY = norResYprime; const float norResY2(norResYprime * norResYprime); hitParams.probY = TMath::Prob(norResY2, 1); // Cluster parameters if (m_tkTreeVar_[rawId].subdetId == PixelSubdetector::PixelBarrel || m_tkTreeVar_[rawId].subdetId == PixelSubdetector::PixelEndcap) { const SiPixelRecHit& pixelHit = dynamic_cast<const SiPixelRecHit&>(recHit); const SiPixelCluster& pixelCluster = *pixelHit.cluster(); hitParams.chargePixel = pixelCluster.charge(); hitParams.widthX = pixelCluster.sizeX(); hitParams.baryStripX = pixelCluster.x(); hitParams.widthY = pixelCluster.sizeY(); hitParams.baryStripY = pixelCluster.y(); hitParams.clusterProbabilityXY = pixelHit.clusterProbability(0); hitParams.clusterProbabilityQ = pixelHit.clusterProbability(2); hitParams.clusterProbabilityXYQ = pixelHit.clusterProbability(1); hitParams.logClusterProbability = std::log10(hitParams.clusterProbabilityXY); hitParams.isOnEdge = pixelHit.isOnEdge(); hitParams.hasBadPixels = pixelHit.hasBadPixels(); hitParams.spansTwoRoc = pixelHit.spansTwoROCs(); hitParams.qBin = pixelHit.qBin(); hitParams.isPixelHit = true; } else if (m_tkTreeVar_[rawId].subdetId == StripSubdetector::TIB || m_tkTreeVar_[rawId].subdetId == StripSubdetector::TOB || m_tkTreeVar_[rawId].subdetId == StripSubdetector::TID || m_tkTreeVar_[rawId].subdetId == StripSubdetector::TEC) { if (!(dynamic_cast<const SiStripRecHit2D*>(&recHit) || dynamic_cast<const SiStripRecHit1D*>(&recHit))) { edm::LogError("FillHitVariables") << "RecHit in Strip is 'Matched' or 'Projected', but here all should be monohits per module"; hitParams.hitState = TrackStruct::invalid; return hitParams; } const SiStripCluster* clusterPtr(nullptr); if (m_tkTreeVar_[rawId].subdetId == StripSubdetector::TIB || m_tkTreeVar_[rawId].subdetId == StripSubdetector::TOB) { if (dynamic_cast<const SiStripRecHit1D*>(&recHit)) { const SiStripRecHit1D& stripHit = dynamic_cast<const SiStripRecHit1D&>(recHit); clusterPtr = &(*stripHit.cluster()); } else if (dynamic_cast<const SiStripRecHit2D*>(&recHit)) { edm::LogWarning("FillHitVariables") << "Data has TIB/TOB hits as SiStripRecHit2D and not 1D. Probably data is " "processed with CMSSW<34X. Nevertheless everything should work fine"; const SiStripRecHit2D& stripHit = dynamic_cast<const SiStripRecHit2D&>(recHit); clusterPtr = &(*stripHit.cluster()); } } else if (m_tkTreeVar_[rawId].subdetId == StripSubdetector::TID || m_tkTreeVar_[rawId].subdetId == StripSubdetector::TEC) { const SiStripRecHit2D& stripHit = dynamic_cast<const SiStripRecHit2D&>(recHit); clusterPtr = &(*stripHit.cluster()); } if (!clusterPtr) { edm::LogError("FillHitVariables") << "Pointer to cluster not valid!!! This should never happen..."; hitParams.hitState = TrackStruct::invalid; return hitParams; } const SiStripCluster& stripCluster(*clusterPtr); siStripClusterInfo_.setCluster(stripCluster, rawId); auto stripChargeL = siStripClusterInfo_.stripCharges().begin(); auto stripChargeR = siStripClusterInfo_.stripCharges().end() - 1; const std::pair<uint16_t, uint16_t> stripChargeLR = std::make_pair(*stripChargeL, *stripChargeR); hitParams.chargeStrip = siStripClusterInfo_.charge(); hitParams.widthX = siStripClusterInfo_.width(); hitParams.baryStripX = siStripClusterInfo_.baryStrip() + 1.; hitParams.isModuleUsable = siStripClusterInfo_.IsModuleUsable(); hitParams.maxStrip = siStripClusterInfo_.maxStrip() + 1; hitParams.maxStripInv = m_tkTreeVar_[rawId].nStrips - hitParams.maxStrip + 1; hitParams.maxCharge = siStripClusterInfo_.maxCharge(); hitParams.maxIndex = siStripClusterInfo_.maxIndex(); hitParams.chargeOnEdges = static_cast<float>(stripChargeLR.first + stripChargeLR.second) / static_cast<float>(hitParams.chargeStrip); hitParams.chargeAsymmetry = static_cast<float>(stripChargeLR.first - stripChargeLR.second) / static_cast<float>(stripChargeLR.first + stripChargeLR.second); hitParams.chargeLRplus = static_cast<float>(siStripClusterInfo_.chargeLR().first + siStripClusterInfo_.chargeLR().second) / static_cast<float>(hitParams.chargeStrip); hitParams.chargeLRminus = static_cast<float>(siStripClusterInfo_.chargeLR().first - siStripClusterInfo_.chargeLR().second) / static_cast<float>(hitParams.chargeStrip); hitParams.sOverN = siStripClusterInfo_.signalOverNoise(); // Calculate projection length corrected by drift if (!hit.detUnit()) { hitParams.hitState = TrackStruct::invalid; return hitParams; } // is it a single physical module? const GeomDetUnit& detUnit = *hit.detUnit(); if (!dynamic_cast<const StripTopology*>(&detUnit.type().topology())) { hitParams.hitState = TrackStruct::invalid; return hitParams; } const MagneticField* magField = &iSetup.getData(magFieldToken_); const SiStripLorentzAngle* lorentzAngle = &iSetup.getData(lorentzAngleToken_); const StripGeomDetUnit* stripDet = (const StripGeomDetUnit*)(&detUnit); LocalVector bField = (stripDet->surface()).toLocal(magField->inTesla(stripDet->surface().position())); float tanLorentzAnglePerTesla = lorentzAngle->getLorentzAngle(stripDet->geographicalId().rawId()); float dirX = -tanLorentzAnglePerTesla * bField.y(); float dirY = tanLorentzAnglePerTesla * bField.x(); float dirZ = 1.; // E field always in z direction LocalVector driftDirection(dirX, dirY, dirZ); const Bounds& bounds = stripDet->specificSurface().bounds(); float maxLength = std::sqrt(std::pow(bounds.length(), 2) + std::pow(bounds.width(), 2)); float thickness = bounds.thickness(); const StripTopology& topol = dynamic_cast<const StripTopology&>(detUnit.type().topology()); LocalVector momentumDir(tsos.localDirection()); LocalPoint momentumPos(tsos.localPosition()); LocalVector scaledMomentumDir(momentumDir); if (momentumDir.z() > 0.) scaledMomentumDir *= std::fabs(thickness / momentumDir.z()); else if (momentumDir.z() < 0.) scaledMomentumDir *= -std::fabs(thickness / momentumDir.z()); else scaledMomentumDir *= maxLength / momentumDir.mag(); float projEdge1 = topol.measurementPosition(momentumPos - 0.5 * scaledMomentumDir).x(); if (projEdge1 < 0.) projEdge1 = 0.; else if (projEdge1 > m_tkTreeVar_[rawId].nStrips) projEdge1 = m_tkTreeVar_[rawId].nStrips; float projEdge2 = topol.measurementPosition(momentumPos + 0.5 * scaledMomentumDir).x(); if (projEdge2 < 0.) projEdge1 = 0.; else if (projEdge2 > m_tkTreeVar_[rawId].nStrips) projEdge1 = m_tkTreeVar_[rawId].nStrips; float coveredStrips = std::fabs(projEdge2 - projEdge1); hitParams.projWidth = coveredStrips; } else { edm::LogError("FillHitVariables") << "Incorrect subdetector ID, hit not associated to tracker"; hitParams.hitState = TrackStruct::notInTracker; return hitParams; } if (!hitParams.isModuleUsable) { hitParams.hitState = TrackStruct::invalid; return hitParams; } if (hitParams.v_sector.empty()) { hitParams.hitState = TrackStruct::notAssignedToSectors; return hitParams; } return hitParams; //} } ApeEstimator::StatePositionAndError2 ApeEstimator::positionAndError2(const LocalPoint& localPoint, const LocalError& localError, const TransientTrackingRecHit& hit) { StatePositionAndError2 vPE2 = std::make_pair(TrackStruct::invalid, PositionAndError2()); const DetId& detId(hit.geographicalId()); const uint32_t& rawId(detId.rawId()); const unsigned int& subdetId(m_tkTreeVar_[rawId].subdetId); if (localError.xx() < 0. || localError.yy() < 0.) { // Do not print error message by default //edm::LogError("Negative error Value")<<"@SUB=ApeEstimator::fillHitVariables" // <<"One of the squared error methods gives negative result\n" // <<"\tSubdetector\tlocalError.xx()\tlocalError.yy()\n" // <<"\t"<<subdetId<<"\t\t"<<localError.xx()<<"\t"<<localError.yy(); vPE2.first = TrackStruct::negativeError; return vPE2; } if (subdetId == PixelSubdetector::PixelBarrel || subdetId == PixelSubdetector::PixelEndcap || subdetId == StripSubdetector::TIB || subdetId == StripSubdetector::TOB) { // Cartesian coordinates vPE2 = std::make_pair(TrackStruct::ok, this->rectangularPositionAndError2(localPoint, localError)); } else if (subdetId == StripSubdetector::TID || subdetId == StripSubdetector::TEC) { // Local x in radial coordinates if (!hit.detUnit()) return vPE2; // is it a single physical module? const GeomDetUnit& detUnit = *hit.detUnit(); if (!dynamic_cast<const RadialStripTopology*>(&detUnit.type().topology())) return vPE2; const RadialStripTopology& topol = dynamic_cast<const RadialStripTopology&>(detUnit.type().topology()); MeasurementError measError = topol.measurementError(localPoint, localError); if (measError.uu() < 0. || measError.vv() < 0.) { // Do not print error message by default //edm::LogError("Negative error Value")<<"@SUB=ApeEstimator::fillHitVariables" // <<"One of the squared error methods gives negative result\n" // <<"\tmeasError.uu()\tmeasError.vv()\n" // <<"\t"<<measError.uu()<<"\t"<<measError.vv() // <<"\n\nOriginalValues:\n" // <<localPoint.x()<<" "<<localPoint.y()<<"\n" // <<localError.xx()<<" "<<localError.yy()<<"\n" // <<"Subdet: "<<subdetId; vPE2.first = TrackStruct::negativeError; return vPE2; } vPE2 = std::make_pair(TrackStruct::ok, this->radialPositionAndError2(localPoint, localError, topol)); } else { edm::LogError("FillHitVariables") << "Incorrect subdetector ID, hit not associated to tracker"; } return vPE2; } ApeEstimator::PositionAndError2 ApeEstimator::rectangularPositionAndError2(const LocalPoint& lP, const LocalError& lE) { const float x(lP.x()); const float y(lP.y()); const float errX2(lE.xx()); const float errY2(lE.yy()); return PositionAndError2(x, y, errX2, errY2); } ApeEstimator::PositionAndError2 ApeEstimator::radialPositionAndError2(const LocalPoint& lP, const LocalError& lE, const RadialStripTopology& topol) { MeasurementPoint measPos = topol.measurementPosition(lP); MeasurementError measErr = topol.measurementError(lP, lE); const float r_0 = topol.originToIntersection(); const float stripLength = topol.localStripLength(lP); const float phi = topol.stripAngle(measPos.x()); float x(-999.F); float y(-999.F); float errX2(-999.F); float errY2(-999.F); x = phi * r_0; // Radial y (not symmetric around 0; radial distance with minimum at middle strip at lower edge [0, yMax]) const float l_0 = r_0 - topol.detHeight() / 2; const float cosPhi(std::cos(phi)); y = measPos.y() * stripLength - 0.5 * stripLength + l_0 * (1. / cosPhi - 1.); const float angularWidth2(topol.angularWidth() * topol.angularWidth()); const float errPhi2(measErr.uu() * angularWidth2); errX2 = errPhi2 * r_0 * r_0; // Radial y (not symmetric around 0, real radial distance from intersection point) const float cosPhi4(std::pow(cosPhi, 4)), sinPhi2(std::sin(phi) * std::sin(phi)); const float helpSummand = l_0 * l_0 * (sinPhi2 / cosPhi4 * errPhi2); errY2 = measErr.vv() * stripLength * stripLength + helpSummand; return PositionAndError2(x, y, errX2, errY2); } // ----------------------------------------------------------------------------------------------------------- void ApeEstimator::hitSelection() { this->setHitSelectionMapUInt("width"); this->setHitSelectionMap("widthProj"); this->setHitSelectionMap("widthDiff"); this->setHitSelectionMap("charge"); this->setHitSelectionMapUInt("edgeStrips"); this->setHitSelectionMap("maxCharge"); this->setHitSelectionMapUInt("maxIndex"); this->setHitSelectionMap("chargeOnEdges"); this->setHitSelectionMap("chargeAsymmetry"); this->setHitSelectionMap("chargeLRplus"); this->setHitSelectionMap("chargeLRminus"); this->setHitSelectionMap("sOverN"); this->setHitSelectionMap("chargePixel"); this->setHitSelectionMapUInt("widthX"); this->setHitSelectionMapUInt("widthY"); this->setHitSelectionMap("baryStripX"); this->setHitSelectionMap("baryStripY"); this->setHitSelectionMap("clusterProbabilityXY"); this->setHitSelectionMap("clusterProbabilityQ"); this->setHitSelectionMap("clusterProbabilityXYQ"); this->setHitSelectionMap("logClusterProbability"); this->setHitSelectionMapUInt("isOnEdge"); this->setHitSelectionMapUInt("hasBadPixels"); this->setHitSelectionMapUInt("spansTwoRoc"); this->setHitSelectionMapUInt("qBin"); this->setHitSelectionMap("phiSens"); this->setHitSelectionMap("phiSensX"); this->setHitSelectionMap("phiSensY"); this->setHitSelectionMap("resX"); this->setHitSelectionMap("norResX"); this->setHitSelectionMap("probX"); this->setHitSelectionMap("errXHit"); this->setHitSelectionMap("errXTrk"); this->setHitSelectionMap("errX"); this->setHitSelectionMap("errX2"); this->setHitSelectionMap("resY"); this->setHitSelectionMap("norResY"); this->setHitSelectionMap("probY"); this->setHitSelectionMap("errYHit"); this->setHitSelectionMap("errYTrk"); this->setHitSelectionMap("errY"); this->setHitSelectionMap("errY2"); edm::LogInfo("HitSelector") << "applying hit cuts ..."; bool emptyMap(true); for (auto& i_hitSelection : m_hitSelection_) { if (!i_hitSelection.second.empty()) { int entry(1); double intervalBegin(999.); for (std::vector<double>::iterator i_hitInterval = i_hitSelection.second.begin(); i_hitInterval != i_hitSelection.second.end(); ++entry) { if (entry % 2 == 1) { intervalBegin = *i_hitInterval; ++i_hitInterval; } else { if (intervalBegin > *i_hitInterval) { edm::LogError("HitSelector") << "INVALID Interval selected for " << i_hitSelection.first << ":\t" << intervalBegin << " > " << (*i_hitInterval) << "\n ... delete Selection for " << i_hitSelection.first; i_hitSelection.second.clear(); i_hitInterval = i_hitSelection.second.begin(); //emptyMap = true; i_hitSelection = m_hitSelection_.begin(); } else { edm::LogInfo("HitSelector") << "Interval selected for " << i_hitSelection.first << ":\t" << intervalBegin << ", " << (*i_hitInterval); ++i_hitInterval; } } } if (!i_hitSelection.second.empty()) emptyMap = false; } } bool emptyMapUInt(true); for (auto& i_hitSelection : m_hitSelectionUInt_) { if (!i_hitSelection.second.empty()) { int entry(1); unsigned int intervalBegin(999); for (std::vector<unsigned int>::iterator i_hitInterval = i_hitSelection.second.begin(); i_hitInterval != i_hitSelection.second.end(); ++entry) { if (entry % 2 == 1) { intervalBegin = *i_hitInterval; ++i_hitInterval; } else { if (intervalBegin > *i_hitInterval) { edm::LogError("HitSelector") << "INVALID Interval selected for " << i_hitSelection.first << ":\t" << intervalBegin << " > " << (*i_hitInterval) << "\n ... delete Selection for " << i_hitSelection.first; i_hitSelection.second.clear(); i_hitInterval = i_hitSelection.second.begin(); //emptyMap = true; i_hitSelection = m_hitSelection_.begin(); } else { edm::LogInfo("HitSelector") << "Interval selected for " << i_hitSelection.first << ":\t" << intervalBegin << ", " << (*i_hitInterval); ++i_hitInterval; } } } if (!i_hitSelection.second.empty()) emptyMapUInt = false; } } if (emptyMap && emptyMapUInt) { m_hitSelection_.clear(); m_hitSelectionUInt_.clear(); edm::LogInfo("HitSelector") << "NO hit cuts applied"; } return; } void ApeEstimator::setHitSelectionMap(const std::string& cutVariable) { edm::ParameterSet parSet(parameterSet_.getParameter<edm::ParameterSet>("HitSelector")); std::vector<double> v_cutVariable(parSet.getParameter<std::vector<double> >(cutVariable)); if (v_cutVariable.size() % 2 == 1) { edm::LogError("HitSelector") << "Invalid Hit Selection for " << cutVariable << ": need even number of arguments (intervals)" << "\n ... delete Selection for " << cutVariable; v_cutVariable.clear(); m_hitSelection_[cutVariable] = v_cutVariable; return; } m_hitSelection_[cutVariable] = v_cutVariable; return; } void ApeEstimator::setHitSelectionMapUInt(const std::string& cutVariable) { edm::ParameterSet parSet(parameterSet_.getParameter<edm::ParameterSet>("HitSelector")); std::vector<unsigned int> v_cutVariable(parSet.getParameter<std::vector<unsigned int> >(cutVariable)); if (v_cutVariable.size() % 2 == 1) { edm::LogError("HitSelector") << "Invalid Hit Selection for " << cutVariable << ": need even number of arguments (intervals)" << "\n ... delete Selection for " << cutVariable; v_cutVariable.clear(); m_hitSelectionUInt_[cutVariable] = v_cutVariable; return; } m_hitSelectionUInt_[cutVariable] = v_cutVariable; return; } // ----------------------------------------------------------------------------------------------------------- bool ApeEstimator::hitSelected(TrackStruct::HitParameterStruct& hitParams) const { if (hitParams.hitState == TrackStruct::notInTracker) return false; if (hitParams.hitState == TrackStruct::invalid || hitParams.hitState == TrackStruct::negativeError) return false; bool isGoodHit(true); bool isGoodHitX(true); bool isGoodHitY(true); for (auto& i_hitSelection : m_hitSelection_) { const std::string& hitSelection(i_hitSelection.first); const std::vector<double>& v_hitSelection(i_hitSelection.second); if (v_hitSelection.empty()) continue; // For pixel and strip sectors in common if (hitSelection == "phiSens") { if (!this->inDoubleInterval(v_hitSelection, hitParams.phiSens)) isGoodHit = false; } else if (hitSelection == "phiSensX") { if (!this->inDoubleInterval(v_hitSelection, hitParams.phiSensX)) isGoodHit = false; } else if (hitSelection == "phiSensY") { if (!this->inDoubleInterval(v_hitSelection, hitParams.phiSensY)) isGoodHit = false; } else if (hitSelection == "resX") { if (!this->inDoubleInterval(v_hitSelection, hitParams.resX)) isGoodHitX = false; } else if (hitSelection == "norResX") { if (!this->inDoubleInterval(v_hitSelection, hitParams.norResX)) isGoodHitX = false; } else if (hitSelection == "probX") { if (!this->inDoubleInterval(v_hitSelection, hitParams.probX)) isGoodHitX = false; } else if (hitSelection == "errXHit") { if (!this->inDoubleInterval(v_hitSelection, hitParams.errXHit)) isGoodHitX = false; } else if (hitSelection == "errXTrk") { if (!this->inDoubleInterval(v_hitSelection, hitParams.errXTrk)) isGoodHitX = false; } else if (hitSelection == "errX") { if (!this->inDoubleInterval(v_hitSelection, hitParams.errX)) isGoodHitX = false; } else if (hitSelection == "errX2") { if (!this->inDoubleInterval(v_hitSelection, hitParams.errX2)) isGoodHitX = false; } // For pixel only if (hitParams.isPixelHit) { if (hitSelection == "chargePixel") { if (!this->inDoubleInterval(v_hitSelection, hitParams.chargePixel)) isGoodHit = false; } else if (hitSelection == "clusterProbabilityXY") { if (!this->inDoubleInterval(v_hitSelection, hitParams.clusterProbabilityXY)) isGoodHit = false; } else if (hitSelection == "clusterProbabilityQ") { if (!this->inDoubleInterval(v_hitSelection, hitParams.clusterProbabilityQ)) isGoodHit = false; } else if (hitSelection == "clusterProbabilityXYQ") { if (!this->inDoubleInterval(v_hitSelection, hitParams.clusterProbabilityXYQ)) isGoodHit = false; } else if (hitSelection == "logClusterProbability") { if (!this->inDoubleInterval(v_hitSelection, hitParams.logClusterProbability)) isGoodHit = false; } else if (hitSelection == "baryStripX") { if (!this->inDoubleInterval(v_hitSelection, hitParams.baryStripX)) isGoodHitX = false; } else if (hitSelection == "baryStripY") { if (!this->inDoubleInterval(v_hitSelection, hitParams.baryStripY)) isGoodHitY = false; } else if (hitSelection == "resY") { if (!this->inDoubleInterval(v_hitSelection, hitParams.resY)) isGoodHitY = false; } else if (hitSelection == "norResY") { if (!this->inDoubleInterval(v_hitSelection, hitParams.norResY)) isGoodHitY = false; } else if (hitSelection == "probY") { if (!this->inDoubleInterval(v_hitSelection, hitParams.probY)) isGoodHitY = false; } else if (hitSelection == "errYHit") { if (!this->inDoubleInterval(v_hitSelection, hitParams.errYHit)) isGoodHitY = false; } else if (hitSelection == "errYTrk") { if (!this->inDoubleInterval(v_hitSelection, hitParams.errYTrk)) isGoodHitY = false; } else if (hitSelection == "errY") { if (!this->inDoubleInterval(v_hitSelection, hitParams.errY)) isGoodHitY = false; } else if (hitSelection == "errY2") { if (!this->inDoubleInterval(v_hitSelection, hitParams.errY2)) isGoodHitY = false; } } else { // For strip only if (hitSelection == "widthProj") { if (!this->inDoubleInterval(v_hitSelection, hitParams.projWidth)) isGoodHit = false; } else if (hitSelection == "widthDiff") { if (!this->inDoubleInterval(v_hitSelection, hitParams.projWidth - static_cast<float>(hitParams.widthX))) isGoodHit = false; } else if (hitSelection == "charge") { if (!this->inDoubleInterval(v_hitSelection, hitParams.chargeStrip)) isGoodHit = false; } else if (hitSelection == "maxCharge") { if (!this->inDoubleInterval(v_hitSelection, hitParams.maxCharge)) isGoodHit = false; } else if (hitSelection == "chargeOnEdges") { if (!this->inDoubleInterval(v_hitSelection, hitParams.chargeOnEdges)) isGoodHit = false; } else if (hitSelection == "chargeAsymmetry") { if (!this->inDoubleInterval(v_hitSelection, hitParams.chargeAsymmetry)) isGoodHit = false; } else if (hitSelection == "chargeLRplus") { if (!this->inDoubleInterval(v_hitSelection, hitParams.chargeLRplus)) isGoodHit = false; } else if (hitSelection == "chargeLRminus") { if (!this->inDoubleInterval(v_hitSelection, hitParams.chargeLRminus)) isGoodHit = false; } else if (hitSelection == "sOverN") { if (!this->inDoubleInterval(v_hitSelection, hitParams.sOverN)) isGoodHit = false; } } } for (auto& i_hitSelection : m_hitSelectionUInt_) { const std::string& hitSelection(i_hitSelection.first); const std::vector<unsigned int>& v_hitSelection(i_hitSelection.second); if (v_hitSelection.empty()) continue; // For pixel and strip sectors in common // For pixel only if (hitParams.isPixelHit) { if (hitSelection == "isOnEdge") { if (!this->inUintInterval(v_hitSelection, hitParams.isOnEdge)) isGoodHit = false; } else if (hitSelection == "hasBadPixels") { if (!this->inUintInterval(v_hitSelection, hitParams.hasBadPixels)) isGoodHit = false; } else if (hitSelection == "spansTwoRoc") { if (!this->inUintInterval(v_hitSelection, hitParams.spansTwoRoc)) isGoodHit = false; } else if (hitSelection == "qBin") { if (!this->inUintInterval(v_hitSelection, hitParams.qBin)) isGoodHit = false; } else if (hitSelection == "widthX") { if (!this->inUintInterval(v_hitSelection, hitParams.widthX)) isGoodHitX = false; } else if (hitSelection == "widthY") { if (!this->inUintInterval(v_hitSelection, hitParams.widthY)) isGoodHitY = false; } } else { // For strip only if (hitSelection == "width") { if (!this->inUintInterval(v_hitSelection, hitParams.widthX)) isGoodHit = false; } else if (hitSelection == "edgeStrips") { if (!this->inUintInterval(v_hitSelection, hitParams.maxStrip, hitParams.maxStripInv)) isGoodHit = false; } else if (hitSelection == "maxIndex") { if (!this->inUintInterval(v_hitSelection, hitParams.maxIndex)) isGoodHit = false; } } } if (hitParams.isPixelHit) { hitParams.goodXMeasurement = isGoodHit && isGoodHitX; hitParams.goodYMeasurement = isGoodHit && isGoodHitY; } else { hitParams.goodXMeasurement = isGoodHit && isGoodHitX; hitParams.goodYMeasurement = false; } if (!hitParams.goodXMeasurement && !hitParams.goodYMeasurement) return false; else return true; } bool ApeEstimator::inDoubleInterval(const std::vector<double>& v_hitSelection, const float variable) const { int entry(0); double intervalBegin(999.); bool isSelected(false); for (auto const& i_hitInterval : v_hitSelection) { ++entry; if (entry % 2 == 1) intervalBegin = i_hitInterval; else if (variable >= intervalBegin && variable < i_hitInterval) isSelected = true; } return isSelected; } bool ApeEstimator::inUintInterval(const std::vector<unsigned int>& v_hitSelection, const unsigned int variable, const unsigned int variable2) const { int entry(0); unsigned int intervalBegin(999); bool isSelected(false); for (auto i_hitInterval : v_hitSelection) { ++entry; if (entry % 2 == 1) intervalBegin = i_hitInterval; else if (variable >= intervalBegin && variable <= i_hitInterval) { if (variable2 == 999 || (variable2 >= intervalBegin && variable2 <= i_hitInterval)) isSelected = true; } } return isSelected; } // ----------------------------------------------------------------------------------------------------------- void ApeEstimator::fillHistsForAnalyzerMode(const TrackStruct& trackStruct) { unsigned int goodHitsPerTrack(trackStruct.v_hitParams.size()); tkDetector_.HitsGood->Fill(goodHitsPerTrack); tkDetector_.HitsGoodVsHitsValid->Fill(trackStruct.trkParams.hitsValid, goodHitsPerTrack); tkDetector_.PHitsGoodVsHitsValid->Fill(trackStruct.trkParams.hitsValid, goodHitsPerTrack); if (parameterSet_.getParameter<bool>("applyTrackCuts")) { // which tracks to take? need min. nr. of selected hits? if (goodHitsPerTrack < minGoodHitsPerTrack_) return; } tkDetector_.HitsSize->Fill(trackStruct.trkParams.hitsSize); tkDetector_.HitsValid->Fill(trackStruct.trkParams.hitsValid); tkDetector_.HitsInvalid->Fill(trackStruct.trkParams.hitsInvalid); tkDetector_.Hits2D->Fill(trackStruct.trkParams.hits2D); tkDetector_.LayersMissed->Fill(trackStruct.trkParams.layersMissed); tkDetector_.HitsPixel->Fill(trackStruct.trkParams.hitsPixel); tkDetector_.HitsStrip->Fill(trackStruct.trkParams.hitsStrip); tkDetector_.Charge->Fill(trackStruct.trkParams.charge); tkDetector_.Chi2->Fill(trackStruct.trkParams.chi2); tkDetector_.Ndof->Fill(trackStruct.trkParams.ndof); tkDetector_.NorChi2->Fill(trackStruct.trkParams.norChi2); tkDetector_.Prob->Fill(trackStruct.trkParams.prob); tkDetector_.Eta->Fill(trackStruct.trkParams.eta); tkDetector_.EtaErr->Fill(trackStruct.trkParams.etaErr); tkDetector_.EtaSig->Fill(trackStruct.trkParams.eta / trackStruct.trkParams.etaErr); tkDetector_.Theta->Fill(trackStruct.trkParams.theta * 180. / M_PI); tkDetector_.Phi->Fill(trackStruct.trkParams.phi * 180. / M_PI); tkDetector_.PhiErr->Fill(trackStruct.trkParams.phiErr * 180. / M_PI); tkDetector_.PhiSig->Fill(trackStruct.trkParams.phi / trackStruct.trkParams.phiErr); tkDetector_.D0Beamspot->Fill(trackStruct.trkParams.d0Beamspot); tkDetector_.D0BeamspotErr->Fill(trackStruct.trkParams.d0BeamspotErr); tkDetector_.D0BeamspotSig->Fill(trackStruct.trkParams.d0Beamspot / trackStruct.trkParams.d0BeamspotErr); tkDetector_.Dz->Fill(trackStruct.trkParams.dz); tkDetector_.DzErr->Fill(trackStruct.trkParams.dzErr); tkDetector_.DzSig->Fill(trackStruct.trkParams.dz / trackStruct.trkParams.dzErr); tkDetector_.P->Fill(trackStruct.trkParams.p); tkDetector_.Pt->Fill(trackStruct.trkParams.pt); tkDetector_.PtErr->Fill(trackStruct.trkParams.ptErr); tkDetector_.PtSig->Fill(trackStruct.trkParams.pt / trackStruct.trkParams.ptErr); tkDetector_.MeanAngle->Fill(trackStruct.trkParams.meanPhiSensToNorm * 180. / M_PI); tkDetector_.MeanAngleVsHits->Fill(trackStruct.trkParams.hitsSize, trackStruct.trkParams.meanPhiSensToNorm * 180. / M_PI); tkDetector_.HitsPixelVsEta->Fill(trackStruct.trkParams.eta, trackStruct.trkParams.hitsPixel); tkDetector_.HitsPixelVsTheta->Fill(trackStruct.trkParams.theta * 180. / M_PI, trackStruct.trkParams.hitsPixel); tkDetector_.HitsStripVsEta->Fill(trackStruct.trkParams.eta, trackStruct.trkParams.hitsStrip); tkDetector_.HitsStripVsTheta->Fill(trackStruct.trkParams.theta * 180. / M_PI, trackStruct.trkParams.hitsStrip); tkDetector_.PtVsEta->Fill(trackStruct.trkParams.eta, trackStruct.trkParams.pt); tkDetector_.PtVsTheta->Fill(trackStruct.trkParams.theta * 180. / M_PI, trackStruct.trkParams.pt); tkDetector_.PMeanAngleVsHits->Fill(trackStruct.trkParams.hitsSize, trackStruct.trkParams.meanPhiSensToNorm * 180. / M_PI); tkDetector_.PHitsPixelVsEta->Fill(trackStruct.trkParams.eta, trackStruct.trkParams.hitsPixel); tkDetector_.PHitsPixelVsTheta->Fill(trackStruct.trkParams.theta * 180. / M_PI, trackStruct.trkParams.hitsPixel); tkDetector_.PHitsStripVsEta->Fill(trackStruct.trkParams.eta, trackStruct.trkParams.hitsStrip); tkDetector_.PHitsStripVsTheta->Fill(trackStruct.trkParams.theta * 180. / M_PI, trackStruct.trkParams.hitsStrip); tkDetector_.PPtVsEta->Fill(trackStruct.trkParams.eta, trackStruct.trkParams.pt); tkDetector_.PPtVsTheta->Fill(trackStruct.trkParams.theta * 180. / M_PI, trackStruct.trkParams.pt); for (auto& i_hit : trackStruct.v_hitParams) { const TrackStruct::HitParameterStruct& hit(i_hit); //Put here from earlier method if (hit.hitState == TrackStruct::notAssignedToSectors) continue; for (auto& i_sector : m_tkSector_) { bool moduleInSector(false); for (auto const& i_hitSector : hit.v_sector) { if (i_sector.first == i_hitSector) { moduleInSector = true; break; } } if (!moduleInSector) continue; TrackerSectorStruct& sector(i_sector.second); if (hit.goodXMeasurement) { std::map<std::string, TrackerSectorStruct::CorrelationHists>& m_corrHists(sector.m_correlationHistsX); // Cluster and Hit Parameters this->fillHitHistsXForAnalyzerMode(hit, sector); // Track Parameters m_corrHists["HitsValid"].fillCorrHistsX(hit, trackStruct.trkParams.hitsValid); m_corrHists["HitsGood"].fillCorrHistsX(hit, goodHitsPerTrack); m_corrHists["HitsInvalid"].fillCorrHistsX(hit, trackStruct.trkParams.hitsInvalid); m_corrHists["Hits2D"].fillCorrHistsX(hit, trackStruct.trkParams.hits2D); m_corrHists["LayersMissed"].fillCorrHistsX(hit, trackStruct.trkParams.layersMissed); m_corrHists["HitsPixel"].fillCorrHistsX(hit, trackStruct.trkParams.hitsPixel); m_corrHists["HitsStrip"].fillCorrHistsX(hit, trackStruct.trkParams.hitsStrip); m_corrHists["NorChi2"].fillCorrHistsX(hit, trackStruct.trkParams.norChi2); m_corrHists["Theta"].fillCorrHistsX(hit, trackStruct.trkParams.theta * 180. / M_PI); m_corrHists["Phi"].fillCorrHistsX(hit, trackStruct.trkParams.phi * 180. / M_PI); m_corrHists["D0Beamspot"].fillCorrHistsX(hit, trackStruct.trkParams.d0Beamspot); m_corrHists["Dz"].fillCorrHistsX(hit, trackStruct.trkParams.dz); m_corrHists["Pt"].fillCorrHistsX(hit, trackStruct.trkParams.pt); m_corrHists["P"].fillCorrHistsX(hit, trackStruct.trkParams.p); m_corrHists["InvP"].fillCorrHistsX(hit, 1. / trackStruct.trkParams.p); m_corrHists["MeanAngle"].fillCorrHistsX(hit, trackStruct.trkParams.meanPhiSensToNorm * 180. / M_PI); } if (hit.goodYMeasurement) { std::map<std::string, TrackerSectorStruct::CorrelationHists>& m_corrHists(sector.m_correlationHistsY); // Cluster and Hit Parameters this->fillHitHistsYForAnalyzerMode(hit, sector); // Track Parameters m_corrHists["HitsValid"].fillCorrHistsY(hit, trackStruct.trkParams.hitsValid); m_corrHists["HitsGood"].fillCorrHistsY(hit, goodHitsPerTrack); m_corrHists["HitsInvalid"].fillCorrHistsY(hit, trackStruct.trkParams.hitsInvalid); m_corrHists["Hits2D"].fillCorrHistsY(hit, trackStruct.trkParams.hits2D); m_corrHists["LayersMissed"].fillCorrHistsY(hit, trackStruct.trkParams.layersMissed); m_corrHists["HitsPixel"].fillCorrHistsY(hit, trackStruct.trkParams.hitsPixel); m_corrHists["HitsStrip"].fillCorrHistsY(hit, trackStruct.trkParams.hitsStrip); m_corrHists["NorChi2"].fillCorrHistsY(hit, trackStruct.trkParams.norChi2); m_corrHists["Theta"].fillCorrHistsY(hit, trackStruct.trkParams.theta * 180. / M_PI); m_corrHists["Phi"].fillCorrHistsY(hit, trackStruct.trkParams.phi * 180. / M_PI); m_corrHists["D0Beamspot"].fillCorrHistsY(hit, trackStruct.trkParams.d0Beamspot); m_corrHists["Dz"].fillCorrHistsY(hit, trackStruct.trkParams.dz); m_corrHists["Pt"].fillCorrHistsY(hit, trackStruct.trkParams.pt); m_corrHists["P"].fillCorrHistsY(hit, trackStruct.trkParams.p); m_corrHists["InvP"].fillCorrHistsY(hit, 1. / trackStruct.trkParams.p); m_corrHists["MeanAngle"].fillCorrHistsY(hit, trackStruct.trkParams.meanPhiSensToNorm * 180. / M_PI); } // Special Histograms for (auto& i_sigmaX : sector.m_sigmaX) { for (auto& iHist : i_sigmaX.second) { if (i_sigmaX.first == "sigmaXHit") iHist->Fill(hit.errXHit * 10000.); else if (i_sigmaX.first == "sigmaXTrk") iHist->Fill(hit.errXTrk * 10000.); else if (i_sigmaX.first == "sigmaX") iHist->Fill(hit.errX * 10000.); } } for (auto& i_sigmaY : sector.m_sigmaY) { for (auto& iHist : i_sigmaY.second) { if (i_sigmaY.first == "sigmaYHit") iHist->Fill(hit.errYHit * 10000.); else if (i_sigmaY.first == "sigmaYTrk") iHist->Fill(hit.errYTrk * 10000.); else if (i_sigmaY.first == "sigmaY") iHist->Fill(hit.errY * 10000.); } } } } } void ApeEstimator::fillHitHistsXForAnalyzerMode(const TrackStruct::HitParameterStruct& hit, TrackerSectorStruct& sector) { std::map<std::string, TrackerSectorStruct::CorrelationHists>& m_corrHists(sector.m_correlationHistsX); // Cluster Parameters m_corrHists["WidthX"].fillCorrHistsX(hit, hit.widthX); m_corrHists["BaryStripX"].fillCorrHistsX(hit, hit.baryStripX); if (hit.isPixelHit) { m_corrHists["ChargePixel"].fillCorrHistsX(hit, hit.chargePixel); m_corrHists["ClusterProbXY"].fillCorrHistsX(hit, hit.clusterProbabilityXY); m_corrHists["ClusterProbQ"].fillCorrHistsX(hit, hit.clusterProbabilityQ); m_corrHists["ClusterProbXYQ"].fillCorrHistsX(hit, hit.clusterProbabilityXYQ); m_corrHists["LogClusterProb"].fillCorrHistsX(hit, hit.logClusterProbability); m_corrHists["IsOnEdge"].fillCorrHistsX(hit, hit.isOnEdge); m_corrHists["HasBadPixels"].fillCorrHistsX(hit, hit.hasBadPixels); m_corrHists["SpansTwoRoc"].fillCorrHistsX(hit, hit.spansTwoRoc); m_corrHists["QBin"].fillCorrHistsX(hit, hit.qBin); } else { m_corrHists["ChargeStrip"].fillCorrHistsX(hit, hit.chargeStrip); m_corrHists["MaxStrip"].fillCorrHistsX(hit, hit.maxStrip); m_corrHists["MaxCharge"].fillCorrHistsX(hit, hit.maxCharge); m_corrHists["MaxIndex"].fillCorrHistsX(hit, hit.maxIndex); m_corrHists["ChargeOnEdges"].fillCorrHistsX(hit, hit.chargeOnEdges); m_corrHists["ChargeAsymmetry"].fillCorrHistsX(hit, hit.chargeAsymmetry); m_corrHists["ChargeLRplus"].fillCorrHistsX(hit, hit.chargeLRplus); m_corrHists["ChargeLRminus"].fillCorrHistsX(hit, hit.chargeLRminus); m_corrHists["SOverN"].fillCorrHistsX(hit, hit.sOverN); m_corrHists["WidthProj"].fillCorrHistsX(hit, hit.projWidth); m_corrHists["WidthDiff"].fillCorrHistsX(hit, hit.projWidth - static_cast<float>(hit.widthX)); sector.WidthVsWidthProjected->Fill(hit.projWidth, hit.widthX); sector.PWidthVsWidthProjected->Fill(hit.projWidth, hit.widthX); sector.WidthDiffVsMaxStrip->Fill(hit.maxStrip, hit.projWidth - static_cast<float>(hit.widthX)); sector.PWidthDiffVsMaxStrip->Fill(hit.maxStrip, hit.projWidth - static_cast<float>(hit.widthX)); sector.WidthDiffVsSigmaXHit->Fill(hit.errXHit, hit.projWidth - static_cast<float>(hit.widthX)); sector.PWidthDiffVsSigmaXHit->Fill(hit.errXHit, hit.projWidth - static_cast<float>(hit.widthX)); sector.WidthVsPhiSensX->Fill(hit.phiSensX * 180. / M_PI, hit.widthX); sector.PWidthVsPhiSensX->Fill(hit.phiSensX * 180. / M_PI, hit.widthX); } // Hit Parameters m_corrHists["SigmaXHit"].fillCorrHistsX(hit, hit.errXHit * 10000.); m_corrHists["SigmaXTrk"].fillCorrHistsX(hit, hit.errXTrk * 10000.); m_corrHists["SigmaX"].fillCorrHistsX(hit, hit.errX * 10000.); m_corrHists["PhiSens"].fillCorrHistsX(hit, hit.phiSens * 180. / M_PI); m_corrHists["PhiSensX"].fillCorrHistsX(hit, hit.phiSensX * 180. / M_PI); m_corrHists["PhiSensY"].fillCorrHistsX(hit, hit.phiSensY * 180. / M_PI); sector.XHit->Fill(hit.xHit); sector.XTrk->Fill(hit.xTrk); sector.SigmaX2->Fill(hit.errX2 * 10000. * 10000.); sector.ResX->Fill(hit.resX * 10000.); sector.NorResX->Fill(hit.norResX); sector.ProbX->Fill(hit.probX); sector.PhiSensXVsBarycentreX->Fill(hit.baryStripX, hit.phiSensX * 180. / M_PI); sector.PPhiSensXVsBarycentreX->Fill(hit.baryStripX, hit.phiSensX * 180. / M_PI); } void ApeEstimator::fillHitHistsYForAnalyzerMode(const TrackStruct::HitParameterStruct& hit, TrackerSectorStruct& sector) { std::map<std::string, TrackerSectorStruct::CorrelationHists>& m_corrHists(sector.m_correlationHistsY); // Do not fill anything for strip if (!hit.isPixelHit) return; // Cluster Parameters m_corrHists["WidthY"].fillCorrHistsY(hit, hit.widthY); m_corrHists["BaryStripY"].fillCorrHistsY(hit, hit.baryStripY); m_corrHists["ChargePixel"].fillCorrHistsY(hit, hit.chargePixel); m_corrHists["ClusterProbXY"].fillCorrHistsY(hit, hit.clusterProbabilityXY); m_corrHists["ClusterProbQ"].fillCorrHistsY(hit, hit.clusterProbabilityQ); m_corrHists["ClusterProbXYQ"].fillCorrHistsY(hit, hit.clusterProbabilityXYQ); m_corrHists["LogClusterProb"].fillCorrHistsY(hit, hit.logClusterProbability); m_corrHists["IsOnEdge"].fillCorrHistsY(hit, hit.isOnEdge); m_corrHists["HasBadPixels"].fillCorrHistsY(hit, hit.hasBadPixels); m_corrHists["SpansTwoRoc"].fillCorrHistsY(hit, hit.spansTwoRoc); m_corrHists["QBin"].fillCorrHistsY(hit, hit.qBin); // Hit Parameters m_corrHists["SigmaYHit"].fillCorrHistsY(hit, hit.errYHit * 10000.); m_corrHists["SigmaYTrk"].fillCorrHistsY(hit, hit.errYTrk * 10000.); m_corrHists["SigmaY"].fillCorrHistsY(hit, hit.errY * 10000.); m_corrHists["PhiSens"].fillCorrHistsY(hit, hit.phiSens * 180. / M_PI); m_corrHists["PhiSensX"].fillCorrHistsY(hit, hit.phiSensX * 180. / M_PI); m_corrHists["PhiSensY"].fillCorrHistsY(hit, hit.phiSensY * 180. / M_PI); sector.YHit->Fill(hit.yHit); sector.YTrk->Fill(hit.yTrk); sector.SigmaY2->Fill(hit.errY2 * 10000. * 10000.); sector.ResY->Fill(hit.resY * 10000.); sector.NorResY->Fill(hit.norResY); sector.ProbY->Fill(hit.probY); sector.PhiSensYVsBarycentreY->Fill(hit.baryStripY, hit.phiSensY * 180. / M_PI); sector.PPhiSensYVsBarycentreY->Fill(hit.baryStripY, hit.phiSensY * 180. / M_PI); } void ApeEstimator::fillHistsForApeCalculation(const TrackStruct& trackStruct) { unsigned int goodHitsPerTrack(trackStruct.v_hitParams.size()); if (parameterSet_.getParameter<bool>("applyTrackCuts")) { // which tracks to take? need min. nr. of selected hits? if (goodHitsPerTrack < minGoodHitsPerTrack_) return; } for (auto const& i_hit : trackStruct.v_hitParams) { // Put here from earlier method if (i_hit.hitState == TrackStruct::notAssignedToSectors) continue; for (auto& i_sector : m_tkSector_) { bool moduleInSector(false); for (auto const& i_hitSector : i_hit.v_sector) { if (i_sector.first == i_hitSector) { moduleInSector = true; break; } } if (!moduleInSector) continue; if (!calculateApe_) continue; if (i_hit.goodXMeasurement) { for (auto const& i_errBins : m_resErrBins_) { // Separate the bins for residual resolution w/o APE, to be consistent within iterations where APE will change (have same hit always in same bin) // So also fill this value in the histogram sigmaX // But of course use the normalized residual regarding the APE to have its influence in its width if (i_hit.errXWoApe < i_errBins.second.first || i_hit.errXWoApe >= i_errBins.second.second) { continue; } i_sector.second.m_binnedHists[i_errBins.first]["sigmaX"]->Fill(i_hit.errXWoApe); i_sector.second.m_binnedHists[i_errBins.first]["norResX"]->Fill(i_hit.norResX); break; } i_sector.second.ResX->Fill(i_hit.resX * 10000.); i_sector.second.NorResX->Fill(i_hit.norResX); } if (i_hit.goodYMeasurement) { for (auto const& i_errBins : m_resErrBins_) { // Separate the bins for residual resolution w/o APE, to be consistent within iterations where APE will change (have same hit always in same bin) // So also fill this value in the histogram sigmaY // But of course use the normalized residual regarding the APE to have its influence in its width if (i_hit.errYWoApe < i_errBins.second.first || i_hit.errYWoApe >= i_errBins.second.second) { continue; } i_sector.second.m_binnedHists[i_errBins.first]["sigmaY"]->Fill(i_hit.errYWoApe); i_sector.second.m_binnedHists[i_errBins.first]["norResY"]->Fill(i_hit.norResY); break; } i_sector.second.ResY->Fill(i_hit.resY * 10000.); i_sector.second.NorResY->Fill(i_hit.norResY); } } } } // ----------------------------------------------------------------------------------------------------------- void ApeEstimator::calculateAPE() { // Loop over sectors for calculating APE for (auto& i_sector : m_tkSector_) { // Loop over residual error bins to calculate APE for every bin for (auto const& i_errBins : i_sector.second.m_binnedHists) { std::map<std::string, TH1*> m_Hists = i_errBins.second; // Fitting Parameters double integralX = m_Hists["norResX"]->Integral(); i_sector.second.EntriesX->SetBinContent(i_errBins.first, integralX); if (i_sector.second.isPixel) { double integralY = m_Hists["norResY"]->Integral(); i_sector.second.EntriesY->SetBinContent(i_errBins.first, integralY); } } } } // ----------------------------------------------------------------------------------------------------------- bool ApeEstimator::isHit2D(const TrackingRecHit& hit) const { // we count SiStrip stereo modules as 2D if selected via countStereoHitAs2D_ // (since they provide theta information) // --- NO, here it is always set to true --- if (!hit.isValid() || (hit.dimension() < 2 && !dynamic_cast<const SiStripRecHit1D*>(&hit))) { return false; // real RecHit1D - but SiStripRecHit1D depends on countStereoHitAs2D_ } else { const DetId detId(hit.geographicalId()); if (detId.det() == DetId::Tracker) { if (detId.subdetId() == PixelSubdetector::PixelBarrel || detId.subdetId() == PixelSubdetector::PixelEndcap) { return true; // pixel is always 2D } else { // should be SiStrip now const SiStripDetId stripId(detId); if (stripId.stereo()) return true; // stereo modules else if (dynamic_cast<const SiStripRecHit1D*>(&hit) || dynamic_cast<const SiStripRecHit2D*>(&hit)) return false; // rphi modules hit //the following two are not used any more since ages... else if (dynamic_cast<const SiStripMatchedRecHit2D*>(&hit)) return true; // matched is 2D else if (dynamic_cast<const ProjectedSiStripRecHit2D*>(&hit)) { const ProjectedSiStripRecHit2D* pH = static_cast<const ProjectedSiStripRecHit2D*>(&hit); return (this->isHit2D(pH->originalHit())); // depends on original... } else { edm::LogError("UnknownType") << "@SUB=ApeEstimator::isHit2D" << "Tracker hit not in pixel, neither SiStripRecHit[12]D nor " << "SiStripMatchedRecHit2D nor ProjectedSiStripRecHit2D."; return false; } } } else { // not tracker?? edm::LogWarning("DetectorMismatch") << "@SUB=ApeEstimator::isHit2D" << "Hit not in tracker with 'official' dimension >=2."; return true; // dimension() >= 2 so accept that... } } // never reached... } // ----------------------------------------------------------------------------------------------------------- // ------------ method called to for each event ------------ void ApeEstimator::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { reco::BeamSpot beamSpot; edm::Handle<reco::BeamSpot> beamSpotHandle; iEvent.getByToken(offlinebeamSpot_, beamSpotHandle); if (beamSpotHandle.isValid()) { beamSpot = *beamSpotHandle; } else { edm::LogError("ApeEstimator") << "No beam spot available from EventSetup" << "\n...skip event"; return; } edm::Handle<TrajTrackAssociationCollection> m_TrajTracksMap; iEvent.getByToken(tjTagToken_, m_TrajTracksMap); siStripClusterInfo_.initEvent(iSetup); if (analyzerMode_) tkDetector_.TrkSize->Fill(m_TrajTracksMap->size()); if (maxTracksPerEvent_ != 0 && m_TrajTracksMap->size() > maxTracksPerEvent_) return; //Creation of (traj,track) typedef std::pair<const Trajectory*, const reco::Track*> ConstTrajTrackPair; typedef std::vector<ConstTrajTrackPair> ConstTrajTrackPairCollection; ConstTrajTrackPairCollection trajTracks; TrajTrackAssociationCollection::const_iterator i_trajTrack; for (i_trajTrack = m_TrajTracksMap->begin(); i_trajTrack != m_TrajTracksMap->end(); ++i_trajTrack) { trajTracks.push_back(ConstTrajTrackPair(&(*(*i_trajTrack).key), &(*(*i_trajTrack).val))); } //Loop over Tracks & Hits unsigned int trackSizeGood(0); ConstTrajTrackPairCollection::const_iterator iTrack; for (iTrack = trajTracks.begin(); iTrack != trajTracks.end(); ++iTrack) { const Trajectory* traj = (*iTrack).first; const reco::Track* track = (*iTrack).second; TrackStruct trackStruct; trackStruct.trkParams = this->fillTrackVariables(*track, *traj, beamSpot); if (trackCut_) continue; const std::vector<TrajectoryMeasurement> v_meas = (*traj).measurements(); //Loop over Hits for (std::vector<TrajectoryMeasurement>::const_iterator i_meas = v_meas.begin(); i_meas != v_meas.end(); ++i_meas) { TrackStruct::HitParameterStruct hitParams = this->fillHitVariables(*i_meas, iSetup); if (this->hitSelected(hitParams)) trackStruct.v_hitParams.push_back(hitParams); } if (analyzerMode_) this->fillHistsForAnalyzerMode(trackStruct); if (calculateApe_) this->fillHistsForApeCalculation(trackStruct); if (!trackStruct.v_hitParams.empty()) ++trackSizeGood; } if (analyzerMode_ && trackSizeGood > 0) tkDetector_.TrkSizeGood->Fill(trackSizeGood); } // ------------ method called once each job just before starting event loop ------------ void ApeEstimator::beginJob() { this->hitSelection(); this->sectorBuilder(); this->residualErrorBinning(); if (analyzerMode_) this->bookSectorHistsForAnalyzerMode(); if (calculateApe_) this->bookSectorHistsForApeCalculation(); if (analyzerMode_) this->bookTrackHists(); } // ------------ method called once each job just after ending the event loop ------------ void ApeEstimator::endJob() { if (calculateApe_) this->calculateAPE(); edm::LogInfo("HitSelector") << "\nThere are " << counter1 << " negative Errors calculated\n"; } //define this as a plug-in DEFINE_FWK_MODULE(ApeEstimator);