diff --git a/DQM/Integration/python/clients/pixel_up_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/pixel_up_dqm_sourceclient-live_cfg.py index a2e13414ae491..8b0e0c8d26927 100644 --- a/DQM/Integration/python/clients/pixel_up_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/pixel_up_dqm_sourceclient-live_cfg.py @@ -313,7 +313,7 @@ process.SiPixelPhase1RawDataNErrors.enabled = True process.SiPixelPhase1RawDataNErrors.specs = VPSet( Specification().groupBy("PXForward/PXBlade").groupBy("PXForward", "EXTEND_X").save(), - Specification().groupBy("FEDChannel").groupBy("", "EXTEND_X").save() + Specification().groupBy("LinkInFed").groupBy("", "EXTEND_X").save() ) process.SiPixelPhase1RawDataTypeNErrors.enabled = True diff --git a/DQM/Integration/python/config/fileinputsource_cfi.py b/DQM/Integration/python/config/fileinputsource_cfi.py index 336dfeb710697..a0bff986585ac 100644 --- a/DQM/Integration/python/config/fileinputsource_cfi.py +++ b/DQM/Integration/python/config/fileinputsource_cfi.py @@ -69,7 +69,7 @@ readFiles = cms.untracked.vstring() secFiles = cms.untracked.vstring() # this outputs all results, which can be a lot... - read, sec = filesFromDASQuery("file dataset=%s" % dataset, option=" --limit 10000 ") + read, sec = filesFromDASQuery("file run=%d dataset=%s" % (options.runNumber, dataset), option=" --limit 10000 ") readFiles.extend(read) secFiles.extend(sec) diff --git a/DQM/SiPixelPhase1Clusters/interface/SiPixelPhase1Clusters.h b/DQM/SiPixelPhase1Clusters/interface/SiPixelPhase1Clusters.h index 2948a7c9a36f9..49df1fc390f31 100644 --- a/DQM/SiPixelPhase1Clusters/interface/SiPixelPhase1Clusters.h +++ b/DQM/SiPixelPhase1Clusters/interface/SiPixelPhase1Clusters.h @@ -15,13 +15,18 @@ class SiPixelPhase1Clusters : public SiPixelPhase1Base { enum { CHARGE, SIZE, + SIZEX, + SIZEY, NCLUSTERS, + NCLUSTERSINCLUSIVE, EVENTRATE, POSITION_B, POSITION_F, POSITION_XZ, POSITION_YZ, - SIZE_VS_ETA + SIZE_VS_ETA, + READOUT_CHARGE, + READOUT_NCLUSTERS }; public: diff --git a/DQM/SiPixelPhase1Clusters/python/SiPixelPhase1Clusters_cfi.py b/DQM/SiPixelPhase1Clusters/python/SiPixelPhase1Clusters_cfi.py index 0185af4d82365..a87174868ba48 100644 --- a/DQM/SiPixelPhase1Clusters/python/SiPixelPhase1Clusters_cfi.py +++ b/DQM/SiPixelPhase1Clusters/python/SiPixelPhase1Clusters_cfi.py @@ -8,9 +8,11 @@ xlabel = "Charge (electrons)", specs = VPSet( - StandardSpecification2DProfile, + #StandardSpecification2DProfile, + StandardSpecificationPixelmapProfile, StandardSpecificationTrend, - StandardSpecifications1D + StandardSpecifications1D, + StandardSpecificationTrend2D ) ) @@ -20,12 +22,43 @@ range_min = 0, range_max = 30, range_nbins = 30, xlabel = "size[pixels]", specs = VPSet( - StandardSpecification2DProfile, + #StandardSpecification2DProfile, + StandardSpecificationPixelmapProfile, StandardSpecificationTrend, - StandardSpecifications1D + StandardSpecifications1D, + StandardSpecificationTrend2D ) ) +SiPixelPhase1ClustersSizeX = DefaultHistoDigiCluster.clone( + name = "sizeX", + title = "Cluster Size in X", + range_min = 0, range_max = 30, range_nbins = 30, + xlabel = "size[pixels]", + specs = VPSet( + #StandardSpecification2DProfile, + #StandardSpecificationPixelmapProfile, + #StandardSpecificationTrend, + StandardSpecifications1D, + #StandardSpecificationTrend2D + ) +) + +SiPixelPhase1ClustersSizeY = DefaultHistoDigiCluster.clone( + name = "sizeY", + title = "Cluster Size in Y", + range_min = 0, range_max = 30, range_nbins = 30, + xlabel = "size[pixels]", + specs = VPSet( + #StandardSpecification2DProfile, + #StandardSpecificationPixelmapProfile, + #StandardSpecificationTrend, + StandardSpecifications1D, + #StandardSpecificationTrend2D + ) +) + + SiPixelPhase1ClustersNClusters = DefaultHistoDigiCluster.clone( name = "clusters", title = "Clusters", @@ -33,24 +66,41 @@ xlabel = "clusters", dimensions = 0, specs = VPSet( + StandardSpecificationOccupancy, StandardSpecification2DProfile_Num, StandardSpecificationTrend_Num, - StandardSpecifications1D_Num + StandardSpecifications1D_Num, ) ) + +SiPixelPhase1ClustersNClustersInclusive = DefaultHistoDigiCluster.clone( + name = "clusters", + title = "Clusters", + range_min = 0, range_max = 2000, range_nbins = 200, + xlabel = "clusters", + dimensions = 0, + specs = VPSet( + StandardSpecificationInclusive_Num + ) +) + + SiPixelPhase1ClustersEventrate = DefaultHistoDigiCluster.clone( - name = "bigfpixclustereventrate", - title = "Number of Events with > 180 FPIX clusters", - xlabel = "Lumisection", + name = "clustereventrate", + title = "Number of Events with clusters", ylabel = "#Events", dimensions = 0, specs = VPSet( Specification().groupBy("Lumisection") + .groupBy("", "EXTEND_X").save(), + Specification().groupBy("BX") .groupBy("", "EXTEND_X").save() - ) + ) + ) + SiPixelPhase1ClustersPositionB = DefaultHistoDigiCluster.clone( name = "clusterposition_zphi", title = "Cluster Positions", @@ -115,16 +165,58 @@ ) ) +SiPixelPhase1ClustersReadoutCharge = DefaultHistoReadout.clone( + name = "charge", + title = "Cluster Charge", + range_min = 0, range_max = 200e3, range_nbins = 200, + xlabel = "Charge (electrons)", + specs = VPSet( + Specification(PerReadout).groupBy("PXBarrel/Shell/Sector").save(), + Specification(PerReadout).groupBy("PXForward/HalfCylinder").save(), + + Specification(PerReadout).groupBy("PXBarrel/Shell/Sector/OnlineBlock") + .groupBy("PXBarrel/Shell/Sector", "EXTEND_Y").save(), + Specification(PerReadout).groupBy("PXForward/HalfCylinder/OnlineBlock") + .groupBy("PXForward/HalfCylinder", "EXTEND_Y").save(), + ) +) + +SiPixelPhase1ClustersReadoutNClusters = DefaultHistoReadout.clone( + name = "clusters", + title = "Clusters", + range_min = 0, range_max = 10, range_nbins = 10, + xlabel = "clusters", + dimensions = 0, + specs = VPSet( + Specification(PerReadout).groupBy("PXBarrel/Shell/Sector/DetId/Event").reduce("COUNT") + .groupBy("PXBarrel/Shell/Sector").save(), + Specification(PerReadout).groupBy("PXForward/HalfCylinder/DetId/Event").reduce("COUNT") + .groupBy("PXForward/HalfCylinder").save(), + + Specification(PerReadout).groupBy("PXBarrel/Shell/Sector/DetId/Event").reduce("COUNT") + .groupBy("PXBarrel/Shell/Sector/Lumisection").reduce("MEAN") + .groupBy("PXBarrel/Shell/Sector", "EXTEND_X").save(), + Specification(PerReadout).groupBy("PXForward/HalfCylinder/DetId/Event").reduce("COUNT") + .groupBy("PXForward/HalfCylinder/Lumisection").reduce("MEAN") + .groupBy("PXForward/HalfCylinder", "EXTEND_X").save(), + ) +) + SiPixelPhase1ClustersConf = cms.VPSet( SiPixelPhase1ClustersCharge, SiPixelPhase1ClustersSize, + SiPixelPhase1ClustersSizeX, + SiPixelPhase1ClustersSizeY, SiPixelPhase1ClustersNClusters, + SiPixelPhase1ClustersNClustersInclusive, SiPixelPhase1ClustersEventrate, SiPixelPhase1ClustersPositionB, SiPixelPhase1ClustersPositionF, SiPixelPhase1ClustersPositionXZ, SiPixelPhase1ClustersPositionYZ, - SiPixelPhase1ClustersSizeVsEta + SiPixelPhase1ClustersSizeVsEta, + SiPixelPhase1ClustersReadoutCharge, + SiPixelPhase1ClustersReadoutNClusters ) diff --git a/DQM/SiPixelPhase1Clusters/src/SiPixelPhase1Clusters.cc b/DQM/SiPixelPhase1Clusters/src/SiPixelPhase1Clusters.cc index 44333ee830289..ea9b5e9da8200 100644 --- a/DQM/SiPixelPhase1Clusters/src/SiPixelPhase1Clusters.cc +++ b/DQM/SiPixelPhase1Clusters/src/SiPixelPhase1Clusters.cc @@ -29,13 +29,12 @@ void SiPixelPhase1Clusters::analyze(const edm::Event& iEvent, const edm::EventSe iEvent.getByToken(srcToken_, input); if (!input.isValid()) return; + bool hasClusters=false; + edm::ESHandle tracker; iSetup.get().get(tracker); assert(tracker.isValid()); - auto forward = geometryInterface.intern("PXForward"); - auto nforward = 0; - edmNew::DetSetVector::const_iterator it; for (it = input->begin(); it != input->end(); ++it) { auto id = DetId(it->detId()); @@ -44,10 +43,18 @@ void SiPixelPhase1Clusters::analyze(const edm::Event& iEvent, const edm::EventSe const PixelTopology& topol = theGeomDet->specificTopology(); for(SiPixelCluster const& cluster : *it) { - histo[CHARGE].fill(double(cluster.charge()), id, &iEvent); - histo[SIZE ].fill(double(cluster.size() ), id, &iEvent); - if (cluster.size() > 1) - histo[NCLUSTERS].fill(id, &iEvent); + int row = cluster.x()-0.5, col = cluster.y()-0.5; + histo[READOUT_CHARGE].fill(double(cluster.charge()), id, &iEvent, col, row); + histo[CHARGE].fill(double(cluster.charge()), id, &iEvent, col, row); + histo[SIZE ].fill(double(cluster.size() ), id, &iEvent, col, row); + histo[SIZEX ].fill(double(cluster.sizeX() ), id, &iEvent, col, row); + histo[SIZEY ].fill(double(cluster.sizeY() ), id, &iEvent, col, row); + histo[NCLUSTERS].fill(id, &iEvent, col, row); + histo[NCLUSTERSINCLUSIVE].fill(id, &iEvent); + hasClusters=true; + if (cluster.size()>1){ + histo[READOUT_NCLUSTERS].fill(id, &iEvent); + } LocalPoint clustlp = topol.localPosition(MeasurementPoint(cluster.x(), cluster.y())); GlobalPoint clustgp = theGeomDet->surface().toGlobal(clustlp); @@ -57,14 +64,16 @@ void SiPixelPhase1Clusters::analyze(const edm::Event& iEvent, const edm::EventSe histo[POSITION_YZ].fill(clustgp.y(), clustgp.z(), id, &iEvent); histo[SIZE_VS_ETA].fill(clustgp.eta(), cluster.sizeY(), id, &iEvent); - if (geometryInterface.extract(forward, id) != GeometryInterface::UNDEFINED) - nforward++; } } - if (nforward > 180) - histo[EVENTRATE].fill(DetId(0), &iEvent); + + if (hasClusters) histo[EVENTRATE].fill(DetId(0), &iEvent); + histo[NCLUSTERS].executePerEventHarvesting(&iEvent); + histo[READOUT_NCLUSTERS].executePerEventHarvesting(&iEvent); + histo[NCLUSTERSINCLUSIVE].executePerEventHarvesting(&iEvent); + } DEFINE_FWK_MODULE(SiPixelPhase1Clusters); diff --git a/DQM/SiPixelPhase1Common/README.md b/DQM/SiPixelPhase1Common/README.md index f520f6e815dfa..36376a451afee 100644 --- a/DQM/SiPixelPhase1Common/README.md +++ b/DQM/SiPixelPhase1Common/README.md @@ -81,8 +81,6 @@ The framework provides a few simple commands to describe histograms using this m - The `reduce` command reduces the right-hand side histograms into histograms of a lower dimensionality. Typically, e.g. for the mean, this is a 0D-histogram, which means a single bin with the respective value. The quantity to extract is specified by the parameter. - The `save`command tells the framework that we are happy with the histograms that are now in the table and that they should be saved to the output file. Proper names are inferred from the column names and steps specified before. -The framework also allows a `custom` command that passes the current table state to custom code, to compute things that the framework does not allow itself. However, this should be used carefully, since such code has to be heavily dependent on internal data structures. - Since the framework can see where quantities go during the computation of derived histograms, it can also automatically keep track of the axis labels and ranges and set them to useful, consistent values automatically. For technical reasons the framework is not able to execute every conceivable specification, but it is able to handle all relevant cases in an efficient way. Since the specification is very abstract, it gives the framework a lot of freedom to implement it in the most efficient way possible. @@ -224,7 +222,7 @@ This is an unspectacular wrapper around histogram-like things. It is used as the This is the base class that all plugins should derive from. It instantiates `HistogramManager`s from config, sets up a `GeometryInterface`, and calls the `book` method of the `HistogramManager`s. If you need anything special, you can also do this yourself ad ignore the base class. -The same file declares the `SiPixelPhase1Harvester`, which is very similar to the base class but is an `DQMEDHarvester` and calls the harvesting methods. Usually this does not need to be modified, it is enough instantiate a copy and set the configuration to be the same as for the analyzer. If you want too use a `custom` step, derive from this class and call the `setCustomHandler` on the HistogramManager before the actual harvesting starts. +The same file declares the `SiPixelPhase1Harvester`, which is very similar to the base class but is an `DQMEDHarvester` and calls the harvesting methods. Usually this does not need to be modified, it is enough instantiate a copy and set the configuration to be the same as for the analyzer. ### SummationSpecification @@ -295,7 +293,3 @@ The fill function asks the `GeometryInterface` for the column values for the mod For the harvesting, first the internal table structure has to be repopulated (remember, we are in a completely new process now). To do this, `loadFromDQMStore` mirrors the booking process (massively stripped down and not actually sharing code) and `get`s the MEs from the `DQMStore`. So, in sum there are 3 places where step1 commands are interpreted: in booking, in filling, and in loading. Make sure to keep them in sync when anything changes. Afterwards, a classical interpreter loop runs over the step2 commands and calls methods to actually execute them, by updating the table structure. This is mostly straight-forward code. Booking happens as the execution progresses, and all metadata is tracked in the `TH1` fields (labels, range). - -In the `custom` command, a custom handler function (that has to be set beforehand) is called. This is again a lambda (using inheritance would be possible as well, but it tends to be a mess in C++), which gets passed the internal table state. It is explicitly allowed to just save a copy of that state for later use, which may be necessary to compute quantities that depend on multiple other quantities (e.g. efficiencies). Later, a `custom` step on a different HistogramManager (possibly one that did not record any data in step1) can take the saved tables, create derived quantities and put them into the histograms in its own table, which the HistogramManager already booked with consistent names (also doing further summation, if specified). - -Alternativey, the `custom` handler gets passed the `IBooker` and `IGetter` objects from the `DQMStore`, so things which cannot be booked using the framework can be handled manually. But then you also need to handle folder- and object names your self; best is to use the path names of the MEs you find in the table and derive new ME names from the existing ME names. diff --git a/DQM/SiPixelPhase1Common/interface/GeometryInterface.h b/DQM/SiPixelPhase1Common/interface/GeometryInterface.h index b192eecdbbc93..e231c94eb8d10 100644 --- a/DQM/SiPixelPhase1Common/interface/GeometryInterface.h +++ b/DQM/SiPixelPhase1Common/interface/GeometryInterface.h @@ -131,6 +131,8 @@ class GeometryInterface { // edm::ParameterSet& iConfig); void loadFromTopology(edm::EventSetup const& iSetup, const edm::ParameterSet& iConfig); + void loadFromSiPixelCoordinates(edm::EventSetup const& iSetup, + const edm::ParameterSet& iConfig); void loadTimebased(edm::EventSetup const& iSetup, const edm::ParameterSet& iConfig); void loadModuleLevel(edm::EventSetup const& iSetup, diff --git a/DQM/SiPixelPhase1Common/interface/HistogramManager.h b/DQM/SiPixelPhase1Common/interface/HistogramManager.h index efa9b190be14a..6b11abf2a749e 100644 --- a/DQM/SiPixelPhase1Common/interface/HistogramManager.h +++ b/DQM/SiPixelPhase1Common/interface/HistogramManager.h @@ -52,17 +52,10 @@ class HistogramManager { void executeHarvesting(DQMStore::IBooker& iBooker, DQMStore::IGetter& iGetter); typedef std::map Table; - // Set a handler to be called when a custom() step is hit. This can do - // arbitrary things to the histogram Table, including copying it for later - // use. Using such saved tables form other HistogramManagers, e.g. - // efficiencies can be computed here. - template - void setCustomHandler(FUNC handler) {customHandler = handler; }; private: const edm::ParameterSet& iConfig; GeometryInterface& geometryInterface; - std::function customHandler; std::vector specs; std::vector tables; diff --git a/DQM/SiPixelPhase1Common/interface/SiPixelCoordinates.h b/DQM/SiPixelPhase1Common/interface/SiPixelCoordinates.h new file mode 100644 index 0000000000000..58506388563a1 --- /dev/null +++ b/DQM/SiPixelPhase1Common/interface/SiPixelCoordinates.h @@ -0,0 +1,208 @@ +#ifndef SiPixelCoordinates_h +#define SiPixelCoordinates_h +// -*- C++ -*- +// +// Class: SiPixelCoordinates +// +// This class provides floating point numbers for +// digis, clusters and hits that can be used to +// easily plot various geometry related histograms +// +// Online and Offline conventions are kept for the variables +// An additional ]0, +1[ or ]-0.5, +0.5[ is added depending on +// the location of digi/cluster/hit on the module, so +// the variables provided are roughly monotonic vs. global +// coordinates (except that overlaps are removed), eg: +// global z: module, disk, disk_ring (large division) +// global r-phi: ladder, blade, blade_panel +// global r: ring, disk_ring (small division) +// +// Original Author: Janos Karancsi + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" +#include "DataFormats/DetId/interface/DetId.h" +#include "DataFormats/TrackerCommon/interface/TrackerTopology.h" +#include "DataFormats/SiPixelDigi/interface/PixelDigi.h" +#include "DataFormats/SiPixelCluster/interface/SiPixelCluster.h" +#include "DataFormats/TrackerRecHit2D/interface/SiPixelRecHit.h" +#include "TrackingTools/TransientTrackingRecHit/interface/TransientTrackingRecHit.h" + +#include "CondFormats/SiPixelObjects/interface/SiPixelFedCablingMap.h" + + +class SiPixelCoordinates { + + public: + + SiPixelCoordinates(); + SiPixelCoordinates(int); + virtual ~SiPixelCoordinates(); + + void init(edm::EventSetup const&); + + // Integers + int quadrant(const DetId&); + int side(const DetId&); + int module(const DetId&); + // barrel specific + int layer(const DetId&); + int sector(const DetId&); + int ladder(const DetId&); + int signed_ladder(const DetId&); + int signed_module(const DetId&); + int half(const DetId&); + int outer(const DetId&); + int flipped(const DetId&); + // endcap specific + int disk(const DetId&); + int signed_disk(const DetId&); + int panel(const DetId&); + int ring(const DetId&); + int blade(const DetId&); + int signed_blade(const DetId&); + + unsigned int fedid(const DetId&); + + int channel(const DetId&, const std::pair&); + int channel(const DetId&, const PixelDigi*); + int channel(const DetId&, const SiPixelCluster*); + int channel(const SiPixelRecHit*); + int channel(const TrackingRecHit*); + + int roc(const DetId&, const std::pair&); + int roc(const DetId&, const PixelDigi*); + int roc(const DetId&, const SiPixelCluster*); + int roc(const SiPixelRecHit*); + int roc(const TrackingRecHit*); + + // Floats (coordinates) + float module_coord(const DetId&, const std::pair&); + float module_coord(const DetId&, const PixelDigi*); + float module_coord(const DetId&, const SiPixelCluster*); + float module_coord(const SiPixelRecHit*); + float module_coord(const TrackingRecHit*); + + float signed_module_coord(const DetId&, const std::pair&); + float signed_module_coord(const DetId&, const PixelDigi*); + float signed_module_coord(const DetId&, const SiPixelCluster*); + float signed_module_coord(const SiPixelRecHit*); + float signed_module_coord(const TrackingRecHit*); + + float ladder_coord(const DetId&, const std::pair&); + float ladder_coord(const DetId&, const PixelDigi*); + float ladder_coord(const DetId&, const SiPixelCluster*); + float ladder_coord(const SiPixelRecHit*); + float ladder_coord(const TrackingRecHit*); + + float signed_ladder_coord(const DetId&, const std::pair&); + float signed_ladder_coord(const DetId&, const PixelDigi*); + float signed_ladder_coord(const DetId&, const SiPixelCluster*); + float signed_ladder_coord(const SiPixelRecHit*); + float signed_ladder_coord(const TrackingRecHit*); + + float ring_coord(const DetId&, const std::pair&); + float ring_coord(const DetId&, const PixelDigi*); + float ring_coord(const DetId&, const SiPixelCluster*); + float ring_coord(const SiPixelRecHit*); + float ring_coord(const TrackingRecHit*); + + float disk_coord(const DetId&, const std::pair&); + float disk_coord(const DetId&, const PixelDigi*); + float disk_coord(const DetId&, const SiPixelCluster*); + float disk_coord(const SiPixelRecHit*); + float disk_coord(const TrackingRecHit*); + + float signed_disk_coord(const DetId&, const std::pair&); + float signed_disk_coord(const DetId&, const PixelDigi*); + float signed_disk_coord(const DetId&, const SiPixelCluster*); + float signed_disk_coord(const SiPixelRecHit*); + float signed_disk_coord(const TrackingRecHit*); + + float disk_ring_coord(const DetId&, const std::pair&); + float disk_ring_coord(const DetId&, const PixelDigi*); + float disk_ring_coord(const DetId&, const SiPixelCluster*); + float disk_ring_coord(const SiPixelRecHit*); + float disk_ring_coord(const TrackingRecHit*); + + float signed_disk_ring_coord(const DetId&, const std::pair&); + float signed_disk_ring_coord(const DetId&, const PixelDigi*); + float signed_disk_ring_coord(const DetId&, const SiPixelCluster*); + float signed_disk_ring_coord(const SiPixelRecHit*); + float signed_disk_ring_coord(const TrackingRecHit*); + + float blade_coord(const DetId&, const std::pair&); + float blade_coord(const DetId&, const PixelDigi*); + float blade_coord(const DetId&, const SiPixelCluster*); + float blade_coord(const SiPixelRecHit*); + float blade_coord(const TrackingRecHit*); + + float signed_blade_coord(const DetId&, const std::pair&); + float signed_blade_coord(const DetId&, const PixelDigi*); + float signed_blade_coord(const DetId&, const SiPixelCluster*); + float signed_blade_coord(const SiPixelRecHit*); + float signed_blade_coord(const TrackingRecHit*); + + float blade_panel_coord(const DetId&, const std::pair&); + float blade_panel_coord(const DetId&, const PixelDigi*); + float blade_panel_coord(const DetId&, const SiPixelCluster*); + float blade_panel_coord(const SiPixelRecHit*); + float blade_panel_coord(const TrackingRecHit*); + + float signed_blade_panel_coord(const DetId&, const std::pair&); + float signed_blade_panel_coord(const DetId&, const PixelDigi*); + float signed_blade_panel_coord(const DetId&, const SiPixelCluster*); + float signed_blade_panel_coord(const SiPixelRecHit*); + float signed_blade_panel_coord(const TrackingRecHit*); + + float signed_shifted_blade_panel_coord(const DetId&, const std::pair&); + float signed_shifted_blade_panel_coord(const DetId&, const PixelDigi*); + float signed_shifted_blade_panel_coord(const DetId&, const SiPixelCluster*); + float signed_shifted_blade_panel_coord(const SiPixelRecHit*); + float signed_shifted_blade_panel_coord(const TrackingRecHit*); + + private: + int phase_; + + const TrackerTopology* tTopo_; + const TrackerGeometry* tGeom_; + const SiPixelFedCablingMap* cablingMap_; + + // Internal containers for optimal speed + // - only calculate things once per DetId + std::map quadrant_; + std::map side_; + std::map module_; + std::map layer_; + std::map sector_; + std::map ladder_; + std::map signed_ladder_; + std::map signed_module_; + std::map half_; + std::map outer_; + std::map flipped_; + std::map disk_; + std::map signed_disk_; + std::map panel_; + std::map ring_; + std::map blade_; + std::map signed_blade_; + + std::map fedid_; + std::map channel_; + std::map roc_; + + // Internal methods used for pixel coordinates + bool isPixel_(const DetId&); + bool isBPix_(const DetId&); + bool isFPix_(const DetId&); + std::pair pixel_(const PixelDigi*); + std::pair pixel_(const SiPixelCluster*); + std::pair pixel_(const SiPixelRecHit*); + float xcoord_on_module_(const DetId&, const std::pair&); + float ycoord_on_module_(const DetId&, const std::pair&); + +}; + +#endif diff --git a/DQM/SiPixelPhase1Common/interface/SummationSpecification.h b/DQM/SiPixelPhase1Common/interface/SummationSpecification.h index ce5b9416684f2..4f66dc5b2e204 100644 --- a/DQM/SiPixelPhase1Common/interface/SummationSpecification.h +++ b/DQM/SiPixelPhase1Common/interface/SummationSpecification.h @@ -29,7 +29,6 @@ struct SummationStep { COUNT = 4, REDUCE = 5, SAVE = 6, - CUSTOM = 7, USE_X = 8, USE_Y = 9, USE_Z = 10, diff --git a/DQM/SiPixelPhase1Common/plugins/SiPixelPhase1OnlineHarvester.cc b/DQM/SiPixelPhase1Common/plugins/SiPixelPhase1OnlineHarvester.cc deleted file mode 100644 index e0133770862c3..0000000000000 --- a/DQM/SiPixelPhase1Common/plugins/SiPixelPhase1OnlineHarvester.cc +++ /dev/null @@ -1,45 +0,0 @@ -// Harvester with a custom step to reset histograms. - -#include "DQM/SiPixelPhase1Common/interface/SiPixelPhase1Base.h" -#include "FWCore/Framework/interface/MakerMacros.h" - -class SiPixelPhase1OnlineHarvester : public SiPixelPhase1Harvester { - // Note: for the current setup of onlineblocks (for overlaid curves, - // e.g. useful for detector commisioning), this plugin is NOT needed. - - public: - SiPixelPhase1OnlineHarvester(const edm::ParameterSet& iConfig) - : SiPixelPhase1Harvester(iConfig) { - - int onlineblock = iConfig.getParameter("geometry").getParameter("onlineblock"); - int n_onlineblocks = iConfig.getParameter("geometry").getParameter("n_onlineblocks"); - - for (auto& h : histo) { - h.setCustomHandler([&h, onlineblock, n_onlineblocks] (SummationStep const& s, HistogramManager::Table & t, - DQMStore::IBooker&, DQMStore::IGetter&) { - if (!h.lumisection) return; // not online - uint32_t ls = h.lumisection->id().luminosityBlock(); - - // TODO: this is hard to get right if we don't see all LS. - uint32_t block = (ls / onlineblock) % n_onlineblocks; - uint32_t next_block = ((ls / onlineblock)+1) % n_onlineblocks; - if (block == next_block) return; - - for (auto& e : t) { - TH1* th1 = e.second.th1; - if (std::string(th1->GetYaxis()->GetTitle()).find("OnlineBlock") != std::string::npos) { - for (int i = 1; i <= th1->GetNbinsX(); i++) { - th1->SetBinContent(i, next_block+1, 0); - } - } else { - // TODO: do sth.like exponential decay here. - } - } - }); - } - } - -}; - -DEFINE_FWK_MODULE(SiPixelPhase1OnlineHarvester); - diff --git a/DQM/SiPixelPhase1Common/python/HistogramManager_cfi.py b/DQM/SiPixelPhase1Common/python/HistogramManager_cfi.py index 4cd0ad952c4e3..3c7caedd86982 100644 --- a/DQM/SiPixelPhase1Common/python/HistogramManager_cfi.py +++ b/DQM/SiPixelPhase1Common/python/HistogramManager_cfi.py @@ -3,12 +3,13 @@ from DQM.SiPixelPhase1Common.SpecificationBuilder_cfi import Specification, parent SiPixelPhase1Geometry = cms.PSet( - # Blades are numbered from 1 to n_inner_ring_blades for the inner ring, and - # from n_inner_ring_blades+1 to for the outer ring - n_inner_ring_blades = cms.int32(22), + # SPixel*Name and friends use the isUpgrade flag, so we also have it as a setting here. + upgradePhase = cms.int32(1), # module geometry. The phase1 detector has only one sort, so this is easy. # the values are assumed to be 0-based, unlike most others. + # TODO: maybe we can use the SiPixelFrameReverter and friends to do these + # conversions without these parameters here. module_rows = cms.int32(160), module_cols = cms.int32(416), roc_rows = cms.int32(80), @@ -22,7 +23,7 @@ # to select a different cabling map (for pilotBlade) CablingMapLabel = cms.string(""), - # online-secific things + # online-specific things onlineblock = cms.int32(20), # #LS after which histograms are reset n_onlineblocks = cms.int32(100), # #blocks to keep for histograms with history @@ -35,7 +36,7 @@ PerLadder = cms.PSet(enabled = cms.bool(True)) # histos per ladder, profiles PerLayer2D = cms.PSet(enabled = cms.bool(True)) # 2D maps/profiles of layers PerLayer1D = cms.PSet(enabled = cms.bool(True)) # normal histos per layer -PerLumisection = cms.PSet(enabled = cms.bool(True)) # trend profiles +PerReadout = cms.PSet(enabled = cms.bool(True)) # "Readout view", also for initial timing # Default histogram configuration. This is _not_ used automatically, but you # can import and pass this (or clones of it) in the plugin config. @@ -100,26 +101,44 @@ DefaultHistoTrack=DefaultHisto.clone() DefaultHistoTrack.topFolderName= cms.string("PixelPhase1/Tracks") +DefaultHistoReadout=DefaultHisto.clone() +DefaultHistoReadout.topFolderName= cms.string("PixelPhase1/FED/Readout") + # Commonly used specifications. StandardSpecifications1D = [ # The column names are either defined in the GeometryInterface.cc or read from TrackerTopology. # Endcap names side by side. The "/" separates columns and also defines how the output folders are nested. # per-ladder and profiles - Specification(PerLadder).groupBy("PXBarrel/Shell/PXLayer/PXLadder") + Specification(PerLadder).groupBy("PXBarrel/Shell/PXLayer/SignedLadder") .save() .reduce("MEAN") .groupBy("PXBarrel/Shell/PXLayer", "EXTEND_X") - .saveAll(), - Specification(PerLadder).groupBy("PXForward/HalfCylinder/PXDisk/PXRing/PXBlade") + .save(), + Specification(PerLadder).groupBy("PXForward/HalfCylinder/PXDisk/PXRing/SignedBlade") .save() .reduce("MEAN") .groupBy("PXForward/HalfCylinder/PXDisk/PXRing", "EXTEND_X") - .saveAll(), + .save() + .groupBy("PXForward/HalfCylinder/PXDisk/", "EXTEND_X") + .save(), + Specification().groupBy("PXBarrel").save(), + Specification().groupBy("PXForward").save(), Specification(PerLayer1D).groupBy("PXBarrel/Shell/PXLayer").save(), Specification(PerLayer1D).groupBy("PXForward/HalfCylinder/PXDisk/PXRing").save(), - Specification(PerModule).groupBy("PXBarrel/Shell/PXLayer/PXLadder/P1PXModuleName").save(), - Specification(PerModule).groupBy("PXForward/HalfCylinder/PXDisk/PXRing/PXBlade/P1PXModuleName").save(), + + Specification(PerModule).groupBy("PXBarrel/Shell/PXLayer/SignedLadder/PXModuleName").save(), + Specification(PerModule).groupBy("PXForward/HalfCylinder/PXDisk/PXRing/SignedBlade/PXModuleName").save(), + + Specification(PerLadder).groupBy("PXForward/HalfCylinder/PXDisk/PXRing/SignedBlade/PXPanel") + .reduce("MEAN") + .groupBy("PXForward/HalfCylinder/PXDisk/PXRing/SignedBlade","EXTEND_X") + .save(), + Specification(PerLadder).groupBy("PXBarrel/Shell/PXLayer/SignedLadder/PXBModule") + .reduce("MEAN") + .groupBy("PXBarrel/Shell/PXLayer/SignedLadder", "EXTEND_X") + .save(), + ] StandardSpecificationTrend = [ @@ -130,57 +149,139 @@ Specification().groupBy("PXForward/Lumisection") .reduce("MEAN") .groupBy("PXForward", "EXTEND_X") - .save(), + .save() ] +StandardSpecificationTrend2D = [ + Specification().groupBy("PXBarrel/PXLayer/Lumisection") + .reduce("MEAN") + .groupBy("PXBarrel/PXLayer", "EXTEND_X") + .groupBy("PXBarrel", "EXTEND_Y") + .save(), + Specification().groupBy("PXForward/PXDisk/Lumisection") + .reduce("MEAN") + .groupBy("PXForward/PXDisk","EXTEND_X") + .groupBy("PXForward", "EXTEND_Y") + .save() +] StandardSpecification2DProfile = [ Specification(PerLayer2D) - .groupBy("PXBarrel/PXLayer/signedLadder/signedModule") + .groupBy("PXBarrel/PXLayer/SignedLadder/SignedModule") + .groupBy("PXBarrel/PXLayer/SignedLadder", "EXTEND_X") + .groupBy("PXBarrel/PXLayer", "EXTEND_Y") + .reduce("MEAN") + .save(), + Specification(PerLayer2D) + .groupBy("PXForward/PXRing/SignedBladePanelCoord/SignedDiskCoord") + .groupBy("PXForward/PXRing/SignedBladePanelCoord", "EXTEND_X") + .groupBy("PXForward/PXRing", "EXTEND_Y") .reduce("MEAN") - .groupBy("PXBarrel/PXLayer/signedLadder", "EXTEND_X") + .save(), +] + +StandardSpecificationPixelmapProfile = [#produces pixel map with the mean (TProfile) + Specification(PerLayer2D) + .groupBy("PXBarrel/PXLayer/SignedLadderCoord/SignedModuleCoord") + .groupBy("PXBarrel/PXLayer/SignedLadderCoord", "EXTEND_X") .groupBy("PXBarrel/PXLayer", "EXTEND_Y") + .reduce("MEAN") .save(), Specification(PerLayer2D) - .groupBy("PXForward/PXDisk/PXBlade/PXPanel") + .groupBy("PXForward/PXRing/SignedBladePanelCoord/SignedDiskCoord") + .groupBy("PXForward/PXRing/SignedBladePanelCoord", "EXTEND_X") + .groupBy("PXForward/PXRing", "EXTEND_Y") .reduce("MEAN") - .groupBy("PXForward/PXDisk/PXBlade", "EXTEND_X") - .groupBy("PXForward/PXDisk", "EXTEND_Y") + .save(), +] + +StandardSpecificationOccupancy = [ #this produces pixel maps with counting + Specification(PerLayer2D) + .groupBy("PXBarrel/PXLayer/SignedLadderCoord/SignedModuleCoord") + .groupBy("PXBarrel/PXLayer/SignedLadderCoord", "EXTEND_X") + .groupBy("PXBarrel/PXLayer", "EXTEND_Y") + .save(), + Specification(PerLayer2D) + .groupBy("PXForward/PXRing/SignedBladePanelCoord/SignedDiskCoord") + .groupBy("PXForward/PXRing/SignedBladePanelCoord", "EXTEND_X") + .groupBy("PXForward/PXRing", "EXTEND_Y") .save(), ] # the same for NDigis and friends. Needed due to technical limitations... StandardSpecifications1D_Num = [ - Specification(PerLadder).groupBy("PXBarrel/Shell/PXLayer/PXLadder/DetId/Event") + Specification(PerLadder).groupBy("PXBarrel/Shell/PXLayer/SignedLadder/DetId/Event") .reduce("COUNT") # per-event counting - .groupBy("PXBarrel/Shell/PXLayer/PXLadder").save() + .groupBy("PXBarrel/Shell/PXLayer/SignedLadder").save() .reduce("MEAN") .groupBy("PXBarrel/Shell/PXLayer", "EXTEND_X") - .saveAll(), - Specification(PerModule).groupBy("PXBarrel/Shell/PXLayer/PXLadder/P1PXModuleName/Event") + .save(), + Specification(PerModule).groupBy("PXBarrel/Shell/PXLayer/SignedLadder/PXModuleName/Event") .reduce("COUNT") - .groupBy("PXBarrel/Shell/PXLayer/PXLadder/P1PXModuleName") + .groupBy("PXBarrel/Shell/PXLayer/SignedLadder/PXModuleName") .save(), - Specification(PerLadder).groupBy("PXForward/HalfCylinder/PXDisk/PXRing/PXBlade/DetId/Event") + Specification(PerLadder).groupBy("PXForward/HalfCylinder/PXDisk/PXRing/SignedBlade/DetId/Event") .reduce("COUNT") # per-event counting - .groupBy("PXForward/HalfCylinder/PXDisk/PXRing/PXBlade").save() + .groupBy("PXForward/HalfCylinder/PXDisk/PXRing/SignedBlade").save() .reduce("MEAN") .groupBy("PXForward/HalfCylinder/PXDisk/PXRing", "EXTEND_X") - .saveAll(), - Specification(PerModule).groupBy("PXForward/HalfCylinder/PXDisk/PXRing/PXBlade/P1PXModuleName/Event") + .save() + .groupBy("PXForward/HalfCylinder/PXDisk/", "EXTEND_X") + .save(), + Specification(PerModule).groupBy("PXForward/HalfCylinder/PXDisk/PXRing/SignedBlade/PXModuleName/Event") .reduce("COUNT") - .groupBy("PXForward/HalfCylinder/PXDisk/PXRing/PXBlade/P1PXModuleName") + .groupBy("PXForward/HalfCylinder/PXDisk/PXRing/SignedBlade/PXModuleName") .save(), + + Specification(PerLadder).groupBy("PXForward/HalfCylinder/PXDisk/PXRing/SignedBlade/PXPanel/Event") + .reduce("COUNT") + .groupBy("PXForward/HalfCylinder/PXDisk/PXRing/SignedBlade/PXPanel") + .reduce("MEAN") + .groupBy("PXForward/HalfCylinder/PXDisk/PXRing/SignedBlade","EXTEND_X") + .save(), + Specification(PerLadder).groupBy("PXBarrel/Shell/PXLayer/SignedLadder/PXBModule/Event") + .reduce("COUNT") + .groupBy("PXBarrel/Shell/PXLayer/SignedLadder/PXBModule") + .reduce("MEAN") + .groupBy("PXBarrel/Shell/PXLayer/SignedLadder", "EXTEND_X") + .save() +] + + +StandardSpecificationInclusive_Num = [#to count inclusively objects in substructures (BPix, FPix) + Specification().groupBy("PXBarrel/Event") + .reduce("COUNT") + .groupBy("PXBarrel") + .save(), + Specification().groupBy("PXForward/Event") + .reduce("COUNT") + .groupBy("PXForward") + .save() ] StandardSpecificationTrend_Num = [ - Specification().groupBy("PXBarrel/Lumisection/PXLayer/Event") + + Specification().groupBy("PXBarrel/PXLayer/Event") + .reduce("COUNT") + .groupBy("PXBarrel/PXLayer/Lumisection") + .reduce("MEAN") + .groupBy("PXBarrel/PXLayer","EXTEND_X") + .groupBy("PXBarrel", "EXTEND_Y") + .save(), + Specification().groupBy("PXBarrel/PXLayer/Event") .reduce("COUNT") .groupBy("PXBarrel/Lumisection") .reduce("MEAN") .groupBy("PXBarrel", "EXTEND_X") .save(), - Specification().groupBy("PXForward/Lumisection/PXDisk/Event") + Specification().groupBy("PXForward/PXDisk/Event") + .reduce("COUNT") + .groupBy("PXForward/PXDisk/Lumisection") + .reduce("MEAN") + .groupBy("PXForward/PXDisk","EXTEND_X") + .groupBy("PXForward", "EXTEND_Y") + .save(), + Specification().groupBy("PXForward/PXDisk/Event") .reduce("COUNT") .groupBy("PXForward/Lumisection") .reduce("MEAN") @@ -191,20 +292,20 @@ StandardSpecification2DProfile_Num = [ Specification(PerLayer2D) - .groupBy("PXBarrel/PXLayer/signedLadder/signedModule" + "/DetId/Event") + .groupBy("PXBarrel/PXLayer/SignedLadder/SignedModule" + "/DetId/Event") .reduce("COUNT") - .groupBy("PXBarrel/PXLayer/signedLadder/signedModule") + .groupBy("PXBarrel/PXLayer/SignedLadder/SignedModule") .reduce("MEAN") - .groupBy("PXBarrel/PXLayer/signedLadder", "EXTEND_X") + .groupBy("PXBarrel/PXLayer/SignedLadder", "EXTEND_X") .groupBy("PXBarrel/PXLayer", "EXTEND_Y") .save(), Specification(PerLayer2D) - .groupBy("PXForward/PXDisk/PXBlade/PXPanel" + "/DetId/Event") + .groupBy("DetId/Event") .reduce("COUNT") - .groupBy("PXForward/PXDisk/PXBlade/PXPanel") - .reduce("MEAN") - .groupBy("PXForward/PXDisk/PXBlade", "EXTEND_X") - .groupBy("PXForward/PXDisk", "EXTEND_Y") + .groupBy("PXForward/PXRing/PXDisk/SignedBladePanel") + .reduce("MEAN") + .groupBy("PXForward/PXRing/PXDisk", "EXTEND_Y") + .groupBy("PXForward/PXRing", "EXTEND_X") .save(), ] diff --git a/DQM/SiPixelPhase1Common/python/SiPixelPhase1GeometryDebug_cfi.py b/DQM/SiPixelPhase1Common/python/SiPixelPhase1GeometryDebug_cfi.py index f34ab72534cb1..1a8d97f332c25 100644 --- a/DQM/SiPixelPhase1Common/python/SiPixelPhase1GeometryDebug_cfi.py +++ b/DQM/SiPixelPhase1Common/python/SiPixelPhase1GeometryDebug_cfi.py @@ -1,44 +1,59 @@ import FWCore.ParameterSet.Config as cms from DQM.SiPixelPhase1Common.HistogramManager_cfi import * -SiPixelPhase1GeometryDebugDetId = DefaultHisto.clone( +DefaultHistoDebug = DefaultHisto.clone( + topFolderName = "PixelPhase1/Debug" +) + +SiPixelPhase1GeometryDebugDetId = DefaultHistoDebug.clone( name = "debug_detid", title = "Location of DetIds", xlabel = "DetId", dimensions = 1, - specs = cms.VPSet( - StandardSpecification2DProfile + specs = VPSet( + StandardSpecification2DProfile, + StandardSpecificationPixelmapProfile, ) ) -SiPixelPhase1GeometryDebugLadderBlade = DefaultHisto.clone( +SiPixelPhase1GeometryDebugLadderBlade = DefaultHistoDebug.clone( name = "debug_ladderblade", title = "Location of Ladders/Blades", xlabel = "offline Ladder/Blade #", dimensions = 1, - specs = cms.VPSet( - StandardSpecification2DProfile + specs = VPSet( + StandardSpecification2DProfile, + StandardSpecificationPixelmapProfile, ) ) -SiPixelPhase1GeometryDebugROC = DefaultHisto.clone( +SiPixelPhase1GeometryDebugROC = DefaultHistoDebug.clone( name = "debug_roc", title = "Location of ROCs", xlabel = "ROC#", dimensions = 1, - specs = cms.VPSet( + specs = VPSet( # TODO: make this per ROC! - StandardSpecification2DProfile + StandardSpecification2DProfile, + StandardSpecificationPixelmapProfile, + Specification() + .groupBy("PXBarrel/PXLayer/PXModuleName/SignedLadderCoord/SignedModuleCoord") + .groupBy("PXBarrel/PXLayer/PXModuleName/SignedLadderCoord", "EXTEND_X") + .groupBy("PXBarrel/PXLayer/PXModuleName/", "EXTEND_Y") + .reduce("MEAN") + .save(), + ) ) -SiPixelPhase1GeometryDebugFED = DefaultHisto.clone( +SiPixelPhase1GeometryDebugFED = DefaultHistoDebug.clone( name = "debug_fed", title = "Location of FEDs", xlabel = "FED#", dimensions = 1, - specs = cms.VPSet( - StandardSpecification2DProfile + specs = VPSet( + StandardSpecification2DProfile, + StandardSpecificationPixelmapProfile, ) ) diff --git a/DQM/SiPixelPhase1Common/python/SpecificationBuilder_cfi.py b/DQM/SiPixelPhase1Common/python/SpecificationBuilder_cfi.py index ff72d19dce7df..5b3fcb5f2edec 100644 --- a/DQM/SiPixelPhase1Common/python/SpecificationBuilder_cfi.py +++ b/DQM/SiPixelPhase1Common/python/SpecificationBuilder_cfi.py @@ -7,6 +7,7 @@ # which outputs a valid form. # these need to stay in sync with the C++ enums. TODO: Can we use Python3 enum or sth.? +# Internal specification step types NO_TYPE = cms.int32(0) GROUPBY = cms.int32(1) # only "SUM", real histograms EXTEND_X = cms.int32(2) # use geometry column as coordinate axis, concatenate @@ -14,17 +15,20 @@ COUNT = cms.int32(4) # drop all values, only count entries. Atm only step1. REDUCE = cms.int32(5) # histogram-to-scalar operator for harvesting, atm only MEAN SAVE = cms.int32(6) # atm not used in execution. Marks stage1/2 switch. -CUSTOM = cms.int32(7) # call callback in harvesting USE_X = cms.int32(8) # use arg-th fill(...) parameter for the respective axis. USE_Y = cms.int32(9) USE_Z = cms.int32(10) PROFILE = cms.int32(11) # marker for step1 to make a profile, related to REDUCE(MEAN) +# Specifications are broken down into Stages, that are executed at different +# points in time (in the fill call, in pre-event harvesting (counters), in +# harvesting (DQM step2) NO_STAGE = cms.int32(0) FIRST = cms.int32(1) # first grouping, before and/or after counting STAGE1 = cms.int32(2) # USE/EXTEND/PROFILE for step1 STAGE2 = cms.int32(3) # REDUCE/EXTEND/GROUPBY/CUSTOM for harvesting +# small helpers def val(maybecms): if hasattr(maybecms, "value"): return maybecms.value() @@ -39,26 +43,30 @@ def parent(path): DefaultConf = cms.PSet(enabled = cms.bool(True)) -# The Specification format is very rigid and looks much less like a program in -# the internal form: -# - There is one entry FIRST, which is a GROUPBY(SUM) or COUNT and some columns -# - There is another entry FIRST, which is a GROUPBY(SUM) and some columns iff +# The internal Specification format is very rigid and looks much less like a +# program in the internal form: +# - There is one entry FIRST, which is a GROUPBY or COUNT and some columns +# - There is another entry FIRST, which is a GROUPBY and some columns iff # the one before was COUNT # - There are some entries STAGE1 # - There is one entry per dimension (ordered) # - which is either USE_* or EXTEND_* -# - with one column, that is usually NOT listed in first. +# - with one column, that is NOT listed in FIRST. # - There is optionally an entry PROFILE to make a profile. -# - There are 0-n steps STAGE2, which are one of GROUPBY(SUM), EXTEND_X, CUSTOM +# - There are 0-n steps STAGE2, which are one of GROUPBY, EXTEND_X # - The argument for GROUPBY and EXTEND_X is a subset of columns of last step -# - CUSTOM may have an arbitrary argument that is simply passed down # - SAVE is ignored class Specification(cms.PSet): def __init__(self, conf = DefaultConf): super(Specification, self).__init__() + # these are the steps passed down to C++. Will be filled later. self.spec = cms.VPSet() + # this is currently only an additional enable flag. Might add topFolder or + # range there in the future. self.conf = conf + + # these are onlly used during construction. self._activeColumns = set() self._state = FIRST @@ -70,9 +78,15 @@ def __deepcopy__(self, memo): return t def groupBy(self, cols, mode = "SUM"): - cnames = val(cols).split("/") + cnames = filter(len, val(cols).split("/")) # omit empty items newstate = self._state + # The behaviour of groupBy depends a lot on when it happens: + # - The first (or second, if there is per-event counting) are very special + # - others in STAGE1 have to be EXTEND, and they will be translated into a + # list of exactly 3 USE/EXTEND steps (one per dimension). + # - in STAGE2 they are just passed down to C++. + if self._state == FIRST: cname = cnames if mode != "SUM": @@ -100,10 +114,10 @@ def groupBy(self, cols, mode = "SUM"): else: raise Exception("Only EXTEND_X or EXTEND_Y allowed here, not " + mode) - # remove the column in earlier steps, we always re-extract in step1. + # remove the column in the FIRST groupBy, we always re-extract in step1. c = list(cname)[0] for s in self.spec: - if s.stage == FIRST and c in s.columns: + if s.stage == FIRST and s.type == GROUPBY and c in s.columns: s.columns.remove(c) if c in self._activeColumns: self._activeColumns.remove(c) @@ -134,8 +148,9 @@ def groupBy(self, cols, mode = "SUM"): arg = cms.string(mode) )) + # In the very beginning emit standard column assignments, they will be + # changed later (above and in save()) to reflect the EXTENDS given above. if newstate == STAGE1 and self._state == FIRST: - # emit standard column assignments, will be changed later self._x = cms.PSet( type = USE_X, stage = STAGE1, columns = cms.vstring(), @@ -160,6 +175,10 @@ def groupBy(self, cols, mode = "SUM"): return self def reduce(self, sort): + # reduce can be MEAN or COUNT. in STAGE2, just pass through. + # in STAGE1, MEAN (anywhere) means make a PROFILE + # COUNT can mean per-event counting or a occupancy plot, which is acheived + # by ignoring the values passed to fill() (like dimensions=0, TODO). if self._state == FIRST: if sort != "COUNT": raise Exception("First statement must be groupBy.") @@ -210,19 +229,8 @@ def save(self): self._state = STAGE2 return self - def custom(self, arg = ""): - if self._state != STAGE2: - raise Exception("Custom processing exists only in Harvesting.") - self.spec.append(cms.PSet( - type = CUSTOM, - stage = self._state, - columns = cms.vstring(), - arg = cms.string(arg) - )) - return self - - def saveAll(self): + # call groupBy() and save() until all colums are consumed. self.save() columns = self._lastColumns for i in range(len(columns)-1, 0, -1): diff --git a/DQM/SiPixelPhase1Common/src/GeometryInterface.cc b/DQM/SiPixelPhase1Common/src/GeometryInterface.cc index b27a7e5c3a2ef..d380f215761f6 100644 --- a/DQM/SiPixelPhase1Common/src/GeometryInterface.cc +++ b/DQM/SiPixelPhase1Common/src/GeometryInterface.cc @@ -9,6 +9,9 @@ #include "DQM/SiPixelPhase1Common/interface/GeometryInterface.h" +// general plotting helpers +#include "DQM/SiPixelPhase1Common/interface/SiPixelCoordinates.h" + // edm stuff #include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" @@ -21,6 +24,7 @@ #include "CondFormats/GeometryObjects/interface/PTrackerParameters.h" #include "CondFormats/SiPixelObjects/interface/SiPixelFedCablingMap.h" #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" +#include "CondFormats/SiPixelObjects/interface/SiPixelFrameReverter.h" // Pixel names #include "DataFormats/SiPixelDetId/interface/PixelBarrelName.h" @@ -31,6 +35,7 @@ #include #include #include +#include const GeometryInterface::Value GeometryInterface::UNDEFINED = 999999999.9f; @@ -40,6 +45,7 @@ void GeometryInterface::load(edm::EventSetup const& iSetup) { loadTimebased(iSetup, iConfig); loadModuleLevel(iSetup, iConfig); loadFEDCabling(iSetup, iConfig); + loadFromSiPixelCoordinates(iSetup, iConfig); edm::LogInfo log("GeometryInterface"); log << "Known colum names:\n"; for (auto e : ids) log << "+++ column: " << e.first @@ -114,7 +120,9 @@ void GeometryInterface::loadFromTopology(edm::EventSetup const& iSetup, const ed // these are just aliases with special handling in formatting // the names are created with PixelBarrelName et. al. later addExtractor(intern("PXModuleName"), detid, 0, 0); - addExtractor(intern("P1PXModuleName"), detid, 0, 0); + + int phase = iConfig.getParameter("upgradePhase"); + bool isUpgrade = phase == 1; // Get a Geometry edm::ESHandle trackerGeometryHandle; @@ -125,136 +133,165 @@ void GeometryInterface::loadFromTopology(edm::EventSetup const& iSetup, const ed auto module_rows = iConfig.getParameter("module_rows") - 1; auto module_cols = iConfig.getParameter("module_cols") - 1; - // We need to track some extra stuff here for the Shells later. - auto pxlayer = extractors[intern("PXLayer")]; - auto pxladder = extractors[intern("PXLadder")]; - auto pxmodule = extractors[intern("PXBModule")]; - auto pxblade = extractors[intern("PXBlade")]; - std::vector maxladders; - Value maxmodule = 0; - Value innerring = iConfig.getParameter("n_inner_ring_blades"); - Value outerring = 0; - // Now traverse the detector and collect whatever we need. auto detids = trackerGeometryHandle->detIds(); for (DetId id : detids) { if (id.subdetId() != PixelSubdetector::PixelBarrel && id.subdetId() != PixelSubdetector::PixelEndcap) continue; auto iq = InterestingQuantities{nullptr, id, 0, 0}; - auto layer = pxlayer(iq); - if (layer != UNDEFINED) { - if (layer >= Value(maxladders.size())) maxladders.resize(layer+1); - auto ladder = pxladder(iq); - if (ladder > maxladders[layer]) maxladders[layer] = ladder; - } - auto module = pxmodule(iq); - if (module != UNDEFINED && module > maxmodule) maxmodule = module; - auto blade = pxblade(iq); - if (blade != UNDEFINED && blade > outerring) outerring = blade; // prepare pretty names - // We try Phase0 and Phase1 here, since we only later know which to use... - std::string name_P0 = "", name_P1 = ""; - if (layer != UNDEFINED) { // Barrel - PixelBarrelName mod_P0(id, tt, false); - PixelBarrelName mod_P1(id, tt, true); - name_P0 = mod_P0.name(); - name_P1 = mod_P1.name(); + std::string name = ""; + if (id.subdetId() == PixelSubdetector::PixelBarrel) { // Barrel + PixelBarrelName mod(id, tt, isUpgrade); + name = mod.name(); } else { // assume Endcap - PixelEndcapName mod_P0(id, tt, false); - PixelEndcapName mod_P1(id, tt, true); - name_P0 = mod_P0.name(); - name_P1 = mod_P1.name(); + PixelEndcapName mod(id, tt, isUpgrade); + name = mod.name(); } - format_value[std::make_pair(intern("PXModuleName"), Value(id.rawId()))] = name_P0; - format_value[std::make_pair(intern("P1PXModuleName"), Value(id.rawId()))] = name_P1; + format_value[std::make_pair(intern("PXModuleName"), Value(id.rawId()))] = name; // we record each module 4 times, one for each corner, so we also get ROCs // in booking (at least for the ranges) - iq.row = 0; iq.col = 0; + // TODO: add all ROCs? + // TODO: Things are more complicated for phase2, and we support that via + // SiPixelCoordinates, so we should support it here too. + iq.row = 1; iq.col = 1; all_modules.push_back(iq); - iq.row = module_rows; iq.col = 0; + iq.row = module_rows-1; iq.col = 1; all_modules.push_back(iq); - iq.row = 0; iq.col = module_cols; + iq.row = 1; iq.col = module_cols-1; all_modules.push_back(iq); - iq.row = module_rows; iq.col = module_cols; + iq.row = module_rows-1; iq.col = module_cols-1; all_modules.push_back(iq); } +} + +void GeometryInterface::loadFromSiPixelCoordinates(edm::EventSetup const& iSetup, const edm::ParameterSet& iConfig) { + // TODO: SiPixelCoordinates has a large overlap with theis GeometryInterface + // in general. + // Rough convention is to use own code for things that are easy and fast to + // determine, and use SiPixelCoordinates for complicated things. + // SiPixelCoordinates uses lookup maps for everything, so it is faster than + // most other code, but still slow on DQM scales. + int phase = iConfig.getParameter("upgradePhase"); - outerring = outerring - innerring; + // this shared pointer is kept alive by the references in the lambdas that follow. + // That is a bit less obvious than keeping it as a member but more correct. + auto coord = std::make_shared(phase); - // Shells are a concept that cannot be derived from bitmasks. - // Use hardcoded logic here. - // This contains a lot more assumptions about general geometry than the rest - // of the code, but it might work for Phase0 as well. + // note that we should reeinit for each event. But this probably won't explode + // thanks to the massive memoization in SiPixelCoordinates which is completely + // initialized while booking. + coord->init(iSetup); + + // SiPixelCoordinates uses a different convention for UNDEFINED: + auto from_coord = [](double in) { return (in == -9999.0) ? UNDEFINED : Value(in); }; + + // Rings are a concept that cannot be derived from bitmasks. addExtractor(intern("PXRing"), - [pxblade, innerring] (InterestingQuantities const& iq) { - auto blade = pxblade(iq); - if (blade == UNDEFINED) return UNDEFINED; - if (blade <= innerring) return Value(1); - else return Value(2); + [coord, from_coord] (InterestingQuantities const& iq) { + return from_coord(coord->ring(iq.sourceModule)); } ); + // Quadrant names. + auto pxbarrel = extractors[intern("PXBarrel")]; addExtractor(intern("HalfCylinder"), - [pxendcap, pxblade, innerring, outerring] (InterestingQuantities const& iq) { - auto ec = pxendcap(iq); - if (ec == UNDEFINED) return UNDEFINED; - auto blade = pxblade(iq); - // blade 1 and 56 are at 3 o'clock. This is a mess. - auto inring = blade > innerring ? (innerring+outerring+1) - blade : blade; - auto perring = blade > innerring ? outerring : innerring; - // inring is now 1-based, 1 at 3 o'clock, upto perring. - int frac = (int) ((inring-1) / float(perring) * 4); // floor semantics here - if (frac == 0 || frac == 3) return 10*ec + 1; // inner half - if (frac == 1 || frac == 2) return 10*ec + 2; // outer half - assert(!"HalfCylinder logic problem"); - return UNDEFINED; + [coord, pxbarrel] (InterestingQuantities const& iq) { + if (pxbarrel(iq) != UNDEFINED) return UNDEFINED; + int quadrant = coord->quadrant(iq.sourceModule); + switch (quadrant) { + case 1: return Value(12); // mO + case 2: return Value(11); // mI + case 3: return Value(22); // pO + case 4: return Value(21); // pI + default: return UNDEFINED; + } + }, 0, 0 // N/A + ); + addExtractor(intern("Shell"), + [coord, pxbarrel] (InterestingQuantities const& iq) { + if (pxbarrel(iq) == UNDEFINED) return UNDEFINED; + int quadrant = coord->quadrant(iq.sourceModule); + switch (quadrant) { + case 1: return Value(12); // mO + case 2: return Value(11); // mI + case 3: return Value(22); // pO + case 4: return Value(21); // pI + default: return UNDEFINED; + } }, 0, 0 // N/A ); - // For the '+-shape' (ladder vs. module) plots, we need signed numbers with - // (unused) 0-ladder/module at x=0/z=0. This means a lot of messing with the - // ladder/shell numbering... - addExtractor(intern("signedLadder"), - [pxbarrel, pxladder, pxlayer, maxladders, maxmodule] (InterestingQuantities const& iq) { - if(pxbarrel(iq) == UNDEFINED) return UNDEFINED; - auto layer = pxlayer(iq); - auto ladder = pxladder(iq); - int frac = (int) ((ladder-1) / float(maxladders[layer]) * 4); // floor semantics - Value quarter = maxladders[layer] / 4; - if (frac == 0) return -ladder + quarter + 1; // top right - +1 for gap - if (frac == 1) return -ladder + quarter; // top left - - if (frac == 2) return -ladder + quarter; // bot left - same - if (frac == 3) return -ladder + 4*quarter + quarter + 1; // bot right - like top right but wrap around - assert(!"Shell logic problem"); - return UNDEFINED; + // Online Numbering. + addExtractor(intern("SignedLadder"), + [coord, from_coord] (InterestingQuantities const& iq) { + return from_coord(coord->signed_ladder(iq.sourceModule())); } ); - - addExtractor(intern("signedModule"), - [pxmodule, maxmodule] (InterestingQuantities const& iq) { - Value mod = pxmodule(iq); // range 1..maxmodule - if (mod == UNDEFINED) return UNDEFINED; - mod -= (maxmodule/2 + 1); // range -(max_module/2)..-1, 0.. - if (mod >= 0) mod += 1; // range -(max_module/2)..-1, 1.. - return mod; + addExtractor(intern("SignedModule"), + [coord, from_coord] (InterestingQuantities const& iq) { + return from_coord(coord->signed_module(iq.sourceModule())); + } + ); + addExtractor(intern("SignedBlade"), + [coord, from_coord] (InterestingQuantities const& iq) { + return from_coord(coord->signed_blade(iq.sourceModule())); } ); - auto signedladder = extractors[intern("signedLadder")]; - auto signedmodule = extractors[intern("signedModule")]; - addExtractor(intern("Shell"), - [signedladder, signedmodule] (InterestingQuantities const& iq) { - auto sl = signedladder(iq); - auto sm = signedmodule(iq); - if (sl == UNDEFINED) return UNDEFINED; - return Value((sm < 0 ? 10 : 20) + (sl < 0 ? 2 : 1)); // negative means outer shell!? - }, 0, 0 // N/A + // Pixel Map axis. + // TODO: binning should be phase-dependent. Or maybe even per-plot configurable. + addExtractor(intern("SignedModuleCoord"), + [coord, from_coord] (InterestingQuantities const& iq) { + return from_coord(coord->signed_module_coord(iq.sourceModule(), + std::make_pair(int(iq.row), int(iq.col)))); + }, UNDEFINED, UNDEFINED, 1.0/8.0 + ); + addExtractor(intern("SignedLadderCoord"), + [coord, from_coord] (InterestingQuantities const& iq) { + return from_coord(coord->signed_ladder_coord(iq.sourceModule(), + std::make_pair(int(iq.row), int(iq.col)))); + }, UNDEFINED, UNDEFINED, 1.0/2.0 + ); + addExtractor(intern("SignedDiskCoord"), + [coord, from_coord] (InterestingQuantities const& iq) { + return from_coord(coord->signed_disk_coord(iq.sourceModule(), + std::make_pair(int(iq.row), int(iq.col)))); + }, UNDEFINED, UNDEFINED, 1.0/8.0 + ); + addExtractor(intern("SignedBladePanelCoord"), + [coord, from_coord, phase] (InterestingQuantities const& iq) { + if (phase == 0) { + return from_coord(coord->signed_blade_coord( + iq.sourceModule(), std::make_pair(int(iq.row), int(iq.col)))); + } else if (phase == 1) { + return from_coord(coord->signed_blade_panel_coord( + iq.sourceModule(), std::make_pair(int(iq.row), int(iq.col)))); + } else { + // TODO: phase2 + return UNDEFINED; + } + }, UNDEFINED, UNDEFINED, phase == 1 ? 0.25 : 0.2 ); - addExtractor(intern(""), // A dummy column. Not much special handling required. - [] (InterestingQuantities const& iq) { return 0; }, - 0, 0 + addExtractor(intern("SignedBladePanel"), + [coord, from_coord] (InterestingQuantities const& iq) { + return from_coord(coord->signed_blade_panel_coord(iq.sourceModule(), std::make_pair(int(iq.row), int(iq.col)))); + }, UNDEFINED, UNDEFINED, 1.0/2.0 + ); + + // more readout-related things. + addExtractor(intern("ROC"), + [coord, from_coord] (InterestingQuantities const& iq) { + return from_coord(coord->roc(iq.sourceModule(), + std::make_pair(int(iq.row), int(iq.col)))); + } + ); + addExtractor(intern("Sector"), + [coord, from_coord] (InterestingQuantities const& iq) { + return from_coord(coord->sector(iq.sourceModule())); + } ); } @@ -304,79 +341,47 @@ void GeometryInterface::loadModuleLevel(edm::EventSetup const& iSetup, const edm 0, iConfig.getParameter("module_cols") - 1 ); - int n_rocs = iConfig.getParameter("n_rocs"); - float roc_cols = iConfig.getParameter("roc_cols"); - float roc_rows = iConfig.getParameter("roc_rows"); - auto pxmodule = extractors[intern("PXBModule")]; - auto pxpanel = extractors[intern("PXPanel")]; - addExtractor(intern("ROC"), - [n_rocs, roc_cols, roc_rows] (InterestingQuantities const& iq) { - int fedrow = int(iq.row / roc_rows); - int fedcol = int(iq.col / roc_cols); - if (fedrow == 0) return Value(fedcol); - if (fedrow == 1) return Value(n_rocs - 1 - fedcol); - return UNDEFINED; - } - ); - - // arbitrary per-ladder numbering (for inefficiencies) - auto roc = extractors[intern("ROC")]; - addExtractor(intern("ROCinLadder"), - [pxmodule, roc, n_rocs] (InterestingQuantities const& iq) { - auto mod = pxmodule(iq); - if (mod == UNDEFINED) return UNDEFINED; - return Value(roc(iq) + n_rocs * (mod-1)); - } - ); - addExtractor(intern("ROCinBlade"), - [pxmodule, pxpanel, roc, n_rocs] (InterestingQuantities const& iq) { - auto mod = pxpanel(iq); - if (mod == UNDEFINED) return UNDEFINED; - return Value(roc(iq) + n_rocs * (mod-1)); - } - ); - } void GeometryInterface::loadFEDCabling(edm::EventSetup const& iSetup, const edm::ParameterSet& iConfig) { auto cablingMapLabel = iConfig.getParameter("CablingMapLabel"); edm::ESHandle theCablingMap; iSetup.get().get(cablingMapLabel, theCablingMap); - std::map fedmap; - std::map chanmap; - - if (theCablingMap.isValid()) { - auto map = theCablingMap.product(); - - for(auto iq : all_modules) { - std::vector paths = map->pathToDetUnit(iq.sourceModule.rawId()); - for (auto p : paths) { - //std::cout << "+++ cabling " << iq.sourceModule.rawId() << " " << p.fed << " " << p.link << " " << p.roc << "\n"; - fedmap[iq.sourceModule] = Value(p.fed); - // TODO: this might not be correct, since channels are assigned per ROC. - chanmap[iq.sourceModule] = Value(p.link); - } - } - } else { - edm::LogError("GeometryInterface") << "+++ No cabling map. Cannot extract FEDs.\n"; - } + + std::shared_ptr siPixelFrameReverter = + // I think passing the bare pointer here is safe, but who knows... + std::make_shared(iSetup, theCablingMap.operator->()); addExtractor(intern("FED"), - [fedmap] (InterestingQuantities const& iq) { + [siPixelFrameReverter] (InterestingQuantities const& iq) { if (iq.sourceModule == 0xFFFFFFFF) return Value(iq.col); // hijacked for the raw data plugin - auto it = fedmap.find(iq.sourceModule); - if (it == fedmap.end()) return GeometryInterface::UNDEFINED; - return it->second; + return Value(siPixelFrameReverter->findFedId(iq.sourceModule.rawId())); } ); - addExtractor(intern("FEDChannel"), - [chanmap] (InterestingQuantities const& iq) { + + // TODO: ranges should be set manually below, since booking probably cannot + // infer them correctly (no ROC-level granularity) + addExtractor(intern("LinkInFed"), + [siPixelFrameReverter] (InterestingQuantities const& iq) { if (iq.sourceModule == 0xFFFFFFFF) return Value(iq.row); // hijacked for the raw data plugin - auto it = chanmap.find(iq.sourceModule); - if (it == chanmap.end()) return GeometryInterface::UNDEFINED; - return it->second; + sipixelobjects::GlobalPixel gp = {iq.row, iq.col}; + return Value(siPixelFrameReverter->findLinkInFed(iq.sourceModule.rawId(), gp)); + } + ); + // not sure if this is useful anywhere. + addExtractor(intern("RocInLink"), + [siPixelFrameReverter] (InterestingQuantities const& iq) { + sipixelobjects::GlobalPixel gp = {iq.row, iq.col}; + return Value(siPixelFrameReverter->findRocInLink(iq.sourceModule.rawId(), gp)); + } + ); + // This might be equivalent to our ROC numbering. + addExtractor(intern("RocInDet"), + [siPixelFrameReverter] (InterestingQuantities const& iq) { + sipixelobjects::GlobalPixel gp = {iq.row, iq.col}; + return Value(siPixelFrameReverter->findRocInDet(iq.sourceModule.rawId(), gp)); } ); } diff --git a/DQM/SiPixelPhase1Common/src/HistogramManager.cc b/DQM/SiPixelPhase1Common/src/HistogramManager.cc index 05b34938a8c08..03186a5d7de86 100644 --- a/DQM/SiPixelPhase1Common/src/HistogramManager.cc +++ b/DQM/SiPixelPhase1Common/src/HistogramManager.cc @@ -425,14 +425,28 @@ void HistogramManager::book(DQMStore::IBooker& iBooker, // determine nbins for geometry derived quantities // due to how we counted above, we need to include lower and upper bound + // For Coord-values, which are not precisely aligned with the bins, we force + // alignment. if (mei.binwidth_x != 0) { - mei.range_x_min -= mei.binwidth_x/2; - mei.range_x_max += mei.binwidth_x/2; + double range = (mei.range_x_max - mei.range_x_min)/mei.binwidth_x; + if ((range - int(range)) == 0.0) { + mei.range_x_min -= mei.binwidth_x/2; + mei.range_x_max += mei.binwidth_x/2; + } else { + mei.range_x_min = std::floor(mei.range_x_min/mei.binwidth_x)*mei.binwidth_x; + mei.range_x_max = std::ceil(mei.range_x_max/mei.binwidth_x)*mei.binwidth_x; + } mei.range_x_nbins = int((mei.range_x_max - mei.range_x_min)/mei.binwidth_x); } if (mei.binwidth_y != 0) { - mei.range_y_min -= mei.binwidth_y/2; - mei.range_y_max += mei.binwidth_y/2; + double range = (mei.range_y_max - mei.range_y_min)/mei.binwidth_y; + if ((range - int(range)) == 0.0) { + mei.range_y_min -= mei.binwidth_y/2; + mei.range_y_max += mei.binwidth_y/2; + } else { + mei.range_y_min = std::floor(mei.range_y_min/mei.binwidth_y)*mei.binwidth_y; + mei.range_y_max = std::ceil(mei.range_y_max/mei.binwidth_y)*mei.binwidth_y; + } mei.range_y_nbins = int((mei.range_y_max - mei.range_y_min)/mei.binwidth_y); } @@ -576,7 +590,6 @@ void HistogramManager::executeExtend(SummationStep const& step, Table& t, AbstractHistogram& new_histo = out[significantvalues]; if (!new_histo.me) { - // TODO: this might be incorrect, but it is only for the title. // we put the name of the actual, last column of a input histo there. std::string colname = geometryInterface.pretty((e.first.end()-1)->first); @@ -661,9 +674,6 @@ void HistogramManager::executeHarvesting(DQMStore::IBooker& iBooker, case SummationStep::EXTEND_Y: assert(!"EXTEND_Y currently not supported in harvesting."); break; - case SummationStep::CUSTOM: - if (customHandler) customHandler(step, t, iBooker, iGetter); - break; default: assert(!"Operation not supported in harvesting."); } diff --git a/DQM/SiPixelPhase1Common/src/SiPixelCoordinates.cc b/DQM/SiPixelPhase1Common/src/SiPixelCoordinates.cc new file mode 100644 index 0000000000000..d76b2ba0eebf6 --- /dev/null +++ b/DQM/SiPixelPhase1Common/src/SiPixelCoordinates.cc @@ -0,0 +1,916 @@ +// -*- C++ -*- +// +// Class: SiPixelCoordinates +// +// Implementations of the class +// +// Original Author: Janos Karancsi + +#include "../interface/SiPixelCoordinates.h" + +#include "Geometry/TrackerGeometryBuilder/interface/PixelGeomDetUnit.h" +#include "Geometry/CommonTopologies/interface/PixelTopology.h" +#include "Geometry/Records/interface/TrackerDigiGeometryRecord.h" +#include "CondFormats/DataRecord/interface/SiPixelFedCablingMapRcd.h" +#include "DataFormats/SiPixelDetId/interface/PixelBarrelName.h" +#include "DataFormats/SiPixelDetId/interface/PixelEndcapName.h" +#include "DataFormats/FEDRawData/interface/FEDNumbering.h" +#include "CondFormats/SiPixelObjects/interface/SiPixelFrameConverter.h" + +#include + +// _________________________________________________________ +// Constructors, destructor +SiPixelCoordinates::SiPixelCoordinates() { phase_=-1; } + +SiPixelCoordinates::SiPixelCoordinates(int phase) : phase_(phase) {} + +SiPixelCoordinates::~SiPixelCoordinates() {} + + +// _________________________________________________________ +// init, called in the beginning of each event +void SiPixelCoordinates::init(edm::EventSetup const& iSetup) { + // Get CablingMap (used for ROC number) + edm::ESHandle cablingMapHandle; + iSetup.get().get(cablingMapHandle); + cablingMap_ = cablingMapHandle.product(); + + // Get TrackerTopology + edm::ESHandle trackerTopologyHandle; + iSetup.get().get(trackerTopologyHandle); + tTopo_ = trackerTopologyHandle.product(); + + // Get TrackerGeometry + edm::ESHandle trackerGeometryHandle; + iSetup.get().get(trackerGeometryHandle); + tGeom_ = trackerGeometryHandle.product(); + + // If not specified, determine from the geometry + if (phase_==-1) { + if (tGeom_ -> isThere(GeomDetEnumerators::PixelBarrel) && + tGeom_ -> isThere(GeomDetEnumerators::PixelEndcap) ) + phase_ = 0; + else if (tGeom_ -> isThere(GeomDetEnumerators::P1PXB) && + tGeom_ -> isThere(GeomDetEnumerators::P1PXEC) ) + phase_ = 1; + else if (tGeom_ -> isThere(GeomDetEnumerators::P1PXB) && + tGeom_ -> isThere(GeomDetEnumerators::P1PXEC) ) + phase_ = 2; + } +} + +// _________________________________________________________ +// Offline/Online variables from TrackerTopology +// and pixel naming classes + +// Taken from pixel naming classes +// BmO (-z-x) = 1, BmI (-z+x) = 2 , BpO (+z-x) = 3 , BpI (+z+x) = 4 +int SiPixelCoordinates::quadrant(const DetId& detid) { + if (quadrant_.count(detid.rawId())) return quadrant_[detid.rawId()]; + if (!isPixel_(detid)) return quadrant_[detid.rawId()] = -9999; + if(detid.subdetId() == PixelSubdetector::PixelBarrel) + return quadrant_[detid.rawId()] = PixelBarrelName(detid, tTopo_, phase_).shell(); + else + return quadrant_[detid.rawId()] = PixelEndcapName(detid, tTopo_, phase_).halfCylinder(); +} + +// Taken from Pixel naming class for barrel +// and TrackerTopology for endcap +// BmO/BmI = 1, BpO/BpI = 2 +int SiPixelCoordinates::side(const DetId& detid) { + if (side_.count(detid.rawId())) return side_[detid.rawId()]; + if (!isPixel_(detid)) return side_[detid.rawId()] = -9999; + if(detid.subdetId() == PixelSubdetector::PixelBarrel) + return side_[detid.rawId()] = 1 + (quadrant(detid)>2); + else + return side_[detid.rawId()] = tTopo_->pxfSide(detid); +} + +// Offline module convention taken from TrackerTopology +int SiPixelCoordinates::module(const DetId& detid) { + if (module_.count(detid.rawId())) return module_[detid.rawId()]; + if (!isPixel_(detid)) return module_[detid.rawId()] = -9999; + if(detid.subdetId() == PixelSubdetector::PixelBarrel) + return module_[detid.rawId()] = tTopo_->pxbModule(detid.rawId()); + else + return module_[detid.rawId()] = tTopo_->pxfModule(detid.rawId()); +} + +// Taken from TrackerTopology +int SiPixelCoordinates::layer(const DetId& detid) { + if (layer_.count(detid.rawId())) return layer_[detid.rawId()]; + if (!isBPix_(detid)) return layer_[detid.rawId()] = -9999; + return layer_[detid.rawId()] = tTopo_->pxbLayer(detid); +} + +// Taken from pixel naming class for barrel +int SiPixelCoordinates::sector(const DetId& detid) { + if (sector_.count(detid.rawId())) return sector_[detid.rawId()]; + if (!isBPix_(detid)) return sector_[detid.rawId()] = -9999; + return sector_[detid.rawId()] = PixelBarrelName(detid, tTopo_, phase_).sectorName(); +} + +// Offline ladder convention taken from TrackerTopology +int SiPixelCoordinates::ladder(const DetId& detid) { + if (ladder_.count(detid.rawId())) return ladder_[detid.rawId()]; + if (!isBPix_(detid)) return ladder_[detid.rawId()] = -9999; + return ladder_[detid.rawId()] = tTopo_->pxbLadder(detid); +} + +// Online ladder convention taken from pixel naming class for barrel +// Apply sign convention (- sign for BmO and BpO) +int SiPixelCoordinates::signed_ladder(const DetId& detid) { + if (signed_ladder_.count(detid.rawId())) return signed_ladder_[detid.rawId()]; + if (!isBPix_(detid)) return signed_ladder_[detid.rawId()] = -9999; + int signed_ladder = PixelBarrelName(detid, tTopo_, phase_).ladderName(); + if (quadrant(detid)%2) signed_ladder *= -1; + return signed_ladder_[detid.rawId()] = signed_ladder; +} + +// Online mdoule convention taken from pixel naming class for barrel +// Apply sign convention (- sign for BmO and BmI) +int SiPixelCoordinates::signed_module(const DetId& detid) { + if (signed_module_.count(detid.rawId())) return signed_module_[detid.rawId()]; + if (!isBPix_(detid)) return signed_module_[detid.rawId()] = -9999; + int signed_module = PixelBarrelName(detid, tTopo_, phase_).moduleName(); + if (quadrant(detid)<3) signed_module *= -1; + return signed_module_[detid.rawId()] = signed_module; +} + +// Half ladders taken from pixel naming class +int SiPixelCoordinates::half(const DetId& detid) { + if (half_.count(detid.rawId())) return half_[detid.rawId()]; + if (!isBPix_(detid)) return half_[detid.rawId()] = -9999; + return half_[detid.rawId()] = PixelBarrelName(detid, tTopo_, phase_).isHalfModule(); +} + +// Using TrackerTopology +// Ladders have a staggered structure +// Non-flipped ladders are on the outer radius +// Phase 0: Outer ladders are odd for layer 1,3 and even for layer 2 +// Phase 1: Outer ladders are odd for layer 4 and even for layer 1,2,3 +int SiPixelCoordinates::outer(const DetId& detid) { + if (outer_.count(detid.rawId())) return outer_[detid.rawId()]; + if (!isBPix_(detid)) return outer_[detid.rawId()] = -9999; + int outer = -9999; + int layer = tTopo_->pxbLayer(detid.rawId()); + bool odd_ladder = tTopo_->pxbLadder(detid.rawId())%2; + if (phase_ == 0) { + if (layer==2) outer = !odd_ladder; + else outer = odd_ladder; + } else if (phase_ == 1) { + if (layer==4) outer = odd_ladder; + else outer = !odd_ladder; + } + return outer_[detid.rawId()] = outer; +} + +// Using outer() method +// We call ladders in the inner radius flipped (see above) +int SiPixelCoordinates::flipped(const DetId& detid) { + if (flipped_.count(detid.rawId())) return flipped_[detid.rawId()]; + if (!isBPix_(detid)) return flipped_[detid.rawId()] = -9999; + int flipped = -9999; + if (phase_ < 2) flipped = outer(detid)==0; + return flipped_[detid.rawId()] = flipped; +} + +// Offline disk convention taken from TrackerTopology +int SiPixelCoordinates::disk(const DetId& detid) { + if (disk_.count(detid.rawId())) return disk_[detid.rawId()]; + if (!isFPix_(detid)) return disk_[detid.rawId()] = -9999; + return disk_[detid.rawId()] = tTopo_->pxfDisk(detid); +} + +// Online disk convention +// Apply sign convention (- sign for BmO and BmI) +int SiPixelCoordinates::signed_disk(const DetId& detid) { + if (signed_disk_.count(detid.rawId())) return signed_disk_[detid.rawId()]; + if (!isFPix_(detid)) return signed_disk_[detid.rawId()] = -9999; + int signed_disk = disk(detid); + if (quadrant(detid)<3) signed_disk *= -1; + return signed_disk_[detid.rawId()] = signed_disk; +} + +// Taken from TrackerTopology +int SiPixelCoordinates::panel(const DetId& detid) { + if (panel_.count(detid.rawId())) return panel_[detid.rawId()]; + if (!isFPix_(detid)) return panel_[detid.rawId()] = -9999; + return panel_[detid.rawId()] = tTopo_->pxfPanel(detid); +} + +// Phase 0: Ring was not an existing convention +// but the 7 plaquettes were split by HV group +// --> Derive Ring 1/2 for them +// Panel 1 plq 1-2, Panel 2, plq 1 = Ring 1 +// Panel 1 plq 3-4, Panel 2, plq 2-3 = Ring 2 +// Phase 1: Using pixel naming class for endcap +int SiPixelCoordinates::ring(const DetId& detid) { + if (ring_.count(detid.rawId())) return ring_[detid.rawId()]; + if (!isFPix_(detid)) return ring_[detid.rawId()] = -9999; + int ring = -9999; + if (phase_==0) { + ring = 1 + (panel(detid)+module(detid)>3); + } else if (phase_==1) { + ring = PixelEndcapName(detid, tTopo_, phase_).ringName(); + } + return ring_[detid.rawId()] = ring; +} + +// Offline blade convention taken from TrackerTopology +int SiPixelCoordinates::blade(const DetId& detid) { + if (blade_.count(detid.rawId())) return blade_[detid.rawId()]; + if (!isFPix_(detid)) return blade_[detid.rawId()] = -9999; + return blade_[detid.rawId()] = tTopo_->pxfBlade(detid); +} + +// Online blade convention taken from pixel naming class for endcap +// Apply sign convention (- sign for BmO and BpO) +int SiPixelCoordinates::signed_blade(const DetId& detid) { + if (signed_blade_.count(detid.rawId())) return signed_blade_[detid.rawId()]; + if (!isFPix_(detid)) return signed_blade_[detid.rawId()] = -9999; + int signed_blade = PixelEndcapName(detid, tTopo_, phase_).bladeName(); + if (quadrant(detid)%2) signed_blade *= -1; + return signed_blade_[detid.rawId()] = signed_blade; +} + +// Get the FED number using the cabling map +unsigned int SiPixelCoordinates::fedid(const DetId& detid) { + if (fedid_.count(detid.rawId())) return fedid_[detid.rawId()]; + if (!isPixel_(detid)) return fedid_[detid.rawId()] = 9999; + unsigned int fedid = 9999; + for(auto& fedId : cablingMap_->fedIds()) { + if(SiPixelFrameConverter(cablingMap_, fedId).hasDetUnit(detid.rawId())) { + fedid=fedId; + break; + } + } + return fedid_[detid.rawId()] = fedid; +} + + +// _________________________________________________________ +// Private methods +bool SiPixelCoordinates::isPixel_(const DetId& detid) { + if (detid.det() != DetId::Tracker) return false; + if (detid.subdetId() == PixelSubdetector::PixelBarrel) return true; + if (detid.subdetId() == PixelSubdetector::PixelEndcap) return true; + return false; +} +bool SiPixelCoordinates::isBPix_(const DetId& detid) { + if (detid.det() != DetId::Tracker) return false; + if (detid.subdetId() == PixelSubdetector::PixelBarrel) return true; + return false; +} +bool SiPixelCoordinates::isFPix_(const DetId& detid) { + if (detid.det() != DetId::Tracker) return false; + if (detid.subdetId() == PixelSubdetector::PixelEndcap) return true; + return false; +} + +std::pair SiPixelCoordinates::pixel_(const PixelDigi* digi) { + return std::make_pair(digi->row(), digi->column()); +} +std::pair SiPixelCoordinates::pixel_(const SiPixelCluster* cluster) { + // Cluster positions are already shifted by 0.5 + // We remove this and add back later (for all pixels) + // The aim is to get the offline row/col number of the pixel + int row = cluster->x()-0.5, col = cluster->y()-0.5; + return std::make_pair(row, col); +} +std::pair SiPixelCoordinates::pixel_(const SiPixelRecHit* rechit) { + // Convert RecHit local position to local pixel using Topology + const PixelGeomDetUnit* detUnit = static_cast(rechit->detUnit()); + const PixelTopology* topo = static_cast(&detUnit->specificTopology()); + std::pair pixel = topo->pixel(rechit->localPosition()); + // We could leave it like this, but it's better to constrain pixel to be on the module + // Also truncate floating point to int (similar to digis) + int row = std::max(0, std::min(topo->nrows()-1, (int)pixel.first)); + int col = std::max(0, std::min(topo->ncolumns()-1, (int)pixel.second)); + return std::make_pair(row, col); +} + +float SiPixelCoordinates::xcoord_on_module_(const DetId& detid, const std::pair& pixel) { + int nrows = 160; + // Leave it hard-coded for phase 0/1, read from geometry for phase 2 + // no special treatment needed here for phase 0 1x8, 1x5 and 1x2 modules either + // because we do not want to scale coordinates (only shift if needed) + if (phase_==2) { + const PixelGeomDetUnit* detUnit = static_cast(tGeom_->idToDetUnit(detid)); + const PixelTopology* topo = static_cast(&detUnit->specificTopology()); + nrows = topo->nrows(); + } + // Shift to the middle of the pixel, for precision binning + return (pixel.first+0.5)/nrows; +} + +float SiPixelCoordinates::ycoord_on_module_(const DetId& detid, const std::pair& pixel) { + int ncols = 416; + // Leave it hard-coded for phase 0/1, read from geometry for phase 2 + if (phase_==2) { + const PixelGeomDetUnit* detUnit = static_cast(tGeom_->idToDetUnit(detid)); + const PixelTopology* topo = static_cast(&detUnit->specificTopology()); + ncols = topo->ncolumns(); + } + else if (phase_==0 && isFPix_(detid)) { + // Always use largest length for Phase 0 FPix modules (1x5 and 2x5) + // because we do not want to scale coordinates so ROC size remains fixed + // and only shifts are needed + ncols = 260; + } + // Shift to the middle of the pixel, for precision binning + return (pixel.second+0.5)/ncols; +} + +// _________________________________________________________ +// Online Link and ROC number + +// Get the FED channel (link) number +// Link may depend on the TBM side of the module +// so pixel location is needed +// Using the cabling map works for all detectors +// Taken from DQM/SiPixelMonitorClient/src/SiPixelInformationExtractor.cc +int SiPixelCoordinates::channel(const DetId& detid, const std::pair& pixel) { + if (!isPixel_(detid)) return -9999; + // The method below may be slow when looping on a lot of pixels, so let's try to speed it up + // by quickly chategorizing pixels to ROC coordinates inside det units + int rowsperroc = 80, colsperroc = 52; + if (phase_==2) { + // Can get roc info from Geometry for Phase 2, this will need to be specified when it's final + const PixelGeomDetUnit* detUnit = static_cast(tGeom_->idToDetUnit(detid)); + const PixelTopology* topo = static_cast(&detUnit->specificTopology()); + rowsperroc = topo->rowsperroc(); + colsperroc = topo->colsperroc(); + } + // It is unlikely a ROC would have more than 256 chips, so let's use this formula + // If a ROC number was ever found, then binary search in a map will be much quicker + uint64_t pseudo_roc_num = uint64_t(1<<16) * detid.rawId() + (1<<8) * (pixel.first/rowsperroc) + pixel.second/colsperroc; + if (channel_.count(pseudo_roc_num)) return channel_[pseudo_roc_num]; + // If not found previously, get the channel number + unsigned int fedId = fedid(detid); + SiPixelFrameConverter converter(cablingMap_, fedId); + sipixelobjects::DetectorIndex detector = { detid.rawId(), pixel.first, pixel.second }; + sipixelobjects::ElectronicIndex cabling; + converter.toCabling(cabling, detector); + // Time consuming part is over, so let's save the roc number too + const sipixelobjects::PixelROC *theRoc = converter.toRoc(cabling.link, cabling.roc); + int roc = theRoc->idInDetUnit(); + if (detid.subdetId() == PixelSubdetector::PixelBarrel && side(detid)==1 && half(detid)) roc += 8; + roc_[pseudo_roc_num] = roc; + //printf ("Online FED, LNK, LNKID, ROC: %2d %2d %2d %2d - Offline RAWID, ROW, COL: %9d [%3d,%3d] [%3d,%3d]\n", + // fedId, cabling.link, cabling.roc, roc, detid.rawId(), + // (pixel.first /rowsperroc)*rowsperroc, (pixel.first /rowsperroc+1)*rowsperroc-1, + // (pixel.second/colsperroc)*colsperroc, (pixel.second/colsperroc+1)*colsperroc-1); + return channel_[pseudo_roc_num] = cabling.link; +} +int SiPixelCoordinates::channel(const DetId& detid, const PixelDigi* digi) { + if (!isPixel_(detid)) return -9999; + return channel(detid, pixel_(digi)); +} +int SiPixelCoordinates::channel(const DetId& detid, const SiPixelCluster* cluster) { + if (!isPixel_(detid)) return -9999; + return channel(detid, pixel_(cluster)); +} +int SiPixelCoordinates::channel(const SiPixelRecHit* rechit) { + if (!isPixel_(rechit->geographicalId())) return -9999; + return channel(rechit->geographicalId(), pixel_(rechit)); +} +int SiPixelCoordinates::channel(const TrackingRecHit* rechit) { + if (!isPixel_(rechit->geographicalId())) return -9999; + return channel(static_cast(rechit->hit())); +} + + +// Using the cabling map works for all detectors +// Taken from DQM/SiPixelMonitorClient/src/SiPixelInformationExtractor.cc +// Although using coordinates (only available for Phase 0/1) is much faster +// The advantage is very visible when running on smaller statistics +// because the map will speed it up greatly after high enough ROCs were sampled +// The coordinate method is validated to give the same result as the cabling map +// Example for the barrel: +// ROC number is read out in a U shape from ROC 0 to 15 (or maxroc) +// row [80-159] col [0-51] is always ROC 0 on the +Z side of the barrel +// Both coordinates are mirrored on the -Z side (180 deg rotation effectively) +// -Z 8 9 10 11 12 13 14 15 +Z 0 1 2 3 4 5 6 7 +// (0,0) 7 6 5 4 3 2 1 0 (0,0) 15 14 13 12 11 10 9 8 +// Half modules on the -Z side should consider the second row of ROCs instead, etc. see below +int SiPixelCoordinates::roc(const DetId& detid, const std::pair& pixel) { + if (!isPixel_(detid)) return -9999; + // The method below may be slow when looping on a lot of pixels, so let's try to speed it up + // by quickly chategorizing pixels to ROC coordinates inside det units + int rowsperroc = 80, colsperroc = 52; + if (phase_==2) { + // Can get roc info from Geometry for Phase 2, this will need to be specified when it's final + const PixelGeomDetUnit* detUnit = static_cast(tGeom_->idToDetUnit(detid)); + const PixelTopology* topo = static_cast(&detUnit->specificTopology()); + rowsperroc = topo->rowsperroc(); + colsperroc = topo->colsperroc(); + } + // It is unlikely a ROC would have more than 256 chips, so let's use this formula + // If a ROC number was ever found, then binary search in a map will be much quicker + uint64_t pseudo_roc_num = uint64_t(1<<16) * detid.rawId() + (1<<8) * (pixel.first/rowsperroc) + pixel.second/colsperroc; + if (roc_.count(pseudo_roc_num)) return roc_[pseudo_roc_num]; + // If not found previously, get the ROC number + int roc = -9999; + // Use the Fed Cabling Map if specified by the bool + // or if using channel number too, or if it's the Phase 2 detector + if (phase_==2||channel_.size()) { + unsigned int fedId = fedid(detid); + SiPixelFrameConverter converter(cablingMap_, fedId); + sipixelobjects::DetectorIndex detector = { detid.rawId(), pixel.first, pixel.second }; + sipixelobjects::ElectronicIndex cabling; + converter.toCabling(cabling, detector); + // Time consuming part is over, so let's save the channel number too + channel_[pseudo_roc_num] = cabling.link; + const sipixelobjects::PixelROC *theRoc = converter.toRoc(cabling.link, cabling.roc); + int roc = theRoc->idInDetUnit(); + if (detid.subdetId() == PixelSubdetector::PixelBarrel && side(detid)==1 && half(detid)) roc += 8; + //printf ("Online FED, LNK, LNKID, ROC: %2d %2d %2d %2d - Offline RAWID, ROW, COL: %9d [%3d,%3d] [%3d,%3d]\n", + // fedId, cabling.link, cabling.roc, roc, detid.rawId(), + // (pixel.first /rowsperroc)*rowsperroc, (pixel.first /rowsperroc+1)*rowsperroc-1, + // (pixel.second/colsperroc)*colsperroc, (pixel.second/colsperroc+1)*colsperroc-1); + } else if (phase_<2) { + // This method is faster if only ROC number is needed + int pan = panel(detid), mod = module(detid), rocsY = 8; + if (phase_==0&&detid.subdetId() == PixelSubdetector::PixelEndcap) rocsY = pan+mod; + int rocX = pixel.first/rowsperroc, rocY = pixel.second/colsperroc; + // Consider second row for all 1xN Phase 0 modules + if (phase_==0) { + int v1x8 = half(detid)==1, v1x2 = (pan==1&&mod==1), v1x5 = (pan==1&&mod==4); + if (v1x8||v1x2||v1x5) ++rocX; + } + // Mirror both coordinates for barrel -Z side + // and for endcap (but only Panel 2 for Phase 0) + if ( (detid.subdetId() == PixelSubdetector::PixelBarrel && side(detid)==1) || + (detid.subdetId() == PixelSubdetector::PixelEndcap && ((phase_==0 && pan==2)||phase_==1) ) ) { + rocX = 1-rocX; + rocY = rocsY-1 - rocY; + } + // U-shape readout order + roc = rocX ? rocY : 2*rocsY-1 - rocY; + } + return roc_[pseudo_roc_num] = roc; +} +int SiPixelCoordinates::roc(const DetId& detid, const PixelDigi* digi) { + if (!isPixel_(detid)) return -9999; + return roc(detid, pixel_(digi)); +} +int SiPixelCoordinates::roc(const DetId& detid, const SiPixelCluster* cluster) { + if (!isPixel_(detid)) return -9999; + return roc(detid, pixel_(cluster)); +} +int SiPixelCoordinates::roc(const SiPixelRecHit* rechit) { + if (!isPixel_(rechit->geographicalId())) return -9999; + return roc(rechit->geographicalId(), pixel_(rechit)); +} +int SiPixelCoordinates::roc(const TrackingRecHit* rechit) { + if (!isPixel_(rechit->geographicalId())) return -9999; + return roc(static_cast(rechit->hit())); +} + + +// _________________________________________________________ +// Floating point Pixel Coordinates similar to those +// given by TrackerTopology and naming classes +// but we add a shift within ]-0.5,+0.5[ +// eg. std::round(coord) gives back the original int +float SiPixelCoordinates::module_coord(const DetId& detid, const std::pair& pixel) { + if (!isBPix_(detid)) return -9999; + // offline module number is monotonously increasing with global z + // sign is negative because local y is antiparallel to global z + return module(detid) - (ycoord_on_module_(detid, pixel) - 0.5); +} +float SiPixelCoordinates::module_coord(const DetId& detid, const PixelDigi* digi) { + if (!isBPix_(detid)) return -9999; + return module_coord(detid, pixel_(digi)); +} +float SiPixelCoordinates::module_coord(const DetId& detid, const SiPixelCluster* cluster) { + if (!isBPix_(detid)) return -9999; + return module_coord(detid, pixel_(cluster)); +} +float SiPixelCoordinates::module_coord(const SiPixelRecHit* rechit) { + if (!isBPix_(rechit->geographicalId())) return -9999; + return module_coord(rechit->geographicalId(), pixel_(rechit)); +} +float SiPixelCoordinates::module_coord(const TrackingRecHit* rechit) { + if (!isBPix_(rechit->geographicalId())) return -9999; + return module_coord(static_cast(rechit->hit())); +} + + +float SiPixelCoordinates::signed_module_coord(const DetId& detid, const std::pair& pixel) { + if (!isBPix_(detid)) return -9999; + // offline module number is monotonously increasing with global z + // sign is negative because local y is antiparallel to global z + return signed_module(detid) - (ycoord_on_module_(detid, pixel) - 0.5); +} +float SiPixelCoordinates::signed_module_coord(const DetId& detid, const PixelDigi* digi) { + if (!isBPix_(detid)) return -9999; + return signed_module_coord(detid, pixel_(digi)); +} +float SiPixelCoordinates::signed_module_coord(const DetId& detid, const SiPixelCluster* cluster) { + if (!isBPix_(detid)) return -9999; + return signed_module_coord(detid, pixel_(cluster)); +} +float SiPixelCoordinates::signed_module_coord(const SiPixelRecHit* rechit) { + if (!isBPix_(rechit->geographicalId())) return -9999; + return signed_module_coord(rechit->geographicalId(), pixel_(rechit)); +} +float SiPixelCoordinates::signed_module_coord(const TrackingRecHit* rechit) { + if (!isBPix_(rechit->geographicalId())) return -9999; + return signed_module_coord(static_cast(rechit->hit())); +} + + +float SiPixelCoordinates::ladder_coord(const DetId& detid, const std::pair& pixel) { + if (!isBPix_(detid)) return -9999; + // offline ladder number is monotonously increasing with global phi + // flipped/inner ladders: lx parallel to global r-phi - positive sign + // non-flipped/outer ladders: lx anti-parallel to global r-phi - negative sign + int sign = flipped(detid) ? 1 : -1; + return ladder(detid) + sign * (xcoord_on_module_(detid, pixel) + half(detid)*0.5 - 0.5); +} +float SiPixelCoordinates::ladder_coord(const DetId& detid, const PixelDigi* digi) { + if (!isBPix_(detid)) return -9999; + return ladder_coord(detid, pixel_(digi)); +} +float SiPixelCoordinates::ladder_coord(const DetId& detid, const SiPixelCluster* cluster) { + if (!isBPix_(detid)) return -9999; + return ladder_coord(detid, pixel_(cluster)); +} +float SiPixelCoordinates::ladder_coord(const SiPixelRecHit* rechit) { + if (!isBPix_(rechit->geographicalId())) return -9999; + return ladder_coord(rechit->geographicalId(), pixel_(rechit)); +} +float SiPixelCoordinates::ladder_coord(const TrackingRecHit* rechit) { + if (!isBPix_(rechit->geographicalId())) return -9999; + return ladder_coord(static_cast(rechit->hit())); +} + + +float SiPixelCoordinates::signed_ladder_coord(const DetId& detid, const std::pair& pixel) { + if (!isBPix_(detid)) return -9999; + // online ladder number is monotonously decreasing with global phi + // flipped/inner ladders: lx parallel to global r-phi - negative sign + // non-flipped/outer ladders: lx anti-parallel to global r-phi - positive sign + int sign = flipped(detid) ? -1 : 1; + return signed_ladder(detid) + sign * (xcoord_on_module_(detid, pixel) + half(detid)*0.5 - 0.5); +} +float SiPixelCoordinates::signed_ladder_coord(const DetId& detid, const PixelDigi* digi) { + if (!isBPix_(detid)) return -9999; + return signed_ladder_coord(detid, pixel_(digi)); +} +float SiPixelCoordinates::signed_ladder_coord(const DetId& detid, const SiPixelCluster* cluster) { + if (!isBPix_(detid)) return -9999; + return signed_ladder_coord(detid, pixel_(cluster)); +} +float SiPixelCoordinates::signed_ladder_coord(const SiPixelRecHit* rechit) { + if (!isBPix_(rechit->geographicalId())) return -9999; + return signed_ladder_coord(rechit->geographicalId(), pixel_(rechit)); +} +float SiPixelCoordinates::signed_ladder_coord(const TrackingRecHit* rechit) { + if (!isBPix_(rechit->geographicalId())) return -9999; + return signed_ladder_coord(static_cast(rechit->hit())); +} + + +// Rings are defined in the radial direction +// which is local x for phase 0 and local y for phase 1 +// Rings were not defined for phase 0, but we had a similar +// convention, HV group, the 7 plaquettes were split like this +// Panel 1 plq 1-2, Panel 2, plq 1 = Ring 1 (HV grp 1) +// Panel 1 plq 3-4, Panel 2, plq 2-3 = Ring 2 (HV grp 2) +// A subdivision of 8 is suggested for both phase 0 and 1 +float SiPixelCoordinates::ring_coord(const DetId& detid, const std::pair& pixel) { + if (!isFPix_(detid)) return -9999; + float ring_coord = ring(detid), coord_shift = 0; + if (phase_==0) { + // local x on panel 1 is anti-parallel to global radius - sign is negative + // and parallel for panel 2 - sign is positive + int pan = panel(detid), mod = module(detid); + if (pan==1) { + if (mod==1) coord_shift = (-xcoord_on_module_(detid, pixel) )/4; + else if (mod==2) coord_shift = (-xcoord_on_module_(detid, pixel) + 2.0)/4; + else if (mod==3) coord_shift = (-xcoord_on_module_(detid, pixel) )/4; + else if (mod==4) coord_shift = (-xcoord_on_module_(detid, pixel) + 1.5)/4; + } else { + if (mod==1) coord_shift = ( xcoord_on_module_(detid, pixel) )/4; + else if (mod==2) coord_shift = ( xcoord_on_module_(detid, pixel) - 2.0)/4; + else if (mod==3) coord_shift = ( xcoord_on_module_(detid, pixel) )/4; + } + } else if (phase_==1) { + // local y is parallel to global radius, so sign is positive + coord_shift = ycoord_on_module_(detid, pixel) - 0.5; + } + ring_coord += coord_shift; + return ring_coord; +} +float SiPixelCoordinates::ring_coord(const DetId& detid, const PixelDigi* digi) { + if (!isFPix_(detid)) return -9999; + return ring_coord(detid, pixel_(digi)); +} +float SiPixelCoordinates::ring_coord(const DetId& detid, const SiPixelCluster* cluster) { + if (!isFPix_(detid)) return -9999; + return ring_coord(detid, pixel_(cluster)); +} +float SiPixelCoordinates::ring_coord(const SiPixelRecHit* rechit) { + if (!isFPix_(rechit->geographicalId())) return -9999; + return ring_coord(rechit->geographicalId(), pixel_(rechit)); +} +float SiPixelCoordinates::ring_coord(const TrackingRecHit* rechit) { + if (!isFPix_(rechit->geographicalId())) return -9999; + return ring_coord(static_cast(rechit->hit())); +} + + +// Treat disk number as it is (parallel to global z) +// Subdivisions on the forward can be the radial direction +// Which is local x for phase 0 and local y for phase 1 +// Closest radius is chosen to be closest to disk = 0 +// Rings are not separated, 8 subdivisions are suggested +// Plot suitable for separate ring plots +float SiPixelCoordinates::disk_coord(const DetId& detid, const std::pair& pixel) { + if (!isFPix_(detid)) return -9999; + float disk_coord = disk(detid), coord_shift = ring_coord(detid,pixel)-ring(detid); + disk_coord += coord_shift; + return disk_coord; +} +float SiPixelCoordinates::disk_coord(const DetId& detid, const PixelDigi* digi) { + if (!isFPix_(detid)) return -9999; + return disk_coord(detid, pixel_(digi)); +} +float SiPixelCoordinates::disk_coord(const DetId& detid, const SiPixelCluster* cluster) { + if (!isFPix_(detid)) return -9999; + return disk_coord(detid, pixel_(cluster)); +} +float SiPixelCoordinates::disk_coord(const SiPixelRecHit* rechit) { + if (!isFPix_(rechit->geographicalId())) return -9999; + return disk_coord(rechit->geographicalId(), pixel_(rechit)); +} +float SiPixelCoordinates::disk_coord(const TrackingRecHit* rechit) { + if (!isFPix_(rechit->geographicalId())) return -9999; + return disk_coord(static_cast(rechit->hit())); +} + + +// Same as above, but using online convention +// !!! Recommended for Phase 1 !!! +// Can be used for Phase 0 too for comparison purposes +float SiPixelCoordinates::signed_disk_coord(const DetId& detid, const std::pair& pixel) { + if (!isFPix_(detid)) return -9999; + float signed_disk_coord = signed_disk(detid), coord_shift = ring_coord(detid,pixel)-ring(detid); + // Mirror -z side, so plots are symmetric + if (signed_disk_coord<0) coord_shift = -coord_shift; + signed_disk_coord += coord_shift; + return signed_disk_coord; +} +float SiPixelCoordinates::signed_disk_coord(const DetId& detid, const PixelDigi* digi) { + if (!isFPix_(detid)) return -9999; + return signed_disk_coord(detid, pixel_(digi)); +} +float SiPixelCoordinates::signed_disk_coord(const DetId& detid, const SiPixelCluster* cluster) { + if (!isFPix_(detid)) return -9999; + return signed_disk_coord(detid, pixel_(cluster)); +} +float SiPixelCoordinates::signed_disk_coord(const SiPixelRecHit* rechit) { + if (!isFPix_(rechit->geographicalId())) return -9999; + return signed_disk_coord(rechit->geographicalId(), pixel_(rechit)); +} +float SiPixelCoordinates::signed_disk_coord(const TrackingRecHit* rechit) { + if (!isFPix_(rechit->geographicalId())) return -9999; + return signed_disk_coord(static_cast(rechit->hit())); +} + +// Same as the above two, but subdivisions incorporate rings as well +// 16 subdivisions are suggested +float SiPixelCoordinates::disk_ring_coord(const DetId& detid, const std::pair& pixel) { + if (!isFPix_(detid)) return -9999; + float disk_ring_coord = disk(detid), coord_shift = 0; + //if (phase_==0) coord_shift = (ring_coord(detid,pixel) - 1.625) / 1.5; + //else if (phase_==1) coord_shift = (ring_coord(detid,pixel) - 1.5 ) / 2.0; + coord_shift = (ring_coord(detid,pixel) - 1.5 ) / 2.0; + disk_ring_coord += coord_shift; + return disk_ring_coord; +} +float SiPixelCoordinates::disk_ring_coord(const DetId& detid, const PixelDigi* digi) { + if (!isFPix_(detid)) return -9999; + return disk_ring_coord(detid, pixel_(digi)); +} +float SiPixelCoordinates::disk_ring_coord(const DetId& detid, const SiPixelCluster* cluster) { + if (!isFPix_(detid)) return -9999; + return disk_ring_coord(detid, pixel_(cluster)); +} +float SiPixelCoordinates::disk_ring_coord(const SiPixelRecHit* rechit) { + if (!isFPix_(rechit->geographicalId())) return -9999; + return disk_ring_coord(rechit->geographicalId(), pixel_(rechit)); +} +float SiPixelCoordinates::disk_ring_coord(const TrackingRecHit* rechit) { + if (!isFPix_(rechit->geographicalId())) return -9999; + return disk_ring_coord(static_cast(rechit->hit())); +} + + +// Same as above, but using online convention +// !!! Recommended for Phase 0 !!! +float SiPixelCoordinates::signed_disk_ring_coord(const DetId& detid, const std::pair& pixel) { + if (!isFPix_(detid)) return -9999; + float signed_disk_ring_coord = signed_disk(detid), coord_shift = 0; + //if (phase_==0) coord_shift = (ring_coord(detid,pixel) - 1.625) / 1.5; + //else if (phase_==1) coord_shift = (ring_coord(detid,pixel) - 1.5 ) / 2.0; + coord_shift = (ring_coord(detid,pixel) - 1.5 ) / 2.0; + // Mirror -z side, so plots are symmetric + if (signed_disk_ring_coord<0) coord_shift = -coord_shift; + signed_disk_ring_coord += coord_shift; + return signed_disk_ring_coord; +} +float SiPixelCoordinates::signed_disk_ring_coord(const DetId& detid, const PixelDigi* digi) { + if (!isFPix_(detid)) return -9999; + return signed_disk_ring_coord(detid, pixel_(digi)); +} +float SiPixelCoordinates::signed_disk_ring_coord(const DetId& detid, const SiPixelCluster* cluster) { + if (!isFPix_(detid)) return -9999; + return signed_disk_ring_coord(detid, pixel_(cluster)); +} +float SiPixelCoordinates::signed_disk_ring_coord(const SiPixelRecHit* rechit) { + if (!isFPix_(rechit->geographicalId())) return -9999; + return signed_disk_ring_coord(rechit->geographicalId(), pixel_(rechit)); +} +float SiPixelCoordinates::signed_disk_ring_coord(const TrackingRecHit* rechit) { + if (!isFPix_(rechit->geographicalId())) return -9999; + return signed_disk_ring_coord(static_cast(rechit->hit())); +} + + +// Offline blade convention +// Blade number is parallel to global phi +// For Phase 0: local y is parallel with phi +// On +Z side ly is parallel with phi +// On -Z side ly is anti-parallel +// Phase 1: local x is parallel with phi +// +Z Panel 1, -Z Panel 2 is parallel +// +Z Panel 2, -Z Panel 1 is anti-parallel +// Plot suitable for separate panel 1/2 plots +// 10 subdivisions are recommended for Phase 0 (Half-ROC granularity) +// 2 for Phase 1 +float SiPixelCoordinates::blade_coord(const DetId& detid, const std::pair& pixel) { + if (!isFPix_(detid)) return -9999; + float blade_coord = blade(detid), coord_shift = 0; + if (phase_==0) { + int rocsY = panel(detid)+module(detid); + coord_shift = ycoord_on_module_(detid, pixel) - rocsY/10.; + if (side(detid)==1) coord_shift = -coord_shift; + } else if (phase_==1) { + coord_shift = xcoord_on_module_(detid, pixel) - 0.5; + if ((side(detid)+panel(detid))%2==0) coord_shift = -coord_shift; + } + blade_coord += coord_shift; + return blade_coord; +} +float SiPixelCoordinates::blade_coord(const DetId& detid, const PixelDigi* digi) { + if (!isFPix_(detid)) return -9999; + return blade_coord(detid, pixel_(digi)); +} +float SiPixelCoordinates::blade_coord(const DetId& detid, const SiPixelCluster* cluster) { + if (!isFPix_(detid)) return -9999; + return blade_coord(detid, pixel_(cluster)); +} +float SiPixelCoordinates::blade_coord(const SiPixelRecHit* rechit) { + if (!isFPix_(rechit->geographicalId())) return -9999; + return blade_coord(rechit->geographicalId(), pixel_(rechit)); +} +float SiPixelCoordinates::blade_coord(const TrackingRecHit* rechit) { + if (!isFPix_(rechit->geographicalId())) return -9999; + return blade_coord(static_cast(rechit->hit())); +} + + +// Online blade convention +// Blade number is anti-parallel to global phi +// so signs are the opposite as above +// Plot suitable for separate panel 1/2 plots +// 10 subdivisions are recommended for Phase 0 (Half-ROC granularity) +// 2 for Phase 1 +// !!! Recommended for Phase 0 ||| +float SiPixelCoordinates::signed_blade_coord(const DetId& detid, const std::pair& pixel) { + if (!isFPix_(detid)) return -9999; + float signed_blade_coord = signed_blade(detid), coord_shift = 0; + if (phase_==0) { + int rocsY = panel(detid)+module(detid); + coord_shift = ycoord_on_module_(detid, pixel) - rocsY/10.; + if (side(detid)==2) coord_shift = -coord_shift; + } else if (phase_==1) { + coord_shift = xcoord_on_module_(detid, pixel) - 0.5; + if ((side(detid)+panel(detid))%2==1) coord_shift = -coord_shift; + } + signed_blade_coord += coord_shift; + return signed_blade_coord; +} +float SiPixelCoordinates::signed_blade_coord(const DetId& detid, const PixelDigi* digi) { + if (!isFPix_(detid)) return -9999; + return signed_blade_coord(detid, pixel_(digi)); +} +float SiPixelCoordinates::signed_blade_coord(const DetId& detid, const SiPixelCluster* cluster) { + if (!isFPix_(detid)) return -9999; + return signed_blade_coord(detid, pixel_(cluster)); +} +float SiPixelCoordinates::signed_blade_coord(const SiPixelRecHit* rechit) { + if (!isFPix_(rechit->geographicalId())) return -9999; + return signed_blade_coord(rechit->geographicalId(), pixel_(rechit)); +} +float SiPixelCoordinates::signed_blade_coord(const TrackingRecHit* rechit) { + if (!isFPix_(rechit->geographicalId())) return -9999; + return signed_blade_coord(static_cast(rechit->hit())); +} + + +// Offline blade convention + alternating panels +// Same as above two, but subdivisions incorporate panels +// Panel 2 is towards higher phi values for Phase 1 (overlap for phase 0) +// 20 subdivisions are recommended for Phase 0 (Half-ROC granularity) +// 4 for Phase 1 +float SiPixelCoordinates::blade_panel_coord(const DetId& detid, const std::pair& pixel) { + if (!isFPix_(detid)) return -9999; + float blade_panel_coord = blade(detid); + float coord_shift = (blade_coord(detid, pixel) - blade_panel_coord + panel(detid) - 1.5)/2; + blade_panel_coord += coord_shift; + return blade_panel_coord; +} +float SiPixelCoordinates::blade_panel_coord(const DetId& detid, const PixelDigi* digi) { + if (!isFPix_(detid)) return -9999; + return blade_panel_coord(detid, pixel_(digi)); +} +float SiPixelCoordinates::blade_panel_coord(const DetId& detid, const SiPixelCluster* cluster) { + if (!isFPix_(detid)) return -9999; + return blade_panel_coord(detid, pixel_(cluster)); +} +float SiPixelCoordinates::blade_panel_coord(const SiPixelRecHit* rechit) { + if (!isFPix_(rechit->geographicalId())) return -9999; + return blade_panel_coord(rechit->geographicalId(), pixel_(rechit)); +} +float SiPixelCoordinates::blade_panel_coord(const TrackingRecHit* rechit) { + if (!isFPix_(rechit->geographicalId())) return -9999; + return blade_panel_coord(static_cast(rechit->hit())); +} + + +// Online blade convention + alternating panels +// Blade number is anti-parallel to global phi +// so signs are the opposite as above +// 20 subdivisions are recommended for Phase 0 (Half-ROC granularity) +// 4 for Phase 1 +// !!! Recommended for Phase 1 !!! +float SiPixelCoordinates::signed_blade_panel_coord(const DetId& detid, const std::pair& pixel) { + if (!isFPix_(detid)) return -9999; + float signed_blade_panel_coord = signed_blade(detid); + float coord_shift = (signed_blade_coord(detid, pixel) - signed_blade_panel_coord - panel(detid) + 1.5)/2; + signed_blade_panel_coord += coord_shift; + return signed_blade_panel_coord; +} +float SiPixelCoordinates::signed_blade_panel_coord(const DetId& detid, const PixelDigi* digi) { + if (!isFPix_(detid)) return -9999; + return signed_blade_panel_coord(detid, pixel_(digi)); +} +float SiPixelCoordinates::signed_blade_panel_coord(const DetId& detid, const SiPixelCluster* cluster) { + if (!isFPix_(detid)) return -9999; + return signed_blade_panel_coord(detid, pixel_(cluster)); +} +float SiPixelCoordinates::signed_blade_panel_coord(const SiPixelRecHit* rechit) { + if (!isFPix_(rechit->geographicalId())) return -9999; + return signed_blade_panel_coord(rechit->geographicalId(), pixel_(rechit)); +} +float SiPixelCoordinates::signed_blade_panel_coord(const TrackingRecHit* rechit) { + if (!isFPix_(rechit->geographicalId())) return -9999; + return signed_blade_panel_coord(static_cast(rechit->hit())); +} + + +// Same as above, but blade numbers are shifted for Phase 1 Ring 1 +// so one can plot Ring1+Ring2 while conserving geometrical +// overlaps in phi +// Ring 2: 17 blades x 4 ROC --> 68 bin +// Ring 1: 2 gap, 4 ROC, alternating for 11 blades --> 68 bin +float SiPixelCoordinates::signed_shifted_blade_panel_coord(const DetId& detid, const std::pair& pixel) { + if (!isFPix_(detid)) return -9999; + float signed_shifted_blade_panel_coord = signed_blade(detid); + float coord_shift = (signed_blade_coord(detid, pixel) - signed_shifted_blade_panel_coord - panel(detid) + 1.5)/2; + if (phase_==1&&ring(detid)==1) signed_shifted_blade_panel_coord *= 1.5; + signed_shifted_blade_panel_coord += coord_shift; + return signed_shifted_blade_panel_coord; +} +float SiPixelCoordinates::signed_shifted_blade_panel_coord(const DetId& detid, const PixelDigi* digi) { + if (!isFPix_(detid)) return -9999; + return signed_shifted_blade_panel_coord(detid, pixel_(digi)); +} +float SiPixelCoordinates::signed_shifted_blade_panel_coord(const DetId& detid, const SiPixelCluster* cluster) { + if (!isFPix_(detid)) return -9999; + return signed_shifted_blade_panel_coord(detid, pixel_(cluster)); +} +float SiPixelCoordinates::signed_shifted_blade_panel_coord(const SiPixelRecHit* rechit) { + if (!isFPix_(rechit->geographicalId())) return -9999; + return signed_shifted_blade_panel_coord(rechit->geographicalId(), pixel_(rechit)); +} +float SiPixelCoordinates::signed_shifted_blade_panel_coord(const TrackingRecHit* rechit) { + if (!isFPix_(rechit->geographicalId())) return -9999; + return signed_shifted_blade_panel_coord(static_cast(rechit->hit())); +} diff --git a/DQM/SiPixelPhase1Config/python/SiPixelPhase1OfflineDQM_harvesting_cff.py b/DQM/SiPixelPhase1Config/python/SiPixelPhase1OfflineDQM_harvesting_cff.py index d6a13ad7c72ec..a64ff4296dc57 100644 --- a/DQM/SiPixelPhase1Config/python/SiPixelPhase1OfflineDQM_harvesting_cff.py +++ b/DQM/SiPixelPhase1Config/python/SiPixelPhase1OfflineDQM_harvesting_cff.py @@ -2,12 +2,14 @@ from DQM.SiPixelPhase1Config.SiPixelPhase1OfflineDQM_source_cff import * -siPixelPhase1OfflineDQM_harvesting = cms.Sequence(SiPixelPhase1DigisHarvester +siPixelPhase1OfflineDQM_harvesting = cms.Sequence(SiPixelPhase1RawDataHarvester + + SiPixelPhase1DigisHarvester + SiPixelPhase1ClustersHarvester + SiPixelPhase1RecHitsHarvester + SiPixelPhase1TrackResidualsHarvester + SiPixelPhase1TrackClustersHarvester + SiPixelPhase1TrackEfficiencyHarvester + + SiPixelPhase1RawDataHarvester ) siPixelPhase1OfflineDQM_harvesting_cosmics = siPixelPhase1OfflineDQM_harvesting.copyAndExclude([ diff --git a/DQM/SiPixelPhase1Config/python/SiPixelPhase1OfflineDQM_source_cff.py b/DQM/SiPixelPhase1Config/python/SiPixelPhase1OfflineDQM_source_cff.py index 4b4db718bba5b..17e388a807ca7 100644 --- a/DQM/SiPixelPhase1Config/python/SiPixelPhase1OfflineDQM_source_cff.py +++ b/DQM/SiPixelPhase1Config/python/SiPixelPhase1OfflineDQM_source_cff.py @@ -1,5 +1,7 @@ import FWCore.ParameterSet.Config as cms +# Raw data +from DQM.SiPixelPhase1RawData.SiPixelPhase1RawData_cfi import * # Pixel Digi Monitoring from DQM.SiPixelPhase1Digis.SiPixelPhase1Digis_cfi import * # Cluster (track-independent) monitoring @@ -12,15 +14,20 @@ from DQM.SiPixelPhase1TrackClusters.SiPixelPhase1TrackClusters_cfi import * # Hit Efficiencies from DQM.SiPixelPhase1TrackEfficiency.SiPixelPhase1TrackEfficiency_cfi import * +# FED/RAW Data +from DQM.SiPixelPhase1RawData.SiPixelPhase1RawData_cfi import * + PerModule.enabled = False -siPixelPhase1OfflineDQM_source = cms.Sequence(SiPixelPhase1DigisAnalyzer +siPixelPhase1OfflineDQM_source = cms.Sequence(SiPixelPhase1RawDataAnalyzer + + SiPixelPhase1DigisAnalyzer + SiPixelPhase1ClustersAnalyzer + SiPixelPhase1RecHitsAnalyzer + SiPixelPhase1TrackResidualsAnalyzer + SiPixelPhase1TrackClustersAnalyzer + SiPixelPhase1TrackEfficiencyAnalyzer + + SiPixelPhase1RawDataAnalyzer ) siPixelPhase1OfflineDQM_source_cosmics = siPixelPhase1OfflineDQM_source.copyAndExclude([ diff --git a/DQM/SiPixelPhase1Config/python/SiPixelPhase1OnlineDQM_cff.py b/DQM/SiPixelPhase1Config/python/SiPixelPhase1OnlineDQM_cff.py index 75b77d160173a..355e0655efece 100644 --- a/DQM/SiPixelPhase1Config/python/SiPixelPhase1OnlineDQM_cff.py +++ b/DQM/SiPixelPhase1Config/python/SiPixelPhase1OnlineDQM_cff.py @@ -2,60 +2,65 @@ from DQM.SiPixelPhase1Common.HistogramManager_cfi import * -StandardSpecifications1D.append( - Specification(PerLayer1D).groupBy("PXBarrel/PXLayer/OnlineBlock") # per-layer with history for online - .groupBy("PXBarrel/PXLayer", "EXTEND_Y") - .save() -) - -StandardSpecifications1D.append( - Specification(PerLayer1D).groupBy("PXForward/PXDisk/OnlineBlock") # per-layer with history for online - .groupBy("PXForward/PXDisk", "EXTEND_Y") - .save() -) - -StandardSpecifications1D.append( - Specification().groupBy("PXBarrel/OnlineBlock") # per-layer with history for online - .groupBy("PXBarrel", "EXTEND_Y") - .save() -) -StandardSpecifications1D.append( - Specification().groupBy("PXForward/OnlineBlock") # per-layer with history for online - .groupBy("PXForward", "EXTEND_Y") - .save() -) - -StandardSpecifications1D_Num.append( - Specification(PerLayer1D).groupBy("PXBarrel/PXLayer/OnlineBlock/DetId/Event") # per-layer with history for online - .reduce("COUNT") - .groupBy("PXBarrel/PXLayer/OnlineBlock") - .groupBy("PXBarrel/PXLayer", "EXTEND_Y") - .save() -) -StandardSpecifications1D_Num.append( - Specification(PerLayer1D).groupBy("PXForward/PXDisk/OnlineBlock/DetId/Event") # per-layer with history for online - .reduce("COUNT") - .groupBy("PXForward/PXDisk/OnlineBlock") - .groupBy("PXForward/PXDisk", "EXTEND_Y") - .save() -) -StandardSpecifications1D_Num.append( - Specification().groupBy("PXBarrel/OnlineBlock/DetId/Event") # per-layer with history for online - .reduce("COUNT") - .groupBy("PXBarrel/OnlineBlock") - .groupBy("PXBarrel", "EXTEND_Y") - .save() -) -StandardSpecifications1D_Num.append( - Specification().groupBy("PXForward/OnlineBlock/DetId/Event") # per-layer with history for online - .reduce("COUNT") - .groupBy("PXForward/OnlineBlock") - .groupBy("PXForward", "EXTEND_Y") - .save() -) - +SuperimoposePlotsInOnlineBlocks=False + +if SuperimoposePlotsInOnlineBlocks: #if someone wants to enble/disable the superimposed plots can switch them off with the bool above + + StandardSpecifications1D.append( + Specification(PerLayer1D).groupBy("PXBarrel/PXLayer/OnlineBlock") # per-layer with history for online + .groupBy("PXBarrel/PXLayer", "EXTEND_Y") + .save() + ) + + StandardSpecifications1D.append( + Specification(PerLayer1D).groupBy("PXForward/PXDisk/OnlineBlock") # per-layer with history for online + .groupBy("PXForward/PXDisk", "EXTEND_Y") + .save() + ) + + StandardSpecifications1D.append( + Specification().groupBy("PXBarrel/OnlineBlock") # per-layer with history for online + .groupBy("PXBarrel", "EXTEND_Y") + .save() + ) + StandardSpecifications1D.append( + Specification().groupBy("PXForward/OnlineBlock") # per-layer with history for online + .groupBy("PXForward", "EXTEND_Y") + .save() + ) + + StandardSpecifications1D_Num.append( + Specification(PerLayer1D).groupBy("PXBarrel/PXLayer/OnlineBlock/DetId/Event") # per-layer with history for online + .reduce("COUNT") + .groupBy("PXBarrel/PXLayer/OnlineBlock") + .groupBy("PXBarrel/PXLayer", "EXTEND_Y") + .save() + ) + StandardSpecifications1D_Num.append( + Specification(PerLayer1D).groupBy("PXForward/PXDisk/OnlineBlock/DetId/Event") # per-layer with history for online + .reduce("COUNT") + .groupBy("PXForward/PXDisk/OnlineBlock") + .groupBy("PXForward/PXDisk", "EXTEND_Y") + .save() + ) + StandardSpecifications1D_Num.append( + Specification().groupBy("PXBarrel/OnlineBlock/DetId/Event") # per-layer with history for online + .reduce("COUNT") + .groupBy("PXBarrel/OnlineBlock") + .groupBy("PXBarrel", "EXTEND_Y") + .save() + ) + StandardSpecifications1D_Num.append( + Specification().groupBy("PXForward/OnlineBlock/DetId/Event") # per-layer with history for online + .reduce("COUNT") + .groupBy("PXForward/OnlineBlock") + .groupBy("PXForward", "EXTEND_Y") + .save() + ) + + # Configure Phase1 DQM for Phase0 data -SiPixelPhase1Geometry.n_inner_ring_blades = 24 # no outer ring +SiPixelPhase1Geometry.upgradePhase = 0 # Turn on 'online' harvesting. This has to be set before other configs are # loaded (due to how the DefaultHisto PSet is later cloned), therefore it is diff --git a/DQM/SiPixelPhase1Config/test/pixelphase1_dqm_sourceclient-live_cfg.py b/DQM/SiPixelPhase1Config/test/pixelphase1_dqm_sourceclient-live_cfg.py index 6961b41b85006..a7226dc7c9a8b 100644 --- a/DQM/SiPixelPhase1Config/test/pixelphase1_dqm_sourceclient-live_cfg.py +++ b/DQM/SiPixelPhase1Config/test/pixelphase1_dqm_sourceclient-live_cfg.py @@ -59,7 +59,7 @@ 'userarea': cms.PSet( type = cms.untracked.string("userarea"), collectorPort = cms.untracked.int32(9190), - collectorHost = cms.untracked.string('localhost'), + collectorHost = cms.untracked.string('lxplus064'), ), } @@ -106,22 +106,29 @@ #------------------------------------------------- process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') from Configuration.AlCa.GlobalTag import GlobalTag -process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase1_2017_realistic', '') +process.GlobalTag = GlobalTag(process.GlobalTag, '90X_upgrade2017_realistic_v0', '') #----------------------- # Reconstruction Modules #----------------------- # Real data raw to digi -process.load("EventFilter.SiPixelRawToDigi.SiPixelRawToDigi_cfi") +process.load("Configuration.StandardSequences.RawToDigi_Data_cff") +#process.load("EventFilter.SiPixelRawToDigi.SiPixelRawToDigi_cfi") process.siPixelDigis.IncludeErrors = True # Local Reconstruction -process.load("RecoLocalTracker.SiPixelClusterizer.SiPixelClusterizer_cfi") +#process.load("RecoLocalTracker.SiPixelClusterizer.SiPixelClusterizer_cfi") + +process.load("Configuration.StandardSequences.Reconstruction_cff") +process.load("Configuration.StandardSequences.RawToDigi_cff") +process.load("Configuration.StandardSequences.L1Reco_cff") #----------------------- # Phase1 DQM #----------------------- + + # first, we load the global defaults and overwrite what needs to be changed from DQM.SiPixelPhase1Common.HistogramManager_cfi import * DefaultHisto.enabled = True @@ -136,15 +143,61 @@ # then, we load the online config. This will overwrite more defaults, and e.g. configure for phase0 real data. process.load("DQM.SiPixelPhase1Config.SiPixelPhase1OnlineDQM_cff") +process.load("DQM.SiPixelPhase1Config.SiPixelPhase1OfflineDQM_harvesting_cff") +#process.load("RecoLocalTracker.SiPixelClusterizer.SiPixelClusterizer_cfi") # this also loads the plugins. After that, some values cannot be changed any more, since they were copied around. # Now change things back to Phase1 MC -SiPixelPhase1Geometry.n_inner_ring_blades = 22 +SiPixelPhase1Geometry.upgradePhase = 1 + + +#process.load('RecoTracker.Configuration.RecoTracker_cff') +# +# #process.newCombinedSeeds.seedCollections = cms.VInputTag( +# # cms.InputTag('initialStepSeeds'), +# # ) +# +#process.load('RecoTracker.FinalTrackSelectors.MergeTrackCollections_cff') +# +##import RecoTracker.FinalTrackSelectors.earlyGeneralTracks_cfi +# +#process.load('RecoTracker.FinalTrackSelectors.earlyGeneralTracks_cfi') +# +# +# +#process.earlyGeneralTracks.hasSelector=cms.vint32(1) +#process.earlyGeneralTracks.selectedTrackQuals = cms.VInputTag( +# # cms.InputTag("initialStepSelector","initialStep"), +# cms.InputTag("initialStep"), +# ) +#process.earlyGeneralTracks.setsToMerge = cms.VPSet( cms.PSet( tLists=cms.vint32(0), pQual=cms.bool(True) ) ) +# +#process.load("RecoTracker.IterativeTracking.iterativeTk_cff") +# +#process.iterTracking_FirstStep =cms.Sequence( +# process.InitialStep +# *process.earlyGeneralTracks +# ) +# +# +##process.earlyGeneralTracks.TrackProducers = ( +## cms.InputTag('initialStepTracks'), +## ) +# +#process.RecoForDQM_LocalReco = cms.Sequence(process.siPixelDigis*process.siStripDigis*process.gtDigis*process.trackerlocalreco)#*process.gtEvmDigis) +# + +#from DQM.SiPixelPhase1TrackResiduals.SiPixelPhase1TrackResiduals_cfi import * +# Clusters ontrack/offtrack (also general tracks) +#from DQM.SiPixelPhase1TrackClusters.SiPixelPhase1TrackClusters_cfi import * +# Hit Efficiencies +#from DQM.SiPixelPhase1TrackEfficiency.SiPixelPhase1TrackEfficiency_cfi import * process.siPixelDigis.InputLabel = cms.InputTag("rawDataCollector") -process.SiPixelPhase1DigisAnalyzer.src = "simSiPixelDigis" -process.SiPixelPhase1RawDataAnalyzer.src = "simSiPixelDigis" +process.SiPixelPhase1DigisAnalyzer.src = "siPixelDigis" +process.SiPixelPhase1RawDataAnalyzer.src = "siPixelDigis" +#process.RecoForDQM_TrkReco = cms.Sequence(process.offlineBeamSpot*process.MeasurementTrackerEventPreSplitting*process.siPixelClusterShapeCachePreSplitting*process.recopixelvertexing*process.InitialStepPreSplitting) # All plot configurations should go the the specific config files (for online and offline) # or to SiPixelPhase1OnlineDQM_cff (if online only). Refer to pixel_up_dqm_sourceclient-live_cfg.py # to see how things could be overwritten here (works the same in SiPixelPhase1OnlineDQM_cff). @@ -160,10 +213,15 @@ process.DQMmodules = cms.Sequence(process.dqmEnv*process.dqmSaver) process.p = cms.Path( - process.siPixelDigis - * process.siPixelClusters + process.RawToDigi + * process.L1Reco + * process.reconstruction + # process.siPixelDigis + #* process.siPixelClusters * process.DQMmodules - * process.siPixelPhase1OnlineDQM_source - * process.siPixelPhase1OnlineDQM_harvesting + * process.siPixelPhase1OfflineDQM_source + * process.siPixelPhase1OfflineDQM_harvesting + * process.SiPixelPhase1GeometryDebugAnalyzer + * process.SiPixelPhase1GeometryDebugHarvester ) diff --git a/DQM/SiPixelPhase1Digis/interface/SiPixelPhase1Digis.h b/DQM/SiPixelPhase1Digis/interface/SiPixelPhase1Digis.h index 9e848a8462d41..2fe7ab146e72f 100644 --- a/DQM/SiPixelPhase1Digis/interface/SiPixelPhase1Digis.h +++ b/DQM/SiPixelPhase1Digis/interface/SiPixelPhase1Digis.h @@ -20,10 +20,12 @@ class SiPixelPhase1Digis : public SiPixelPhase1Base { enum { ADC, // digi ADC readouts NDIGIS, // number of digis per event and module + NDIGISINCLUSIVE, //Total number of digis in BPix and FPix NDIGIS_FED, // number of digis per event and FED NDIGIS_FEDtrend, // number of digis per event and FED EVENT, // event frequency MAP, // digi hitmap per module + OCCUPANCY, // like map but coarser MAX_HIST // a sentinel that gives the number of quantities (not a plot). }; @@ -37,20 +39,4 @@ class SiPixelPhase1Digis : public SiPixelPhase1Base { }; -class SiPixelPhase1DigisHarvester : public SiPixelPhase1Harvester { - enum { - ADC, - NDIGIS, - NDIGIS_FED, - NDIGIS_FEDtrend, - EVENT, - MAP, - - MAX_HIST - }; - public: - explicit SiPixelPhase1DigisHarvester(const edm::ParameterSet& conf); - -}; - #endif diff --git a/DQM/SiPixelPhase1Digis/python/SiPixelPhase1Digis_cfi.py b/DQM/SiPixelPhase1Digis/python/SiPixelPhase1Digis_cfi.py index 02ceebdceda39..48b06c9028d7e 100644 --- a/DQM/SiPixelPhase1Digis/python/SiPixelPhase1Digis_cfi.py +++ b/DQM/SiPixelPhase1Digis/python/SiPixelPhase1Digis_cfi.py @@ -12,7 +12,9 @@ range_nbins = 300, specs = VPSet( StandardSpecificationTrend, - StandardSpecification2DProfile, + StandardSpecificationTrend2D, + StandardSpecificationPixelmapProfile,# ROC level map + #StandardSpecification2DProfile, # module level map StandardSpecifications1D ) ) @@ -32,6 +34,19 @@ ) ) + +SiPixelPhase1ClustersNdigisInclusive = DefaultHistoDigiCluster.clone( + name = "digis", + title = "Digis", + range_min = 0, range_max = 2000, range_nbins = 200, + xlabel = "digis", + dimensions = 0, + specs = VPSet( + StandardSpecificationInclusive_Num + ) +) + + SiPixelPhase1DigisNdigisPerFED = DefaultHisto.clone( #to be removed? name = "feddigis", # This is the same as above up to the ranges. maybe we title = "Digis", # should allow setting the range per spec, but OTOH a @@ -41,9 +56,7 @@ range_nbins = 200, dimensions = 0, specs = VPSet( - # the double "FED" here is due to a "bug", caused by how the specs are - # translated for step1. Interpret as "count by FED, extend by FED". - Specification().groupBy("FED/FED/Event") + Specification().groupBy("FED/Event") .reduce("COUNT") .groupBy("FED") .groupBy("", "EXTEND_Y") @@ -67,12 +80,10 @@ .groupBy("Lumisection", "EXTEND_Y") .groupBy("", "EXTEND_X") .save() - .custom("ratio_to_average") - .save() ) ) -SiPixelPhase1DigisEvents = DefaultHisto.clone( +SiPixelPhase1DigisEvents = DefaultHistoDigiCluster.clone( name = "eventrate", title = "Rate of Pixel Events", xlabel = "Lumisection", @@ -87,32 +98,54 @@ ) SiPixelPhase1DigisHitmap = DefaultHistoDigiCluster.clone( - name = "hitmap", - title = "Position of digis on module", + name = "digi_occupancy", + title = "Digi Occupancy", ylabel = "#digis", dimensions = 0, specs = VPSet( - Specification(PerModule).groupBy("PXBarrel/Shell/PXLayer/PXLadder/P1PXModuleName/row/col") - .groupBy("PXBarrel/Shell/PXLayer/PXLadder/P1PXModuleName/row", "EXTEND_Y") - .groupBy("PXBarrel/Shell/PXLayer/PXLadder/P1PXModuleName", "EXTEND_X") + Specification(PerModule).groupBy("PXBarrel/Shell/PXLayer/PXLadder/PXModuleName/row/col") + .groupBy("PXBarrel/Shell/PXLayer/PXLadder/PXModuleName/row", "EXTEND_Y") + .groupBy("PXBarrel/Shell/PXLayer/PXLadder/PXModuleName", "EXTEND_X") .save(), - Specification(PerModule).groupBy("PXBarrel/Shell/PXLayer/PXLadder/P1PXModuleName/col") - .groupBy("PXBarrel/Shell/PXLayer/PXLadder/P1PXModuleName", "EXTEND_X") + Specification(PerModule).groupBy("PXBarrel/Shell/PXLayer/PXLadder/PXModuleName/col") + .groupBy("PXBarrel/Shell/PXLayer/PXLadder/PXModuleName", "EXTEND_X") .save(), - Specification(PerModule).groupBy("PXBarrel/Shell/PXLayer/PXLadder/P1PXModuleName/row") - .groupBy("PXBarrel/Shell/PXLayer/PXLadder/P1PXModuleName", "EXTEND_X") + Specification(PerModule).groupBy("PXBarrel/Shell/PXLayer/PXLadder/PXModuleName/row") + .groupBy("PXBarrel/Shell/PXLayer/PXLadder/PXModuleName", "EXTEND_X") .save(), - - Specification(PerModule).groupBy("PXForward/HalfCylinder/PXDisk/PXRing/PXBlade/P1PXModuleName/row/col") - .groupBy("PXForward/HalfCylinder/PXDisk/PXRing/PXBlade/P1PXModuleName/row", "EXTEND_Y") - .groupBy("PXForward/HalfCylinder/PXDisk/PXRing/PXBlade/P1PXModuleName", "EXTEND_X") + Specification(PerModule).groupBy("PXForward/HalfCylinder/PXDisk/PXRing/PXBlade/PXModuleName/row/col") + .groupBy("PXForward/HalfCylinder/PXDisk/PXRing/PXBlade/PXModuleName/row", "EXTEND_Y") + .groupBy("PXForward/HalfCylinder/PXDisk/PXRing/PXBlade/PXModuleName", "EXTEND_X") .save(), - Specification(PerModule).groupBy("PXForward/HalfCylinder/PXDisk/PXRing/PXBlade/P1PXModuleName/col") - .groupBy("PXForward/HalfCylinder/PXDisk/PXRing/PXBlade/P1PXModuleName", "EXTEND_X") + Specification(PerModule).groupBy("PXForward/HalfCylinder/PXDisk/PXRing/PXBlade/PXModuleName/col") + .groupBy("PXForward/HalfCylinder/PXDisk/PXRing/PXBlade/PXModuleName", "EXTEND_X") .save(), - Specification(PerModule).groupBy("PXForward/HalfCylinder/PXDisk/PXRing/PXBlade/P1PXModuleName/row") - .groupBy("PXForward/HalfCylinder/PXDisk/PXRing/PXBlade/P1PXModuleName", "EXTEND_X") - .save() + Specification(PerModule).groupBy("PXForward/HalfCylinder/PXDisk/PXRing/PXBlade/PXModuleName/row") + .groupBy("PXForward/HalfCylinder/PXDisk/PXRing/PXBlade/PXModuleName", "EXTEND_X") + .save(), + StandardSpecificationOccupancy, + ) +) + +SiPixelPhase1DigisOccupancy = DefaultHistoReadout.clone( + name = "occupancy", + title = "Digi Occupancy", + dimensions = 0, + specs = VPSet( + Specification(PerReadout).groupBy("PXBarrel/FED/LinkInFed") + .groupBy("PXBarrel/FED", "EXTEND_X").save(), + Specification(PerReadout).groupBy("PXBarrel/FED/LinkInFed/RocInLink") + .groupBy("PXBarrel/FED/LinkInFed", "EXTEND_Y") + .groupBy("PXBarrel/FED", "EXTEND_X").save(), + Specification(PerReadout).groupBy("PXForward/FED/LinkInFed") + .groupBy("PXForward/FED", "EXTEND_X").save(), + Specification(PerReadout).groupBy("PXForward/FED/LinkInFed/RocInLink") + .groupBy("PXForward/FED/LinkInFed", "EXTEND_Y") + .groupBy("PXForward/FED", "EXTEND_X").save(), + Specification(PerReadout).groupBy("PXBarrel/FED") + .groupBy("PXBarrel", "EXTEND_X").save(), + Specification(PerReadout).groupBy("PXForward/FED") + .groupBy("PXForward", "EXTEND_X").save(), ) ) @@ -121,10 +154,12 @@ SiPixelPhase1DigisConf = cms.VPSet( SiPixelPhase1DigisADC, SiPixelPhase1DigisNdigis, + SiPixelPhase1ClustersNdigisInclusive, SiPixelPhase1DigisNdigisPerFED, SiPixelPhase1DigisNdigisPerFEDtrend, SiPixelPhase1DigisEvents, SiPixelPhase1DigisHitmap, + SiPixelPhase1DigisOccupancy, ) SiPixelPhase1DigisAnalyzer = cms.EDAnalyzer("SiPixelPhase1Digis", @@ -133,7 +168,7 @@ geometry = SiPixelPhase1Geometry ) -SiPixelPhase1DigisHarvester = cms.EDAnalyzer("SiPixelPhase1DigisHarvester", +SiPixelPhase1DigisHarvester = cms.EDAnalyzer("SiPixelPhase1Harvester", histograms = SiPixelPhase1DigisConf, geometry = SiPixelPhase1Geometry ) diff --git a/DQM/SiPixelPhase1Digis/src/SiPixelPhase1Digis.cc b/DQM/SiPixelPhase1Digis/src/SiPixelPhase1Digis.cc index 1f35bac054cac..3513827c66467 100644 --- a/DQM/SiPixelPhase1Digis/src/SiPixelPhase1Digis.cc +++ b/DQM/SiPixelPhase1Digis/src/SiPixelPhase1Digis.cc @@ -30,19 +30,24 @@ void SiPixelPhase1Digis::analyze(const edm::Event& iEvent, const edm::EventSetup edm::Handle> input; iEvent.getByToken(srcToken_, input); if (!input.isValid()) return; + bool hasDigis; edm::DetSetVector::const_iterator it; for (it = input->begin(); it != input->end(); ++it) { for(PixelDigi const& digi : *it) { - histo[ADC].fill((double) digi.adc(), DetId(it->detId()), &iEvent); + hasDigis=true; + histo[ADC].fill((double) digi.adc(), DetId(it->detId()), &iEvent, digi.column(), digi.row()); histo[MAP].fill(DetId(it->detId()), &iEvent, digi.column(), digi.row()); + histo[OCCUPANCY].fill(DetId(it->detId()), &iEvent, digi.column(), digi.row()); histo[NDIGIS ].fill(DetId(it->detId()), &iEvent); // count + histo[NDIGISINCLUSIVE].fill(DetId(it->detId()), &iEvent); // count histo[NDIGIS_FED].fill(DetId(it->detId()), &iEvent); histo[NDIGIS_FEDtrend].fill(DetId(it->detId()), &iEvent); } } - histo[EVENT].fill(DetId(0), &iEvent); + if (hasDigis) histo[EVENT].fill(DetId(0), &iEvent); histo[NDIGIS ].executePerEventHarvesting(&iEvent); + histo[NDIGISINCLUSIVE].executePerEventHarvesting(&iEvent); histo[NDIGIS_FED].executePerEventHarvesting(&iEvent); histo[NDIGIS_FEDtrend].executePerEventHarvesting(&iEvent); } diff --git a/DQM/SiPixelPhase1Digis/src/SiPixelPhase1DigisHarvester.cc b/DQM/SiPixelPhase1Digis/src/SiPixelPhase1DigisHarvester.cc deleted file mode 100644 index 39fd245f19131..0000000000000 --- a/DQM/SiPixelPhase1Digis/src/SiPixelPhase1DigisHarvester.cc +++ /dev/null @@ -1,46 +0,0 @@ -// -*- C++ -*- -// -// Package: SiPixelPhase1DigisHarvester -// Class: SiPixelPhase1DigisHarvester -// - -// Original Author: Marcel Schneider - -#include "DQM/SiPixelPhase1Digis/interface/SiPixelPhase1Digis.h" -#include "FWCore/Framework/interface/MakerMacros.h" - -SiPixelPhase1DigisHarvester::SiPixelPhase1DigisHarvester(const edm::ParameterSet& iConfig) : - SiPixelPhase1Harvester(iConfig) -{ - histo[NDIGIS_FED].setCustomHandler([&] (SummationStep const& s, HistogramManager::Table& t, - DQMStore::IBooker& iBooker, DQMStore::IGetter&) { - for (auto e : t) { - TH1* th1 = e.second.th1; - assert(th1->GetDimension() == 2); - TH2D* th2 = dynamic_cast(th1); - assert(th2); - iBooker.setCurrentFolder(e.second.me->getPathname()); - MonitorElement* out = iBooker.book2DD(e.second.me->getName() + "_norm", th2); - - for (int x = 1; x <= th1->GetNbinsX(); x++) { - double sum = 0; - int nonzero = 0; - for (int y = 1; y <= th1->GetNbinsY(); y++) { - double val = th1->GetBinContent(x, y); - sum += val; - if (val != 0.0) nonzero++; - } - - if (nonzero == 0) continue; - - double avg = sum / nonzero; - - for (int y = 1; y <= th1->GetNbinsY(); y++) { - out->setBinContent(x, y, th1->GetBinContent(x, y) / avg); - } - } - } - }); -} - -DEFINE_FWK_MODULE(SiPixelPhase1DigisHarvester); diff --git a/DQM/SiPixelPhase1RawData/python/SiPixelPhase1RawData_cfi.py b/DQM/SiPixelPhase1RawData/python/SiPixelPhase1RawData_cfi.py index 32efe109273a4..ea52c211dbf17 100644 --- a/DQM/SiPixelPhase1RawData/python/SiPixelPhase1RawData_cfi.py +++ b/DQM/SiPixelPhase1RawData/python/SiPixelPhase1RawData_cfi.py @@ -13,13 +13,18 @@ Specification().groupBy("FED/FED/Event") .reduce("COUNT") .groupBy("FED/FED").save(), - Specification().groupBy("FED/FED/FEDChannel") + Specification().groupBy("FED/FED/LinkInFed") .groupBy("FED/FED", "EXTEND_X") .save(), - Specification().groupBy("FED/FEDChannel") + Specification().groupBy("FED/LinkInFed") .groupBy("FED", "EXTEND_X") .groupBy("", "EXTEND_Y") - .save() + .save(), + Specification().groupBy("FED/FED/Lumisection") + .groupBy("FED/FED","EXTEND_X") + .save() + .groupBy("") + .save() ) ) @@ -70,9 +75,14 @@ Specification().groupBy("FED/FED").save(), Specification().groupBy("FED") .groupBy("", "EXTEND_Y").save(), + Specification().groupBy("FED/FED/LinkInFed") + .groupBy("FED/FED","EXTEND_Y").save() + ) ) + + SiPixelPhase1RawDataConf = cms.VPSet( SiPixelPhase1RawDataNErrors, SiPixelPhase1RawDataFIFOFull, diff --git a/DQM/SiPixelPhase1RecHits/python/SiPixelPhase1RecHits_cfi.py b/DQM/SiPixelPhase1RecHits/python/SiPixelPhase1RecHits_cfi.py index feba187f010f8..45c490be03a34 100644 --- a/DQM/SiPixelPhase1RecHits/python/SiPixelPhase1RecHits_cfi.py +++ b/DQM/SiPixelPhase1RecHits/python/SiPixelPhase1RecHits_cfi.py @@ -8,8 +8,11 @@ xlabel = "rechits", dimensions = 0, specs = VPSet( - StandardSpecificationTrend_Num, - StandardSpecification2DProfile_Num + StandardSpecificationInclusive_Num, + StandardSpecificationTrend_Num + # StandardSpecification2DProfile_Num, + # StandardSpecificationInclusive_Num, + # StandardSpecifications1D_Num ) ) @@ -31,6 +34,7 @@ ) SiPixelPhase1RecHitsErrorX = DefaultHistoTrack.clone( + enabled=False, name = "rechiterror_x", title = "RecHit Error in X-direction", range_min = 0, range_max = 0.02, range_nbins = 100, @@ -42,6 +46,7 @@ ) SiPixelPhase1RecHitsErrorY = SiPixelPhase1RecHitsErrorX.clone( + enabled=False, name = "rechiterror_y", title = "RecHit Error in Y-direction", xlabel = "Y error" diff --git a/DQM/SiPixelPhase1TrackClusters/python/SiPixelPhase1TrackClusters_cfi.py b/DQM/SiPixelPhase1TrackClusters/python/SiPixelPhase1TrackClusters_cfi.py index 99ad479ce79d6..1ee2573616f65 100644 --- a/DQM/SiPixelPhase1TrackClusters/python/SiPixelPhase1TrackClusters_cfi.py +++ b/DQM/SiPixelPhase1TrackClusters/python/SiPixelPhase1TrackClusters_cfi.py @@ -27,8 +27,8 @@ ) SiPixelPhase1TrackClustersOnTrackNClusters = DefaultHistoTrack.clone( - name = "clusters", - title = "Clusters", + name = "clusters_ontrack", + title = "Clusters_onTrack", range_min = 0, range_max = 10, range_nbins = 10, xlabel = "clusters", dimensions = 0, @@ -41,12 +41,14 @@ .reduce("COUNT") .groupBy("PXForward/PXDisk") .saveAll(), + StandardSpecificationInclusive_Num, + StandardSpecificationTrend_Num ) ) SiPixelPhase1TrackClustersOnTrackPositionB = DefaultHistoTrack.clone( - name = "clusterposition_zphi", - title = "Cluster Positions", + name = "clusterposition_zphi_ontrack", + title = "Cluster_onTrack Positions", range_min = -60, range_max = 60, range_nbins = 600, range_y_min = -3.2, range_y_max = 3.2, range_y_nbins = 200, xlabel = "Global Z", ylabel = "Global \phi", @@ -58,8 +60,8 @@ ) SiPixelPhase1TrackClustersOnTrackPositionF = DefaultHistoTrack.clone( - name = "clusterposition_xy", - title = "Cluster Positions", + name = "clusterposition_xy_ontrack", + title = "Cluster_onTrack Positions", xlabel = "Global X", ylabel = "Global Y", range_min = -20, range_max = 20, range_nbins = 200, range_y_min = -20, range_y_max = 20, range_y_nbins = 200, diff --git a/DQM/SiPixelPhase1TrackEfficiency/interface/SiPixelPhase1TrackEfficiency.h b/DQM/SiPixelPhase1TrackEfficiency/interface/SiPixelPhase1TrackEfficiency.h index 2b59cbdd0f2e0..716065ce67bba 100644 --- a/DQM/SiPixelPhase1TrackEfficiency/interface/SiPixelPhase1TrackEfficiency.h +++ b/DQM/SiPixelPhase1TrackEfficiency/interface/SiPixelPhase1TrackEfficiency.h @@ -17,7 +17,8 @@ class SiPixelPhase1TrackEfficiency : public SiPixelPhase1Base { enum { VALID, MISSING, - EFFICIENCY + EFFICIENCY, + VERTICES }; public: @@ -30,22 +31,4 @@ class SiPixelPhase1TrackEfficiency : public SiPixelPhase1Base { edm::EDGetTokenT vtxToken_; }; -class SiPixelPhase1TrackEfficiencyHarvester : public SiPixelPhase1Harvester { - enum { - VALID, - MISSING, - EFFICIENCY - }; - - public: - explicit SiPixelPhase1TrackEfficiencyHarvester(const edm::ParameterSet& conf); - - void doHarvesting(SummationStep const& s, HistogramManager::Table& efficiency); - - private: - // we use the custom arg as a tag, to not mix up different tables. - std::map valid; - std::map missing; -}; - #endif diff --git a/DQM/SiPixelPhase1TrackEfficiency/python/SiPixelPhase1TrackEfficiency_cfi.py b/DQM/SiPixelPhase1TrackEfficiency/python/SiPixelPhase1TrackEfficiency_cfi.py index e96f3f53096a4..f7425bba7c6fc 100644 --- a/DQM/SiPixelPhase1TrackEfficiency/python/SiPixelPhase1TrackEfficiency_cfi.py +++ b/DQM/SiPixelPhase1TrackEfficiency/python/SiPixelPhase1TrackEfficiency_cfi.py @@ -4,30 +4,60 @@ SiPixelPhase1TrackEfficiencyValid = DefaultHistoTrack.clone( name = "valid", title = "Valid Hits", + xlabel = "valid hits", dimensions = 0, specs = VPSet( - # custom() is called here after every save to export the histos for the - # efficiency harvesting. The parameter is just a tag that we don't confuse - # the histos of different specs. - Specification().groupBy("PXBarrel/PXLayer/signedLadder/signedModule") - .groupBy("PXBarrel/PXLayer/signedLadder", "EXTEND_X") - .groupBy("PXBarrel/PXLayer", "EXTEND_Y") - .save() - .custom("signedmodule_barrel"), + StandardSpecifications1D_Num, + StandardSpecificationOccupancy, ) ) -SiPixelPhase1TrackEfficiencyMissing = SiPixelPhase1TrackEfficiencyValid.clone( +SiPixelPhase1TrackEfficiencyMissing = DefaultHistoTrack.clone( name = "missing", title = "Missing Hits", + xlabel = "missing hits", + dimensions = 0, + specs = VPSet( + StandardSpecifications1D_Num, + StandardSpecificationOccupancy, + ) ) SiPixelPhase1TrackEfficiencyEfficiency = SiPixelPhase1TrackEfficiencyValid.clone( name = "hitefficiency", title = "Hit Efficiency", - # most stuff done in custom() step, carried over from valid/missing histos - # the custom() step looks for matching valid/mmissing histos and fills the - # efficiency plots if data is available. So all should use the same specs. + xlabel = "#valid/(#valid+#missing)", + dimensions = 1, + specs = VPSet( + StandardSpecification2DProfile, + StandardSpecificationPixelmapProfile, + Specification().groupBy("PXBarrel/PXLayer/ROC") + .groupBy("PXBarrel/PXLayer", "EXTEND_X") + .reduce("MEAN") + .save(), + Specification().groupBy("PXForward/PXRing/ROC") + .groupBy("PXForward/PXRing", "EXTEND_X") + .reduce("MEAN") + .save() + ) +) + +SiPixelPhase1TrackEfficiencyVertices= DefaultHistoTrack.clone( + name = "num_vertices", + title = "PrimaryVertices", + xlabel= "# Vertices", + dimensions = 1, + range_min = -0.5, + range_max = 100.5, + range_nbins =101, + specs = VPSet( + Specification().groupBy("") + .save(), + Specification().groupBy("/Lumisection") + .reduce("MEAN") + .groupBy("","EXTEND_X") + .save() + ) ) @@ -36,6 +66,7 @@ SiPixelPhase1TrackEfficiencyValid, SiPixelPhase1TrackEfficiencyMissing, SiPixelPhase1TrackEfficiencyEfficiency, + SiPixelPhase1TrackEfficiencyVertices ) @@ -47,7 +78,7 @@ geometry = SiPixelPhase1Geometry ) -SiPixelPhase1TrackEfficiencyHarvester = cms.EDAnalyzer("SiPixelPhase1TrackEfficiencyHarvester", +SiPixelPhase1TrackEfficiencyHarvester = cms.EDAnalyzer("SiPixelPhase1Harvester", histograms = SiPixelPhase1TrackEfficiencyConf, geometry = SiPixelPhase1Geometry ) diff --git a/DQM/SiPixelPhase1TrackEfficiency/src/SiPixelPhase1TrackEfficiency.cc b/DQM/SiPixelPhase1TrackEfficiency/src/SiPixelPhase1TrackEfficiency.cc index 16cef2d047176..6973d35307a52 100644 --- a/DQM/SiPixelPhase1TrackEfficiency/src/SiPixelPhase1TrackEfficiency.cc +++ b/DQM/SiPixelPhase1TrackEfficiency/src/SiPixelPhase1TrackEfficiency.cc @@ -38,7 +38,11 @@ void SiPixelPhase1TrackEfficiency::analyze(const edm::Event& iEvent, const edm:: // get primary vertex edm::Handle vertices; iEvent.getByToken( vtxToken_, vertices); - if (!vertices.isValid() || vertices->size() == 0) return; + + if (!vertices.isValid()) return; + histo[VERTICES].fill(vertices->size(),DetId(0),&iEvent); + if (vertices->size() == 0) return; + // should be used for weird cuts //const auto primaryVertex = vertices->at(0); @@ -90,20 +94,32 @@ void SiPixelPhase1TrackEfficiency::analyze(const edm::Event& iEvent, const edm:: bool isHitMissing = hit->getType()==TrackingRecHit::missing; const SiPixelRecHit* pixhit = dynamic_cast(hit->hit()); - int row = 0, col = 0; + const PixelGeomDetUnit* geomdetunit = dynamic_cast ( tracker->idToDet(id) ); + const PixelTopology& topol = geomdetunit->specificTopology(); + LocalPoint lp; if (pixhit) { - const PixelGeomDetUnit* geomdetunit = dynamic_cast ( tracker->idToDet(id) ); - const PixelTopology& topol = geomdetunit->specificTopology(); - LocalPoint const& lp = pixhit->localPositionFast(); - MeasurementPoint mp = topol.measurementPosition(lp); - row = (int) mp.x(); - col = (int) mp.y(); + lp = pixhit->localPosition(); + } else { + lp = measurement.updatedState().localPosition(); } - if (isHitValid) histo[VALID ].fill(id, &iEvent, col, row); - if (isHitMissing) histo[MISSING].fill(id, &iEvent, col, row); + MeasurementPoint mp = topol.measurementPosition(lp); + int row = (int) mp.x(); + int col = (int) mp.y(); + + + if (isHitValid) { + histo[VALID].fill(id, &iEvent, col, row); + histo[EFFICIENCY].fill(1, id, &iEvent, col, row); + } + if (isHitMissing) { + histo[MISSING].fill(id, &iEvent, col, row); + histo[EFFICIENCY].fill(0, id, &iEvent, col, row); + } } } +histo[VALID ].executePerEventHarvesting(&iEvent); +histo[MISSING].executePerEventHarvesting(&iEvent); } DEFINE_FWK_MODULE(SiPixelPhase1TrackEfficiency); diff --git a/DQM/SiPixelPhase1TrackEfficiency/src/SiPixelPhase1TrackEfficiencyHarvester.cc b/DQM/SiPixelPhase1TrackEfficiency/src/SiPixelPhase1TrackEfficiencyHarvester.cc deleted file mode 100644 index a32bfac35ae02..0000000000000 --- a/DQM/SiPixelPhase1TrackEfficiency/src/SiPixelPhase1TrackEfficiencyHarvester.cc +++ /dev/null @@ -1,80 +0,0 @@ -// -*- C++ -*- -// -// Package: SiPixelPhase1TrackEfficiencyHarvester -// Class: SiPixelPhase1TrackEfficiencyHarvester -// - -// Original Author: Marcel Schneider - -#include "DQM/SiPixelPhase1TrackEfficiency/interface/SiPixelPhase1TrackEfficiency.h" -#include "FWCore/Framework/interface/MakerMacros.h" - -SiPixelPhase1TrackEfficiencyHarvester::SiPixelPhase1TrackEfficiencyHarvester(const edm::ParameterSet& iConfig) : - SiPixelPhase1Harvester(iConfig) -{ - // We collect _all_ (all specs/all custom calls) histos from missing/valid in our table - histo[VALID ].setCustomHandler([&] (SummationStep const& s, HistogramManager::Table& t, - DQMStore::IBooker&, DQMStore::IGetter&) { - valid [s.arg].insert(t.begin(), t.end()); - }); - histo[MISSING ].setCustomHandler([&] (SummationStep const& s, HistogramManager::Table& t, - DQMStore::IBooker&, DQMStore::IGetter&) { - missing[s.arg].insert(t.begin(), t.end()); - }); - - // ... and then take those that we need to fill the EFFICIENCY - // note: we don't need the iBooker here, since the eff. histograms are booked with a HistogramManager - histo[EFFICIENCY].setCustomHandler([&] (SummationStep const& s, HistogramManager::Table& t, - DQMStore::IBooker&, DQMStore::IGetter&) { - doHarvesting(s, t); - }); -} - -void SiPixelPhase1TrackEfficiencyHarvester::doHarvesting(SummationStep const& s, HistogramManager::Table& efficiency) { - for (auto const& e : efficiency) { - GeometryInterface::Values const& values = e.first; - auto missing_it = missing[s.arg].find(values); - auto valid_it = valid [s.arg].find(values); - if (missing_it == missing[s.arg].end() || valid_it == valid[s.arg].end()) { - edm::LogError("SiPixelPhase1TrackEfficiencyHarvester") << "Want to do Efficiencies but 'valid' or 'missing' counts are missing."; - continue; - } - auto num = missing_it->second.th1; - auto denom = valid_it->second.th1; - assert(num); - assert(denom); - assert(num->GetDimension() == denom->GetDimension()); - - auto& out = efficiency[values]; - assert(out.th1); - assert(out.th1->GetDimension() == num->GetDimension()); - - if (num->GetDimension() == 1) { - auto xbins = num->GetXaxis()->GetNbins(); - assert(denom->GetXaxis()->GetNbins() == xbins || out.th1->GetXaxis()->GetNbins()); - - for (int x = 1; x <= xbins; x++) { - auto sum = num->GetBinContent(x) + denom->GetBinContent(x); - if (sum == 0.0) continue; // avoid div by zero - out.th1->SetBinContent(x, 1 - (num->GetBinContent(x) / sum)); - } - - } else /* 2D */ { - auto xbins = num->GetXaxis()->GetNbins(); - auto ybins = num->GetYaxis()->GetNbins(); - assert(denom->GetXaxis()->GetNbins() == xbins || out.th1->GetXaxis()->GetNbins()); - assert(denom->GetYaxis()->GetNbins() == ybins || out.th1->GetYaxis()->GetNbins()); - - for (int y = 1; y <= ybins; y++) { - for (int x = 1; x <= xbins; x++) { - auto sum = num->GetBinContent(x,y) + denom->GetBinContent(x,y); - if (sum == 0.0) continue; // avoid div by zero - out.th1->SetBinContent(x, y, 1 - (num->GetBinContent(x,y) / sum)); - } - } - } - } -} - -DEFINE_FWK_MODULE(SiPixelPhase1TrackEfficiencyHarvester); -