Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-07 04:35:06

0001 // -*- C++ -*-
0002 //
0003 // Package:    CalibTracker/SiPixelLorentzAnglePCLWorker
0004 // Class:      SiPixelLorentzAnglePCLWorker
0005 //
0006 /**\class SiPixelLorentzAnglePCLWorker SiPixelLorentzAnglePCLWorker.cc CalibTracker/SiPixelLorentzAnglePCLWorker/src/SiPixelLorentzAnglePCLWorker.cc
0007  Description: generates the intermediate ALCAPROMPT dataset for the measurement of the SiPixel Lorentz Angle in the Prompt Calibration Loop
0008  Implementation:
0009      Books and fills 2D histograms of the drift vs depth in bins of pixel module rings to be fed into the SiPixelLorentzAnglePCLHarvester
0010 */
0011 //
0012 // Original Author:  mmusich
0013 //         Created:  Sat, 29 May 2021 14:46:19 GMT
0014 //
0015 //
0016 
0017 // system includes
0018 #include <string>
0019 #include <fmt/printf.h>
0020 
0021 // user include files
0022 #include "CalibTracker/Records/interface/SiPixelTemplateDBObjectESProducerRcd.h"
0023 #include "CalibTracker/SiPixelLorentzAngle/interface/SiPixelLorentzAngleCalibrationStruct.h"
0024 #include "CondFormats/SiPixelObjects/interface/SiPixelTemplateDBObject.h"
0025 #include "CondFormats/SiPixelTransient/interface/SiPixelTemplate.h"
0026 #include "CondFormats/SiPixelTransient/interface/SiPixelTemplateDefs.h"
0027 #include "DQMServices/Core/interface/DQMEDAnalyzer.h"
0028 #include "DQMServices/Core/interface/DQMStore.h"
0029 #include "DataFormats/GeometryVector/interface/GlobalVector.h"
0030 #include "DataFormats/GeometryVector/interface/LocalVector.h"
0031 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
0032 #include "DataFormats/TrackReco/interface/TrackExtra.h"
0033 #include "DataFormats/TrackReco/interface/TrackFwd.h"
0034 #include "DataFormats/TrackerCommon/interface/PixelBarrelName.h"
0035 #include "DataFormats/TrackerCommon/interface/PixelEndcapName.h"
0036 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
0037 #include "DataFormats/TrackerRecHit2D/interface/SiPixelRecHit.h"
0038 #include "DataFormats/TrackerRecHit2D/interface/SiStripMatchedRecHit2D.h"
0039 #include "DataFormats/TrajectorySeed/interface/TrajectorySeedCollection.h"
0040 #include "FWCore/Framework/interface/Event.h"
0041 #include "FWCore/Framework/interface/ESWatcher.h"
0042 #include "FWCore/Framework/interface/Frameworkfwd.h"
0043 #include "FWCore/Framework/interface/MakerMacros.h"
0044 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0045 #include "Geometry/CommonDetUnit/interface/GeomDetType.h"
0046 #include "Geometry/CommonTopologies/interface/StripTopology.h"
0047 #include "Geometry/Records/interface/IdealGeometryRecord.h"
0048 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
0049 #include "Geometry/TrackerGeometryBuilder/interface/PixelTopologyMap.h"
0050 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
0051 #include "Geometry/CommonTopologies/interface/SimplePixelTopology.h"
0052 #include "RecoTracker/TransientTrackingRecHit/interface/TkTransientTrackingRecHitBuilder.h"
0053 #include "TrackingTools/PatternTools/interface/TrajTrackAssociation.h"
0054 #include "TrackingTools/Records/interface/TransientRecHitRecord.h"
0055 #include "TrackingTools/TrackFitters/interface/TrajectoryStateCombiner.h"
0056 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
0057 #include "MagneticField/Engine/interface/MagneticField.h"
0058 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
0059 
0060 // ROOT includes
0061 #include <TTree.h>
0062 #include <TFile.h>
0063 #include <fstream>
0064 
0065 //
0066 // class declaration
0067 //
0068 
0069 static const int maxpix = 1000;
0070 struct Pixinfo {
0071   int npix;
0072   float row[maxpix];
0073   float col[maxpix];
0074   float adc[maxpix];
0075   float x[maxpix];
0076   float y[maxpix];
0077 };
0078 
0079 struct Hit {
0080   float x;
0081   float y;
0082   double alpha;
0083   double beta;
0084   double gamma;
0085 };
0086 struct Clust {
0087   float x;
0088   float y;
0089   float charge;
0090   int size_x;
0091   int size_y;
0092   int maxPixelCol;
0093   int maxPixelRow;
0094   int minPixelCol;
0095   int minPixelRow;
0096 };
0097 struct Rechit {
0098   float x;
0099   float y;
0100 };
0101 
0102 enum LorentzAngleAnalysisTypeEnum { eGrazingAngle, eMinimumClusterSize };
0103 
0104 class SiPixelLorentzAnglePCLWorker : public DQMEDAnalyzer {
0105 public:
0106   explicit SiPixelLorentzAnglePCLWorker(const edm::ParameterSet&);
0107   ~SiPixelLorentzAnglePCLWorker() override = default;
0108 
0109   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0110 
0111 private:
0112   void bookHistograms(DQMStore::IBooker&, edm::Run const&, edm::EventSetup const&) override;
0113 
0114   void analyze(edm::Event const&, edm::EventSetup const&) override;
0115 
0116   void dqmBeginRun(edm::Run const&, edm::EventSetup const&) override;
0117 
0118   void dqmEndRun(edm::Run const&, edm::EventSetup const&);
0119 
0120   const Pixinfo fillPix(const SiPixelCluster& LocPix, const PixelTopology* topol) const;
0121   const std::pair<LocalPoint, LocalPoint> surface_deformation(const PixelTopology* topol,
0122                                                               TrajectoryStateOnSurface& tsos,
0123                                                               const SiPixelRecHit* recHitPix) const;
0124   LorentzAngleAnalysisTypeEnum convertStringToLorentzAngleAnalysisTypeEnum(std::string type);
0125   // ------------ member data ------------
0126   SiPixelLorentzAngleCalibrationHistograms iHists;
0127 
0128   // template stuff
0129   edm::ESWatcher<SiPixelTemplateDBObjectESProducerRcd> watchSiPixelTemplateRcd_;
0130   const SiPixelTemplateDBObject* templateDBobject_;
0131   const std::vector<SiPixelTemplateStore>* thePixelTemp_ = nullptr;
0132 
0133   LorentzAngleAnalysisTypeEnum analysisType_;
0134   std::string folder_;
0135   bool notInPCL_;
0136   std::string filename_;
0137   std::vector<std::string> newmodulelist_;
0138 
0139   // tree branches barrel
0140   int run_;
0141   long int event_;
0142   int lumiblock_;
0143   int bx_;
0144   int orbit_;
0145   int module_;
0146   int ladder_;
0147   int layer_;
0148   int isflipped_;
0149   float pt_;
0150   float eta_;
0151   float phi_;
0152   double chi2_;
0153   double ndof_;
0154   Pixinfo pixinfo_;
0155   Hit simhit_, trackhit_;
0156   Clust clust_;
0157   Rechit rechit_;
0158   Rechit rechitCorr_;
0159   float trackhitCorrX_;
0160   float trackhitCorrY_;
0161   float qScale_;
0162   float rQmQt_;
0163 
0164   // tree branches forward
0165   int sideF_;
0166   int diskF_;
0167   int bladeF_;
0168   int panelF_;
0169   int moduleF_;
0170   Pixinfo pixinfoF_;
0171   Hit simhitF_, trackhitF_;
0172   Clust clustF_;
0173   Rechit rechitF_;
0174   Rechit rechitCorrF_;
0175   float trackhitCorrXF_;
0176   float trackhitCorrYF_;
0177   float qScaleF_;
0178   float rQmQtF_;
0179 
0180   // parameters from config file
0181   double ptmin_;
0182   double normChi2Max_;
0183   std::vector<int> clustSizeYMin_;
0184   int clustSizeXMax_;
0185   double residualMax_;
0186   double clustChargeMaxPerLength_;
0187   int hist_depth_;
0188   int hist_drift_;
0189 
0190   std::unique_ptr<TFile> hFile_;
0191   std::unique_ptr<TTree> SiPixelLorentzAngleTreeBarrel_;
0192   std::unique_ptr<TTree> SiPixelLorentzAngleTreeForward_;
0193 
0194   // es consumes
0195   edm::ESGetToken<TrackerGeometry, TrackerDigiGeometryRecord> geomEsToken_;
0196   edm::ESGetToken<TrackerTopology, TrackerTopologyRcd> topoEsToken_;
0197   edm::ESGetToken<SiPixelTemplateDBObject, SiPixelTemplateDBObjectESProducerRcd> siPixelTemplateEsToken_;
0198   edm::ESGetToken<std::vector<SiPixelTemplateStore>, SiPixelTemplateDBObjectESProducerRcd> siPixelTemplateStoreEsToken_;
0199   edm::ESGetToken<TrackerTopology, TrackerTopologyRcd> topoPerEventEsToken_;
0200   edm::ESGetToken<TrackerGeometry, TrackerDigiGeometryRecord> geomPerEventEsToken_;
0201   edm::ESGetToken<MagneticField, IdealMagneticFieldRecord> magneticFieldToken_;
0202 
0203   // event consumes
0204   edm::EDGetTokenT<TrajTrackAssociationCollection> t_trajTrack;
0205 };
0206 
0207 //
0208 // constructors and destructor
0209 //
0210 SiPixelLorentzAnglePCLWorker::SiPixelLorentzAnglePCLWorker(const edm::ParameterSet& iConfig)
0211     : analysisType_(convertStringToLorentzAngleAnalysisTypeEnum(iConfig.getParameter<std::string>("analysisType"))),
0212       folder_(iConfig.getParameter<std::string>("folder")),
0213       notInPCL_(iConfig.getParameter<bool>("notInPCL")),
0214       filename_(iConfig.getParameter<std::string>("fileName")),
0215       newmodulelist_(iConfig.getParameter<std::vector<std::string>>("newmodulelist")),
0216       ptmin_(iConfig.getParameter<double>("ptMin")),
0217       normChi2Max_(iConfig.getParameter<double>("normChi2Max")),
0218       clustSizeYMin_(iConfig.getParameter<std::vector<int>>("clustSizeYMin")),
0219       clustSizeXMax_(iConfig.getParameter<int>("clustSizeXMax")),
0220       residualMax_(iConfig.getParameter<double>("residualMax")),
0221       clustChargeMaxPerLength_(iConfig.getParameter<double>("clustChargeMaxPerLength")),
0222       hist_depth_(iConfig.getParameter<int>("binsDepth")),
0223       hist_drift_(iConfig.getParameter<int>("binsDrift")),
0224       geomEsToken_(esConsumes<edm::Transition::BeginRun>()),
0225       topoEsToken_(esConsumes<edm::Transition::BeginRun>()),
0226       siPixelTemplateEsToken_(esConsumes<edm::Transition::BeginRun>()),
0227       siPixelTemplateStoreEsToken_(esConsumes<edm::Transition::BeginRun>()),
0228       topoPerEventEsToken_(esConsumes()),
0229       geomPerEventEsToken_(esConsumes()),
0230       magneticFieldToken_(esConsumes()) {
0231   t_trajTrack = consumes<TrajTrackAssociationCollection>(iConfig.getParameter<edm::InputTag>("src"));
0232 
0233   // now do what ever initialization is needed
0234   int bufsize = 64000;
0235   //    create tree structure
0236   //    Barrel pixel
0237   if (notInPCL_) {
0238     hFile_ = std::make_unique<TFile>(filename_.c_str(), "RECREATE");
0239     SiPixelLorentzAngleTreeBarrel_ =
0240         std::make_unique<TTree>("SiPixelLorentzAngleTreeBarrel_", "SiPixel LorentzAngle tree barrel", bufsize);
0241     SiPixelLorentzAngleTreeBarrel_->Branch("run", &run_, "run/I", bufsize);
0242     SiPixelLorentzAngleTreeBarrel_->Branch("event", &event_, "event/l", bufsize);
0243     SiPixelLorentzAngleTreeBarrel_->Branch("lumiblock", &lumiblock_, "lumiblock/I", bufsize);
0244     SiPixelLorentzAngleTreeBarrel_->Branch("bx", &bx_, "bx/I", bufsize);
0245     SiPixelLorentzAngleTreeBarrel_->Branch("orbit", &orbit_, "orbit/I", bufsize);
0246     SiPixelLorentzAngleTreeBarrel_->Branch("module", &module_, "module/I", bufsize);
0247     SiPixelLorentzAngleTreeBarrel_->Branch("ladder", &ladder_, "ladder/I", bufsize);
0248     SiPixelLorentzAngleTreeBarrel_->Branch("layer", &layer_, "layer/I", bufsize);
0249     SiPixelLorentzAngleTreeBarrel_->Branch("isflipped", &isflipped_, "isflipped/I", bufsize);
0250     SiPixelLorentzAngleTreeBarrel_->Branch("pt", &pt_, "pt/F", bufsize);
0251     SiPixelLorentzAngleTreeBarrel_->Branch("eta", &eta_, "eta/F", bufsize);
0252     SiPixelLorentzAngleTreeBarrel_->Branch("phi", &phi_, "phi/F", bufsize);
0253     SiPixelLorentzAngleTreeBarrel_->Branch("chi2", &chi2_, "chi2/D", bufsize);
0254     SiPixelLorentzAngleTreeBarrel_->Branch("ndof", &ndof_, "ndof/D", bufsize);
0255     SiPixelLorentzAngleTreeBarrel_->Branch("trackhit", &trackhit_, "x/F:y/F:alpha/D:beta/D:gamma_/D", bufsize);
0256     SiPixelLorentzAngleTreeBarrel_->Branch("npix", &pixinfo_.npix, "npix/I", bufsize);
0257     SiPixelLorentzAngleTreeBarrel_->Branch("rowpix", pixinfo_.row, "row[npix]/F", bufsize);
0258     SiPixelLorentzAngleTreeBarrel_->Branch("colpix", pixinfo_.col, "col[npix]/F", bufsize);
0259     SiPixelLorentzAngleTreeBarrel_->Branch("adc", pixinfo_.adc, "adc[npix]/F", bufsize);
0260     SiPixelLorentzAngleTreeBarrel_->Branch("xpix", pixinfo_.x, "x[npix]/F", bufsize);
0261     SiPixelLorentzAngleTreeBarrel_->Branch("ypix", pixinfo_.y, "y[npix]/F", bufsize);
0262 
0263     SiPixelLorentzAngleTreeBarrel_->Branch(
0264         "clust",
0265         &clust_,
0266         "x/F:y/F:charge/F:size_x/I:size_y/I:maxPixelCol/I:maxPixelRow:minPixelCol/I:minPixelRow/I",
0267         bufsize);
0268     SiPixelLorentzAngleTreeBarrel_->Branch("rechit", &rechit_, "x/F:y/F", bufsize);
0269     SiPixelLorentzAngleTreeBarrel_->Branch("rechit_corr", &rechitCorr_, "x/F:y/F", bufsize);
0270     SiPixelLorentzAngleTreeBarrel_->Branch("trackhitcorr_x", &trackhitCorrX_, "trackhitcorr_x/F", bufsize);
0271     SiPixelLorentzAngleTreeBarrel_->Branch("trackhitcorr_y", &trackhitCorrY_, "trackhitcorr_y/F", bufsize);
0272     SiPixelLorentzAngleTreeBarrel_->Branch("qScale", &qScale_, "qScale/F", bufsize);
0273     SiPixelLorentzAngleTreeBarrel_->Branch("rQmQt", &rQmQt_, "rQmQt/F", bufsize);
0274     //    Forward pixel
0275 
0276     SiPixelLorentzAngleTreeForward_ =
0277         std::make_unique<TTree>("SiPixelLorentzAngleTreeForward_", "SiPixel LorentzAngle tree forward", bufsize);
0278     SiPixelLorentzAngleTreeForward_->Branch("run", &run_, "run/I", bufsize);
0279     SiPixelLorentzAngleTreeForward_->Branch("event", &event_, "event/l", bufsize);
0280     SiPixelLorentzAngleTreeForward_->Branch("lumiblock", &lumiblock_, "lumiblock/I", bufsize);
0281     SiPixelLorentzAngleTreeForward_->Branch("bx", &bx_, "bx/I", bufsize);
0282     SiPixelLorentzAngleTreeForward_->Branch("orbit", &orbit_, "orbit/I", bufsize);
0283     SiPixelLorentzAngleTreeForward_->Branch("side", &sideF_, "side/I", bufsize);
0284     SiPixelLorentzAngleTreeForward_->Branch("disk", &diskF_, "disk/I", bufsize);
0285     SiPixelLorentzAngleTreeForward_->Branch("blade", &bladeF_, "blade/I", bufsize);
0286     SiPixelLorentzAngleTreeForward_->Branch("panel", &panelF_, "panel/I", bufsize);
0287     SiPixelLorentzAngleTreeForward_->Branch("module", &moduleF_, "module/I", bufsize);
0288     SiPixelLorentzAngleTreeForward_->Branch("pt", &pt_, "pt/F", bufsize);
0289     SiPixelLorentzAngleTreeForward_->Branch("eta", &eta_, "eta/F", bufsize);
0290     SiPixelLorentzAngleTreeForward_->Branch("phi", &phi_, "phi/F", bufsize);
0291     SiPixelLorentzAngleTreeForward_->Branch("chi2", &chi2_, "chi2/D", bufsize);
0292     SiPixelLorentzAngleTreeForward_->Branch("ndof", &ndof_, "ndof/D", bufsize);
0293     SiPixelLorentzAngleTreeForward_->Branch("trackhit", &trackhitF_, "x/F:y/F:alpha/D:beta/D:gamma_/D", bufsize);
0294     SiPixelLorentzAngleTreeForward_->Branch("npix", &pixinfoF_.npix, "npix/I", bufsize);
0295     SiPixelLorentzAngleTreeForward_->Branch("rowpix", pixinfoF_.row, "row[npix]/F", bufsize);
0296     SiPixelLorentzAngleTreeForward_->Branch("colpix", pixinfoF_.col, "col[npix]/F", bufsize);
0297     SiPixelLorentzAngleTreeForward_->Branch("adc", pixinfoF_.adc, "adc[npix]/F", bufsize);
0298     SiPixelLorentzAngleTreeForward_->Branch("xpix", pixinfoF_.x, "x[npix]/F", bufsize);
0299     SiPixelLorentzAngleTreeForward_->Branch("ypix", pixinfoF_.y, "y[npix]/F", bufsize);
0300 
0301     SiPixelLorentzAngleTreeForward_->Branch(
0302         "clust",
0303         &clustF_,
0304         "x/F:y/F:charge/F:size_x/I:size_y/I:maxPixelCol/I:maxPixelRow:minPixelCol/I:minPixelRow/I",
0305         bufsize);
0306     SiPixelLorentzAngleTreeForward_->Branch("rechit", &rechitF_, "x/F:y/F", bufsize);
0307     SiPixelLorentzAngleTreeForward_->Branch("rechit_corr", &rechitCorrF_, "x/F:y/F", bufsize);
0308     SiPixelLorentzAngleTreeForward_->Branch("trackhitcorr_x", &trackhitCorrXF_, "trackhitcorr_x/F", bufsize);
0309     SiPixelLorentzAngleTreeForward_->Branch("trackhitcorr_y", &trackhitCorrYF_, "trackhitcorr_y/F", bufsize);
0310     SiPixelLorentzAngleTreeForward_->Branch("qScale", &qScaleF_, "qScale/F", bufsize);
0311     SiPixelLorentzAngleTreeForward_->Branch("rQmQt", &rQmQtF_, "rQmQt/F", bufsize);
0312   }
0313 }
0314 
0315 //
0316 // member functions
0317 //
0318 
0319 // ------------ method called for each event  ------------
0320 
0321 void SiPixelLorentzAnglePCLWorker::analyze(edm::Event const& iEvent, edm::EventSetup const& iSetup) {
0322   // Retrieve tracker topology from geometry
0323   const TrackerTopology* const tTopo = &iSetup.getData(topoPerEventEsToken_);
0324 
0325   // Retrieve track geometry
0326   const TrackerGeometry* tracker = &iSetup.getData(geomPerEventEsToken_);
0327 
0328   // Retrieve magnetic field
0329   const MagneticField* magField = &iSetup.getData(magneticFieldToken_);
0330 
0331   // get the association map between tracks and trajectories
0332   edm::Handle<TrajTrackAssociationCollection> trajTrackCollectionHandle;
0333   iEvent.getByToken(t_trajTrack, trajTrackCollectionHandle);
0334 
0335   module_ = -1;
0336   layer_ = -1;
0337   ladder_ = -1;
0338   isflipped_ = -1;
0339   pt_ = -999;
0340   eta_ = 999;
0341   phi_ = 999;
0342   pixinfo_.npix = 0;
0343 
0344   run_ = iEvent.id().run();
0345   event_ = iEvent.id().event();
0346   lumiblock_ = iEvent.luminosityBlock();
0347   bx_ = iEvent.bunchCrossing();
0348   orbit_ = iEvent.orbitNumber();
0349 
0350   if (!trajTrackCollectionHandle->empty()) {
0351     for (TrajTrackAssociationCollection::const_iterator it = trajTrackCollectionHandle->begin();
0352          it != trajTrackCollectionHandle->end();
0353          ++it) {
0354       const reco::Track& track = *it->val;
0355       const Trajectory& traj = *it->key;
0356 
0357       // get the trajectory measurements
0358       std::vector<TrajectoryMeasurement> tmColl = traj.measurements();
0359       pt_ = track.pt();
0360       eta_ = track.eta();
0361       phi_ = track.phi();
0362       chi2_ = traj.chiSquared();
0363       ndof_ = traj.ndof();
0364 
0365       if (pt_ < ptmin_)
0366         continue;
0367 
0368       iHists.h_trackEta_->Fill(eta_);
0369       iHists.h_trackPhi_->Fill(phi_);
0370       iHists.h_trackPt_->Fill(pt_);
0371       iHists.h_trackChi2_->Fill(chi2_ / ndof_);
0372       iHists.h_tracks_->Fill(0);
0373       bool pixeltrack = false;
0374 
0375       // iterate over trajectory measurements
0376       for (const auto& itTraj : tmColl) {
0377         if (!itTraj.updatedState().isValid())
0378           continue;
0379         const TransientTrackingRecHit::ConstRecHitPointer& recHit = itTraj.recHit();
0380         if (!recHit->isValid() || recHit->geographicalId().det() != DetId::Tracker)
0381           continue;
0382         unsigned int subDetID = (recHit->geographicalId().subdetId());
0383         if (subDetID == PixelSubdetector::PixelBarrel || subDetID == PixelSubdetector::PixelEndcap) {
0384           if (!pixeltrack) {
0385             iHists.h_tracks_->Fill(1);
0386           }
0387           pixeltrack = true;
0388         }
0389 
0390         if (subDetID == PixelSubdetector::PixelBarrel) {
0391           DetId detIdObj = recHit->geographicalId();
0392           const PixelGeomDetUnit* theGeomDet = dynamic_cast<const PixelGeomDetUnit*>(tracker->idToDet(detIdObj));
0393           if (!theGeomDet)
0394             continue;
0395 
0396           const PixelTopology* topol = &(theGeomDet->specificTopology());
0397 
0398           float ypitch_ = topol->pitch().second;
0399           float width_ = theGeomDet->surface().bounds().thickness();
0400 
0401           if (!topol)
0402             continue;
0403 
0404           layer_ = tTopo->pxbLayer(detIdObj);
0405           ladder_ = tTopo->pxbLadder(detIdObj);
0406           module_ = tTopo->pxbModule(detIdObj);
0407 
0408           float tmp1 = theGeomDet->surface().toGlobal(Local3DPoint(0., 0., 0.)).perp();
0409           float tmp2 = theGeomDet->surface().toGlobal(Local3DPoint(0., 0., 1.)).perp();
0410 
0411           isflipped_ = (tmp2 < tmp1) ? 1 : 0;
0412 
0413           const SiPixelRecHit* recHitPix = dynamic_cast<const SiPixelRecHit*>((*recHit).hit());
0414           if (!recHitPix)
0415             continue;
0416           rechit_.x = recHitPix->localPosition().x();
0417           rechit_.y = recHitPix->localPosition().y();
0418           SiPixelRecHit::ClusterRef const& cluster = recHitPix->cluster();
0419 
0420           pixinfo_ = fillPix(*cluster, topol);
0421 
0422           // fill entries in clust_
0423 
0424           clust_.x = (cluster)->x();
0425           clust_.y = (cluster)->y();
0426           clust_.charge = (cluster->charge()) / 1000.;  // clust_.charge: in the unit of 1000e
0427           clust_.size_x = cluster->sizeX();
0428           clust_.size_y = cluster->sizeY();
0429           clust_.maxPixelCol = cluster->maxPixelCol();
0430           clust_.maxPixelRow = cluster->maxPixelRow();
0431           clust_.minPixelCol = cluster->minPixelCol();
0432           clust_.minPixelRow = cluster->minPixelRow();
0433 
0434           // fill the trackhit info
0435           TrajectoryStateOnSurface tsos = itTraj.updatedState();
0436           if (!tsos.isValid()) {
0437             edm::LogWarning("SiPixelLorentzAnglePCLWorker") << "tsos not valid";
0438             continue;
0439           }
0440           LocalVector trackdirection = tsos.localDirection();
0441           LocalPoint trackposition = tsos.localPosition();
0442 
0443           if (trackdirection.z() == 0)
0444             continue;
0445           // the local position and direction
0446           trackhit_.alpha = atan2(trackdirection.z(), trackdirection.x());
0447           trackhit_.beta = atan2(trackdirection.z(), trackdirection.y());
0448           trackhit_.gamma = atan2(trackdirection.x(), trackdirection.y());
0449           trackhit_.x = trackposition.x();
0450           trackhit_.y = trackposition.y();
0451 
0452           // get qScale_ = templ.qscale() and  templ.r_qMeas_qTrue();
0453           float cotalpha = trackdirection.x() / trackdirection.z();
0454           float cotbeta = trackdirection.y() / trackdirection.z();
0455           float cotbeta_min = clustSizeYMin_[layer_ - 1] * ypitch_ / width_;
0456           if (std::abs(cotbeta) <= cotbeta_min)
0457             continue;
0458           double drdz = sqrt(1. + cotalpha * cotalpha + cotbeta * cotbeta);
0459           double clusterCharge_cut = clustChargeMaxPerLength_ * drdz;
0460 
0461           auto detId = detIdObj.rawId();
0462           int DetId_index = -1;
0463 
0464           const auto& newModIt = (std::find(iHists.BPixnewDetIds_.begin(), iHists.BPixnewDetIds_.end(), detId));
0465           bool isNewMod = (newModIt != iHists.BPixnewDetIds_.end());
0466           if (isNewMod) {
0467             DetId_index = std::distance(iHists.BPixnewDetIds_.begin(), newModIt);
0468           }
0469 
0470           if (notInPCL_) {
0471             // fill the template from the store (from dqmBeginRun)
0472             SiPixelTemplate theTemplate(*thePixelTemp_);
0473 
0474             float locBx = (cotbeta < 0.) ? -1 : 1.;
0475             float locBz = (cotalpha < 0.) ? -locBx : locBx;
0476 
0477             int TemplID = templateDBobject_->getTemplateID(detId);
0478             theTemplate.interpolate(TemplID, cotalpha, cotbeta, locBz, locBx);
0479             qScale_ = theTemplate.qscale();
0480             rQmQt_ = theTemplate.r_qMeas_qTrue();
0481           }
0482 
0483           // Surface deformation
0484           const auto& lp_pair = surface_deformation(topol, tsos, recHitPix);
0485 
0486           LocalPoint lp_track = lp_pair.first;
0487           LocalPoint lp_rechit = lp_pair.second;
0488 
0489           rechitCorr_.x = lp_rechit.x();
0490           rechitCorr_.y = lp_rechit.y();
0491           trackhitCorrX_ = lp_track.x();
0492           trackhitCorrY_ = lp_track.y();
0493 
0494           if (notInPCL_) {
0495             SiPixelLorentzAngleTreeBarrel_->Fill();
0496           }
0497 
0498           if (analysisType_ != eGrazingAngle)
0499             continue;
0500           // is one pixel in cluster a large pixel ? (hit will be excluded)
0501           bool large_pix = false;
0502           for (int j = 0; j < pixinfo_.npix; j++) {
0503             int colpos = static_cast<int>(pixinfo_.col[j]);
0504             if (pixinfo_.row[j] == 0 || pixinfo_.row[j] == 79 || pixinfo_.row[j] == 80 || pixinfo_.row[j] == 159 ||
0505                 colpos % 52 == 0 || colpos % 52 == 51) {
0506               large_pix = true;
0507             }
0508           }
0509 
0510           double residualsq = (trackhitCorrX_ - rechitCorr_.x) * (trackhitCorrX_ - rechitCorr_.x) +
0511                               (trackhitCorrY_ - rechitCorr_.y) * (trackhitCorrY_ - rechitCorr_.y);
0512 
0513           double xlim1 = trackhitCorrX_ - width_ * cotalpha / 2.;
0514           double hypitch_ = ypitch_ / 2.;
0515           double ylim1 = trackhitCorrY_ - width_ * cotbeta / 2.;
0516           double ylim2 = trackhitCorrY_ + width_ * cotbeta / 2.;
0517 
0518           int clustSizeY_cut = clustSizeYMin_[layer_ - 1];
0519 
0520           if (!large_pix && (chi2_ / ndof_) < normChi2Max_ && cluster->sizeY() >= clustSizeY_cut &&
0521               residualsq < residualMax_ * residualMax_ && cluster->charge() < clusterCharge_cut &&
0522               cluster->sizeX() < clustSizeXMax_) {
0523             // iterate over pixels in hit
0524             for (int j = 0; j < pixinfo_.npix; j++) {
0525               // use trackhits and include bowing correction
0526               float ypixlow = pixinfo_.y[j] - hypitch_;
0527               float ypixhigh = pixinfo_.y[j] + hypitch_;
0528               if (cotbeta > 0.) {
0529                 if (ylim1 > ypixlow)
0530                   ypixlow = ylim1;
0531                 if (ylim2 < ypixhigh)
0532                   ypixhigh = ylim2;
0533               } else {
0534                 if (ylim2 > ypixlow)
0535                   ypixlow = ylim2;
0536                 if (ylim1 < ypixhigh)
0537                   ypixhigh = ylim1;
0538               }
0539               float ypixavg = 0.5f * (ypixlow + ypixhigh);
0540 
0541               float dx = (pixinfo_.x[j] - xlim1) * siPixelLACalibration::cmToum;  // dx: in the unit of micrometer
0542               float dy = (ypixavg - ylim1) * siPixelLACalibration::cmToum;        // dy: in the unit of micrometer
0543               float depth = dy * tan(trackhit_.beta);
0544               float drift = dx - dy * tan(trackhit_.gamma);
0545 
0546               if (isNewMod == false) {
0547                 int i_index = module_ + (layer_ - 1) * iHists.nModules_[layer_ - 1];
0548                 iHists.h_drift_depth_adc_[i_index]->Fill(drift, depth, pixinfo_.adc[j]);
0549                 iHists.h_drift_depth_adc2_[i_index]->Fill(drift, depth, pixinfo_.adc[j] * pixinfo_.adc[j]);
0550                 iHists.h_drift_depth_noadc_[i_index]->Fill(drift, depth, 1.);
0551                 iHists.h_bySectOccupancy_->Fill(i_index - 1);  // histogram starts at 0
0552 
0553                 if (tracker->getDetectorType(subDetID) == TrackerGeometry::ModuleType::Ph1PXB) {
0554                   if ((module_ == 3 || module_ == 5) && (layer_ == 3 || layer_ == 4)) {
0555                     int i_index_merge = i_index + 1;
0556                     iHists.h_drift_depth_adc_[i_index_merge]->Fill(drift, depth, pixinfo_.adc[j]);
0557                     iHists.h_drift_depth_adc2_[i_index_merge]->Fill(drift, depth, pixinfo_.adc[j] * pixinfo_.adc[j]);
0558                     iHists.h_drift_depth_noadc_[i_index_merge]->Fill(drift, depth, 1.);
0559                     iHists.h_bySectOccupancy_->Fill(i_index_merge - 1);
0560                   }
0561                   if ((module_ == 4 || module_ == 6) && (layer_ == 3 || layer_ == 4)) {
0562                     int i_index_merge = i_index - 1;
0563                     iHists.h_drift_depth_adc_[i_index_merge]->Fill(drift, depth, pixinfo_.adc[j]);
0564                     iHists.h_drift_depth_adc2_[i_index_merge]->Fill(drift, depth, pixinfo_.adc[j] * pixinfo_.adc[j]);
0565                     iHists.h_drift_depth_noadc_[i_index_merge]->Fill(drift, depth, 1.);
0566                     iHists.h_bySectOccupancy_->Fill(i_index_merge - 1);
0567                   }
0568                 }
0569 
0570               } else {
0571                 int new_index = iHists.nModules_[iHists.nlay - 1] +
0572                                 (iHists.nlay - 1) * iHists.nModules_[iHists.nlay - 1] + 1 + DetId_index;
0573 
0574                 iHists.h_drift_depth_adc_[new_index]->Fill(drift, depth, pixinfo_.adc[j]);
0575                 iHists.h_drift_depth_adc2_[new_index]->Fill(drift, depth, pixinfo_.adc[j] * pixinfo_.adc[j]);
0576                 iHists.h_drift_depth_noadc_[new_index]->Fill(drift, depth, 1.);
0577                 iHists.h_bySectOccupancy_->Fill(new_index - 1);  // histogram starts at 0
0578               }
0579             }
0580           }
0581         } else if (subDetID == PixelSubdetector::PixelEndcap) {
0582           DetId detIdObj = recHit->geographicalId();
0583           const PixelGeomDetUnit* theGeomDet = dynamic_cast<const PixelGeomDetUnit*>(tracker->idToDet(detIdObj));
0584           if (!theGeomDet)
0585             continue;
0586 
0587           const PixelTopology* topol = &(theGeomDet->specificTopology());
0588 
0589           if (!topol)
0590             continue;
0591 
0592           sideF_ = tTopo->pxfSide(detIdObj);
0593           diskF_ = tTopo->pxfDisk(detIdObj);
0594           bladeF_ = tTopo->pxfBlade(detIdObj);
0595           panelF_ = tTopo->pxfPanel(detIdObj);
0596           moduleF_ = tTopo->pxfModule(detIdObj);
0597 
0598           const SiPixelRecHit* recHitPix = dynamic_cast<const SiPixelRecHit*>((*recHit).hit());
0599           if (!recHitPix)
0600             continue;
0601           rechitF_.x = recHitPix->localPosition().x();
0602           rechitF_.y = recHitPix->localPosition().y();
0603           SiPixelRecHit::ClusterRef const& cluster = recHitPix->cluster();
0604 
0605           pixinfoF_ = fillPix(*cluster, topol);
0606 
0607           // fill entries in clust_
0608 
0609           clustF_.x = (cluster)->x();
0610           clustF_.y = (cluster)->y();
0611           clustF_.charge = (cluster->charge()) / 1000.;  // clustF_.charge: in the unit of 1000e
0612           clustF_.size_x = cluster->sizeX();
0613           clustF_.size_y = cluster->sizeY();
0614           clustF_.maxPixelCol = cluster->maxPixelCol();
0615           clustF_.maxPixelRow = cluster->maxPixelRow();
0616           clustF_.minPixelCol = cluster->minPixelCol();
0617           clustF_.minPixelRow = cluster->minPixelRow();
0618 
0619           // fill the trackhit info
0620           TrajectoryStateOnSurface tsos = itTraj.updatedState();
0621           if (!tsos.isValid()) {
0622             edm::LogWarning("SiPixelLorentzAnglePCLWorker") << "tsos not valid";
0623             continue;
0624           }
0625           LocalVector trackdirection = tsos.localDirection();
0626           LocalPoint trackposition = tsos.localPosition();
0627 
0628           if (trackdirection.z() == 0)
0629             continue;
0630           // the local position and direction
0631           trackhitF_.alpha = atan2(trackdirection.z(), trackdirection.x());
0632           trackhitF_.beta = atan2(trackdirection.z(), trackdirection.y());
0633           trackhitF_.gamma = atan2(trackdirection.x(), trackdirection.y());
0634           trackhitF_.x = trackposition.x();
0635           trackhitF_.y = trackposition.y();
0636 
0637           float cotalpha = trackdirection.x() / trackdirection.z();
0638           float cotbeta = trackdirection.y() / trackdirection.z();
0639 
0640           auto detId = detIdObj.rawId();
0641 
0642           if (notInPCL_) {
0643             // fill the template from the store (from dqmBeginRun)
0644             SiPixelTemplate theTemplate(*thePixelTemp_);
0645 
0646             float locBx = (cotbeta < 0.) ? -1 : 1.;
0647             float locBz = (cotalpha < 0.) ? -locBx : locBx;
0648 
0649             int TemplID = templateDBobject_->getTemplateID(detId);
0650             theTemplate.interpolate(TemplID, cotalpha, cotbeta, locBz, locBx);
0651             qScaleF_ = theTemplate.qscale();
0652             rQmQtF_ = theTemplate.r_qMeas_qTrue();
0653           }
0654 
0655           // Surface deformation
0656           const auto& lp_pair = surface_deformation(topol, tsos, recHitPix);
0657 
0658           LocalPoint lp_track = lp_pair.first;
0659           LocalPoint lp_rechit = lp_pair.second;
0660 
0661           rechitCorrF_.x = lp_rechit.x();
0662           rechitCorrF_.y = lp_rechit.y();
0663           trackhitCorrXF_ = lp_track.x();
0664           trackhitCorrYF_ = lp_track.y();
0665           if (notInPCL_) {
0666             SiPixelLorentzAngleTreeForward_->Fill();
0667           }
0668 
0669           if (analysisType_ != eMinimumClusterSize)
0670             continue;
0671 
0672           int theMagField = magField->nominalValue();
0673           if (theMagField < 37 || theMagField > 39)
0674             continue;
0675 
0676           double chi2_ndof = chi2_ / ndof_;
0677           if (chi2_ndof >= normChi2Max_)
0678             continue;
0679 
0680           //--- large pixel cut
0681           bool large_pix = false;
0682           for (int j = 0; j < pixinfoF_.npix; j++) {
0683             int colpos = static_cast<int>(pixinfoF_.col[j]);
0684             if (pixinfoF_.row[j] == 0 || pixinfoF_.row[j] == 79 || pixinfoF_.row[j] == 80 || pixinfoF_.row[j] == 159 ||
0685                 colpos % 52 == 0 || colpos % 52 == 51) {
0686               large_pix = true;
0687             }
0688           }
0689 
0690           if (large_pix)
0691             continue;
0692 
0693           //--- residual cut
0694           double residual = sqrt(pow(trackhitCorrXF_ - rechitCorrF_.x, 2) + pow(trackhitCorrYF_ - rechitCorrF_.y, 2));
0695 
0696           if (residual > residualMax_)
0697             continue;
0698 
0699           int ringIdx = bladeF_ <= 22 ? 0 : 1;
0700           int panelIdx = panelF_ - 1;
0701           int sideIdx = sideF_ - 1;
0702           int idx = iHists.nSides_ * iHists.nPanels_ * ringIdx + iHists.nSides_ * panelIdx + sideIdx;
0703           int idxBeta = iHists.betaStartIdx_ + idx;
0704 
0705           double cotanAlpha = std::tan(M_PI / 2. - trackhitF_.alpha);
0706           double cotanBeta = std::tan(M_PI / 2. - trackhitF_.beta);
0707 
0708           LocalVector Bfield = theGeomDet->surface().toLocal(magField->inTesla(theGeomDet->surface().position()));
0709           iHists.h_fpixMagField_[0][idx]->Fill(Bfield.x());
0710           iHists.h_fpixMagField_[1][idx]->Fill(Bfield.y());
0711           iHists.h_fpixMagField_[2][idx]->Fill(Bfield.z());
0712 
0713           if (clustF_.size_y >= 2) {
0714             iHists.h_fpixAngleSize_[idx]->Fill(cotanAlpha, clustF_.size_x);
0715           }
0716 
0717           if (clust_.size_x >= 0) {
0718             iHists.h_fpixAngleSize_[idxBeta]->Fill(cotanBeta, clustF_.size_y);
0719           }
0720         }
0721       }  //end iteration over trajectory measurements
0722     }  //end iteration over trajectories
0723   }
0724 }
0725 
0726 void SiPixelLorentzAnglePCLWorker::dqmBeginRun(edm::Run const& run, edm::EventSetup const& iSetup) {
0727   // geometry
0728   const TrackerGeometry* geom = &iSetup.getData(geomEsToken_);
0729   const TrackerTopology* tTopo = &iSetup.getData(topoEsToken_);
0730 
0731   if (notInPCL_) {
0732     // Initialize 1D templates
0733     if (watchSiPixelTemplateRcd_.check(iSetup)) {
0734       templateDBobject_ = &iSetup.getData(siPixelTemplateEsToken_);
0735       thePixelTemp_ = &iSetup.getData(siPixelTemplateStoreEsToken_);
0736     }
0737   }
0738 
0739   PixelTopologyMap map = PixelTopologyMap(geom, tTopo);
0740   iHists.nlay = geom->numberOfLayers(PixelSubdetector::PixelBarrel);
0741   iHists.nModules_.resize(iHists.nlay);
0742   for (int i = 0; i < iHists.nlay; i++) {
0743     iHists.nModules_[i] = map.getPXBModules(i + 1);
0744   }
0745 
0746   // list of modules already filled, then return (we already entered here)
0747   if (!iHists.BPixnewDetIds_.empty() || !iHists.FPixnewDetIds_.empty())
0748     return;
0749 
0750   if (!newmodulelist_.empty()) {
0751     for (auto const& modulename : newmodulelist_) {
0752       if (modulename.find("BPix_") != std::string::npos) {
0753         PixelBarrelName bn(modulename, true);
0754         const auto& detId = bn.getDetId(tTopo);
0755         iHists.BPixnewmodulename_.push_back(modulename);
0756         iHists.BPixnewDetIds_.push_back(detId.rawId());
0757         iHists.BPixnewModule_.push_back(bn.moduleName());
0758         iHists.BPixnewLayer_.push_back(bn.layerName());
0759       } else if (modulename.find("FPix_") != std::string::npos) {
0760         PixelEndcapName en(modulename, true);
0761         const auto& detId = en.getDetId(tTopo);
0762         iHists.FPixnewmodulename_.push_back(modulename);
0763         iHists.FPixnewDetIds_.push_back(detId.rawId());
0764         iHists.FPixnewDisk_.push_back(en.diskName());
0765         iHists.FPixnewBlade_.push_back(en.bladeName());
0766       }
0767     }
0768   }
0769 }
0770 
0771 void SiPixelLorentzAnglePCLWorker::bookHistograms(DQMStore::IBooker& iBooker,
0772                                                   edm::Run const& run,
0773                                                   edm::EventSetup const& iSetup) {
0774   std::string name;
0775   std::string title;
0776   if (analysisType_ == eGrazingAngle) {
0777     // book the by partition monitoring
0778     const auto maxSect = iHists.nlay * iHists.nModules_[iHists.nlay - 1] + (int)iHists.BPixnewDetIds_.size();
0779 
0780     iBooker.setCurrentFolder(fmt::sprintf("%s/SectorMonitoring", folder_.data()));
0781     iHists.h_bySectOccupancy_ = iBooker.book1D(
0782         "h_bySectorOccupancy", "hit occupancy by sector;pixel sector;hits on track", maxSect, -0.5, maxSect - 0.5);
0783 
0784     iBooker.setCurrentFolder(folder_);
0785     static constexpr double min_depth_ = -100.;
0786     static constexpr double max_depth_ = 400.;
0787     static constexpr double min_drift_ = -500.;
0788     static constexpr double max_drift_ = 500.;
0789 
0790     // book the mean values projections and set the bin names of the by sector monitoring
0791     for (int i_layer = 1; i_layer <= iHists.nlay; i_layer++) {
0792       for (int i_module = 1; i_module <= iHists.nModules_[i_layer - 1]; i_module++) {
0793         unsigned int i_index = i_module + (i_layer - 1) * iHists.nModules_[i_layer - 1];
0794         std::string binName = fmt::sprintf("BPix Lay%i Mod%i", i_layer, i_module);
0795         LogDebug("SiPixelLorentzAnglePCLWorker") << " i_index: " << i_index << " bin name: " << binName
0796                                                  << " (i_layer: " << i_layer << " i_module:" << i_module << ")";
0797 
0798         iHists.h_bySectOccupancy_->setBinLabel(i_index, binName);
0799 
0800         name = fmt::sprintf("h_mean_layer%i_module%i", i_layer, i_module);
0801         title = fmt::sprintf(
0802             "average drift vs depth layer%i module%i; production depth [#mum]; #LTdrift#GT [#mum]", i_layer, i_module);
0803         iHists.h_mean_[i_index] = iBooker.book1D(name, title, hist_depth_, min_depth_, max_depth_);
0804       }
0805     }
0806     for (int i = 0; i < (int)iHists.BPixnewDetIds_.size(); i++) {
0807       name = fmt::sprintf("h_BPixnew_mean_%s", iHists.BPixnewmodulename_[i].c_str());
0808       title = fmt::sprintf("average drift vs depth %s; production depth [#mum]; #LTdrift#GT [#mum]",
0809                            iHists.BPixnewmodulename_[i].c_str());
0810       int new_index = iHists.nModules_[iHists.nlay - 1] + (iHists.nlay - 1) * iHists.nModules_[iHists.nlay - 1] + 1 + i;
0811       iHists.h_mean_[new_index] = iBooker.book1D(name, title, hist_depth_, min_depth_, max_depth_);
0812 
0813       LogDebug("SiPixelLorentzAnglePCLWorker")
0814           << "i_index" << new_index << " bin name: " << iHists.BPixnewmodulename_[i];
0815 
0816       iHists.h_bySectOccupancy_->setBinLabel(new_index, iHists.BPixnewmodulename_[i]);
0817     }
0818 
0819     //book the 2D histograms
0820     for (int i_layer = 1; i_layer <= iHists.nlay; i_layer++) {
0821       iBooker.setCurrentFolder(fmt::sprintf("%s/BPix/BPixLayer%i", folder_.data(), i_layer));
0822       for (int i_module = 1; i_module <= iHists.nModules_[i_layer - 1]; i_module++) {
0823         unsigned int i_index = i_module + (i_layer - 1) * iHists.nModules_[i_layer - 1];
0824 
0825         name = fmt::sprintf("h_drift_depth_adc_layer%i_module%i", i_layer, i_module);
0826         title = fmt::sprintf(
0827             "depth vs drift (ADC) layer%i module%i; drift [#mum]; production depth [#mum]", i_layer, i_module);
0828         iHists.h_drift_depth_adc_[i_index] =
0829             iBooker.book2D(name, title, hist_drift_, min_drift_, max_drift_, hist_depth_, min_depth_, max_depth_);
0830 
0831         name = fmt::sprintf("h_drift_depth_adc2_layer%i_module%i", i_layer, i_module);
0832         title = fmt::sprintf(
0833             "depth vs drift (ADC^{2}) layer%i module%i; drift [#mum]; production depth [#mum]", i_layer, i_module);
0834         iHists.h_drift_depth_adc2_[i_index] =
0835             iBooker.book2D(name, title, hist_drift_, min_drift_, max_drift_, hist_depth_, min_depth_, max_depth_);
0836 
0837         name = fmt::sprintf("h_drift_depth_noadc_layer%i_module%i", i_layer, i_module);
0838         title = fmt::sprintf(
0839             "depth vs drift (no ADC) layer%i module%i; drift [#mum]; production depth [#mum]", i_layer, i_module);
0840         iHists.h_drift_depth_noadc_[i_index] =
0841             iBooker.book2D(name, title, hist_drift_, min_drift_, max_drift_, hist_depth_, min_depth_, max_depth_);
0842 
0843         name = fmt::sprintf("h_drift_depth_layer%i_module%i", i_layer, i_module);
0844         title =
0845             fmt::sprintf("depth vs drift layer%i module%i; drift [#mum]; production depth [#mum]", i_layer, i_module);
0846         iHists.h_drift_depth_[i_index] =
0847             iBooker.book2D(name, title, hist_drift_, min_drift_, max_drift_, hist_depth_, min_depth_, max_depth_);
0848       }
0849     }
0850 
0851     // book the "new" modules
0852     iBooker.setCurrentFolder(fmt::sprintf("%s/BPix/NewModules", folder_.data()));
0853     for (int i = 0; i < (int)iHists.BPixnewDetIds_.size(); i++) {
0854       int new_index = iHists.nModules_[iHists.nlay - 1] + (iHists.nlay - 1) * iHists.nModules_[iHists.nlay - 1] + 1 + i;
0855 
0856       name = fmt::sprintf("h_BPixnew_drift_depth_adc_%s", iHists.BPixnewmodulename_[i].c_str());
0857       title = fmt::sprintf("depth vs drift (ADC) %s; drift [#mum]; production depth [#mum]",
0858                            iHists.BPixnewmodulename_[i].c_str());
0859       iHists.h_drift_depth_adc_[new_index] =
0860           iBooker.book2D(name, title, hist_drift_, min_drift_, max_drift_, hist_depth_, min_depth_, max_depth_);
0861 
0862       name = fmt::sprintf("h_BPixnew_drift_depth_adc2_%s", iHists.BPixnewmodulename_[i].c_str());
0863       title = fmt::sprintf("depth vs drift (ADC^{2}) %s; drift [#mum]; production depth [#mum]",
0864                            iHists.BPixnewmodulename_[i].c_str());
0865       iHists.h_drift_depth_adc2_[new_index] =
0866           iBooker.book2D(name, title, hist_drift_, min_drift_, max_drift_, hist_depth_, min_depth_, max_depth_);
0867 
0868       name = fmt::sprintf("h_BPixnew_drift_depth_noadc_%s", iHists.BPixnewmodulename_[i].c_str());
0869       title = fmt::sprintf("depth vs drift (no ADC)%s; drift [#mum]; production depth [#mum]",
0870                            iHists.BPixnewmodulename_[i].c_str());
0871       iHists.h_drift_depth_noadc_[new_index] =
0872           iBooker.book2D(name, title, hist_drift_, min_drift_, max_drift_, hist_depth_, min_depth_, max_depth_);
0873 
0874       name = fmt::sprintf("h_BPixnew_drift_depth_%s", iHists.BPixnewmodulename_[i].c_str());
0875       title = fmt::sprintf("depth vs drift %s; drift [#mum]; production depth [#mum]",
0876                            iHists.BPixnewmodulename_[i].c_str());
0877       iHists.h_drift_depth_[new_index] =
0878           iBooker.book2D(name, title, hist_drift_, min_drift_, max_drift_, hist_depth_, min_depth_, max_depth_);
0879     }
0880   }  // end if GrazinAngleAnalysis
0881   else {
0882     iBooker.setCurrentFolder(folder_);
0883     std::string baseName;
0884     std::string baseTitle;
0885 
0886     for (int r = 0; r < iHists.nRings_; ++r) {
0887       for (int p = 0; p < iHists.nPanels_; ++p) {
0888         for (int s = 0; s < iHists.nSides_; ++s) {
0889           baseName = fmt::sprintf("R%d_P%d_z%d", r + 1, p + 1, s + 1);
0890           if (s == 0)
0891             baseTitle = fmt::sprintf("Ring%d_Panel%d_z-", r + 1, p + 1);
0892           else
0893             baseTitle = fmt::sprintf("Ring%d_Panel%d_z+", r + 1, p + 1);
0894 
0895           int idx = iHists.nSides_ * iHists.nPanels_ * r + iHists.nSides_ * p + s;
0896           int idxBeta = iHists.betaStartIdx_ + idx;
0897 
0898           name = fmt::sprintf("%s_alphaMean", baseName);
0899           title = fmt::sprintf("%s_alphaMean;cot(#alpha); Average cluster size x (pixel)", baseTitle);
0900           iHists.h_fpixMean_[idx] = iBooker.book1D(name, title, 60, -3., 3.);
0901           name = fmt::sprintf("%s_betaMean", baseName);
0902           title = fmt::sprintf("%s_betaMean;cot(#beta); Average cluster size y (pixel)", baseTitle);
0903           iHists.h_fpixMean_[idxBeta] = iBooker.book1D(name, title, 60, -3., 3.);
0904 
0905         }  // loop over sides
0906       }  // loop over panels
0907     }  // loop over rings
0908     iBooker.setCurrentFolder(fmt::sprintf("%s/FPix", folder_.data()));
0909     for (int r = 0; r < iHists.nRings_; ++r) {
0910       for (int p = 0; p < iHists.nPanels_; ++p) {
0911         for (int s = 0; s < iHists.nSides_; ++s) {
0912           baseName = fmt::sprintf("R%d_P%d_z%d", r + 1, p + 1, s + 1);
0913           if (s == 0)
0914             baseTitle = fmt::sprintf("Ring%d_Panel%d_z-", r + 1, p + 1);
0915           else
0916             baseTitle = fmt::sprintf("Ring%d_Panel%d_z+", r + 1, p + 1);
0917 
0918           int idx = iHists.nSides_ * iHists.nPanels_ * r + iHists.nSides_ * p + s;
0919           int idxBeta = iHists.betaStartIdx_ + idx;
0920 
0921           name = fmt::sprintf("%s_alpha", baseName);
0922           title = fmt::sprintf("%s_alpha;cot(#alpha); Cluster size x (pixel)", baseTitle);
0923           iHists.h_fpixAngleSize_[idx] = iBooker.book2D(name, title, 60, -3., 3., 10, 0.5, 10.5);
0924           name = fmt::sprintf("%s_beta", baseName);
0925           title = fmt::sprintf("%s_beta;cot(#beta); Cluster size y (pixel) ", baseTitle);
0926           iHists.h_fpixAngleSize_[idxBeta] = iBooker.book2D(name, title, 60, -3., 3., 10, 0.5, 10.5);
0927           for (int m = 0; m < 3; ++m) {
0928             name = fmt::sprintf("%s_B%d", baseName, m);
0929             char bComp = m == 0 ? 'x' : (m == 1 ? 'y' : 'z');
0930             title = fmt::sprintf("%s_magField%d;B_{%c} [T];Entries", baseTitle, m, bComp);
0931             iHists.h_fpixMagField_[m][idx] = iBooker.book1D(name, title, 10000, -5., 5.);
0932           }  // mag. field comps
0933         }  // loop over sides
0934       }  // loop over panels
0935     }  // loop over rings
0936   }  // if MinimalClusterSize
0937 
0938   // book the track monitoring plots
0939   iBooker.setCurrentFolder(fmt::sprintf("%s/TrackMonitoring", folder_.data()));
0940   iHists.h_tracks_ = iBooker.book1D("h_tracks", ";tracker volume;tracks", 2, -0.5, 1.5);
0941   iHists.h_tracks_->setBinLabel(1, "all tracks", 1);
0942   iHists.h_tracks_->setBinLabel(2, "has pixel hits", 1);
0943   iHists.h_trackEta_ = iBooker.book1D("h_trackEta", ";track #eta; #tracks", 30, -3., 3.);
0944   iHists.h_trackPhi_ = iBooker.book1D("h_trackPhi", ";track #phi; #tracks", 48, -M_PI, M_PI);
0945   iHists.h_trackPt_ = iBooker.book1D("h_trackPt", ";track p_{T} [GeV]; #tracks", 100, 0., 100.);
0946   iHists.h_trackChi2_ = iBooker.book1D("h_trackChi2ndof", ";track #chi^{2}/ndof; #tracks", 100, 0., 10.);
0947 }
0948 
0949 void SiPixelLorentzAnglePCLWorker::dqmEndRun(edm::Run const& run, edm::EventSetup const& iSetup) {
0950   if (notInPCL_) {
0951     hFile_->cd();
0952     hFile_->Write();
0953     hFile_->Close();
0954   }
0955 }
0956 
0957 // method used to fill per pixel info
0958 const Pixinfo SiPixelLorentzAnglePCLWorker::fillPix(const SiPixelCluster& LocPix, const PixelTopology* topol) const {
0959   Pixinfo pixinfo;
0960   const std::vector<SiPixelCluster::Pixel>& pixvector = LocPix.pixels();
0961   pixinfo.npix = 0;
0962   for (std::vector<SiPixelCluster::Pixel>::const_iterator itPix = pixvector.begin(); itPix != pixvector.end();
0963        itPix++) {
0964     pixinfo.row[pixinfo.npix] = itPix->x;
0965     pixinfo.col[pixinfo.npix] = itPix->y;
0966     pixinfo.adc[pixinfo.npix] = itPix->adc;
0967     LocalPoint lp = topol->localPosition(MeasurementPoint(itPix->x + 0.5, itPix->y + 0.5));
0968     pixinfo.x[pixinfo.npix] = lp.x();
0969     pixinfo.y[pixinfo.npix] = lp.y();
0970     pixinfo.npix++;
0971   }
0972   return pixinfo;
0973 }
0974 
0975 // method used to correct for the surface deformation
0976 const std::pair<LocalPoint, LocalPoint> SiPixelLorentzAnglePCLWorker::surface_deformation(
0977     const PixelTopology* topol, TrajectoryStateOnSurface& tsos, const SiPixelRecHit* recHitPix) const {
0978   LocalPoint trackposition = tsos.localPosition();
0979   const LocalTrajectoryParameters& ltp = tsos.localParameters();
0980   const Topology::LocalTrackAngles localTrackAngles(ltp.dxdz(), ltp.dydz());
0981 
0982   std::pair<float, float> pixels_track = topol->pixel(trackposition, localTrackAngles);
0983   std::pair<float, float> pixels_rechit = topol->pixel(recHitPix->localPosition(), localTrackAngles);
0984 
0985   LocalPoint lp_track = topol->localPosition(MeasurementPoint(pixels_track.first, pixels_track.second));
0986 
0987   LocalPoint lp_rechit = topol->localPosition(MeasurementPoint(pixels_rechit.first, pixels_rechit.second));
0988 
0989   std::pair<LocalPoint, LocalPoint> lps = std::make_pair(lp_track, lp_rechit);
0990   return lps;
0991 }
0992 
0993 LorentzAngleAnalysisTypeEnum SiPixelLorentzAnglePCLWorker::convertStringToLorentzAngleAnalysisTypeEnum(
0994     std::string type) {
0995   return (type == "GrazingAngle") ? eGrazingAngle : eMinimumClusterSize;
0996 }
0997 
0998 // ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
0999 void SiPixelLorentzAnglePCLWorker::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
1000   edm::ParameterSetDescription desc;
1001   desc.setComment("Worker module of the SiPixel Lorentz Angle PCL monitoring workflow");
1002   desc.add<std::string>("analysisType", "GrazingAngle")
1003       ->setComment("analysis type - GrazingAngle (default) or MinimumClusterSize");
1004   desc.add<std::string>("folder", "AlCaReco/SiPixelLorentzAngle")->setComment("directory of PCL Worker output");
1005   desc.add<bool>("notInPCL", false)->setComment("create TTree (true) or not (false)");
1006   desc.add<std::string>("fileName", "testrun.root")->setComment("name of the TTree file if notInPCL = true");
1007   desc.add<std::vector<std::string>>("newmodulelist", {})->setComment("the list of DetIds for new sensors");
1008   desc.add<edm::InputTag>("src", edm::InputTag("TrackRefitter"))->setComment("input track collections");
1009   desc.add<double>("ptMin", 3.)->setComment("minimum pt on tracks");
1010   desc.add<double>("normChi2Max", 2.)->setComment("maximum reduced chi squared");
1011   desc.add<std::vector<int>>("clustSizeYMin", {4, 3, 3, 2})
1012       ->setComment("minimum cluster size on Y axis for all Barrel Layers");
1013   desc.add<int>("clustSizeXMax", 5)->setComment("maximum cluster size on X axis");
1014   desc.add<double>("residualMax", 0.005)->setComment("maximum residual");
1015   desc.add<double>("clustChargeMaxPerLength", 50000)
1016       ->setComment("maximum cluster charge per unit length of pixel depth (z)");
1017   desc.add<int>("binsDepth", 50)->setComment("# bins for electron production depth axis");
1018   desc.add<int>("binsDrift", 100)->setComment("# bins for electron drift axis");
1019   descriptions.addWithDefaultLabel(desc);
1020 }
1021 
1022 // define this as a plug-in
1023 DEFINE_FWK_MODULE(SiPixelLorentzAnglePCLWorker);