Skip to content

Commit

Permalink
Merge pull request #9689 from venturia/dpganalysis_sistriptools-75x
Browse files Browse the repository at this point in the history
Fix for orbit number = 3564, update of the documentation and other improvements
  • Loading branch information
cmsbuild committed Jul 3, 2015
2 parents d64f3e6 + 1cb44ee commit 4504c50
Show file tree
Hide file tree
Showing 29 changed files with 671 additions and 83 deletions.
53 changes: 51 additions & 2 deletions DPGAnalysis/SiStripTools/README.md
Expand Up @@ -5,9 +5,58 @@ It is an `EDAnalyzer` which can be used to monitor the content of the `Level1Tri
### APVCyclePhaseProducerFromL1TS
It is an `EDProducer` which produces an `APVCyclePhaseCollection` which contains, for each Tracker partition, an offset, between 0 and 69, to be used to compute the position of each event in the Tracker APV readout cycle from the orbit number and the bunch crossing number using `orbit*3564+bx-offset`. More details can be found [in this page](https://twiki.cern.ch/twiki/bin/view/CMS/APVReadoutCycle). The standard way of using it is to let the EventSetup provide the parameters using the record `SiStripConfObject` with the label `apvphaseoffsets` (configurable). If the configuration parameter `ignoreDB` is set to true, then the parameters are read from the configuration file and are: `defaultPartitionNames` usually equal to `TI,TO,TP,TM`, `defaultPhases` which contains a vector (one value per partition) of offsets which are used as offset when no resync has been issued, `magicOffset` which is used to correct the orbit number of the last resync to compute the phase when a resync has been issued using the expression: `(defaultPhase + (lastresyncorbit+magicOffset)*3564%70)%70`, and `useEC0` if we want to use `lastEC0orbit` instead of `lastresyncorbit` to compute the phase. Examples of configurations can be found in the `python` directory.

### ...MultiplicityProducer
There are three specializations of the `EDProducer` `plugins/MultiplicityProducer.cc` template: `SiStripMultiplicityProducer`, `SiPixelMultiplicityProducer`, `SiStripDigiMultiplicityProducer`. This plugin produce simple objects which contain the numbers of strip/pixel clusters or strip digis in subsets of the detector in a given event.
Examples of configurations can be found in:
* `python/sipixelclustermultiplicityprod_cfi.py`
* `python/sistripclustermultiplicityprod_cfi.py`
* `python/sistripdigimultiplicityprod_cfi.py`

The configuration must contain the name of the collection and the parameter `wantedSubDets` which define the subsets of the detector whose multiplicity has to be computed. Each element of this parameter is a `PSet` which contains an integer index, `detSelection`, used to identify the subset by the `EDAnalyzer`s which will use this product, a string, `detLabel`, for the moment dummy, and a vector of strings, `selection` which contains the configuration for a `DetIdSelector` object which define which part of the detector has to be considered. This last parameter can be omitted if the index `detSelection` is between 0 and 6. In that case "0" means the full tracker and "1-6" correspond to the different subdetector according to the detid schema. The optional parameter `withClusterSize` has to be set `True` if instead of counting the number of clusters we want to count the number of digis which compose the clusters.

###MultiplicityInvestigator
It produces histograms related to the cluster or digi multiplicities using the products of the `MultiplicityProducer` plugins. In the configuration the name of the multiplicity product has to be provided as well as the list of multiplicity values to be used. This information is provided by the parameter `wantedSubDets` which contains `PSet` with the parameter `detSelection` which has to match the one specified in the `MultiplicityProducer`, a `detLabel` which will be used to define the histograms names and titles, and `binMax` which is used to define the range of the histograms. Boolean configuration parameters are used to define the set of histograms:
* if `wantInvestHist` is true the multiplicity distribution and the average multiplicity vs the orbit number is produced. Examples of configurations are `python/spclusmultinvestigator_cfi.py`, `python/ssclusmultinvestigator_cfi.py` and `python/ssdigimultinvestigator_cfi.py`.
* if `wantVtxCorrHist` is true the correlations of the multiplcities with the vertex multiplicity are produced. The configuration must contains also the name of the vertex collection and a `wantedSubDets` parameter has to be included in the `digiVtxCorrConfig` `PSet`. Examples of configurations are: `python/spclusmultinvestigatorwithvtx_cfi.py`, `python/ssclusmultinvestigatorwithvtx_cfi.py`, `python/ssdigimultinvestigatorwithvtx_cfi.py`
* if `wantLumiCorrHist` is true the correlation of the multiplicities with the instantaneous BX luminosities are produces. The name of the lumi producer has to be provided as well as a `wantedSubDets` parameter in the `PSet` `digiLumiCorrConfig`. Examples of configurations are `python/spclusmultlumicorr_cfi.py`, `python/ssclusmultlumicorr_cfi.py` and `python/ssdigimultlumicorr_cfi.py`.
* if `wantPileupCorrHist` is true the correlation of the multiplcities with the pileup (MC only) are produced. The configuration must contain the name of the pileup summary collection and a `wantedSubDets` parameter in the `PSet` `digiPileupCorrConfig`. Examples of configurations are `python/spclusmultpileupcorr_cfi.py`, `python/ssclusmultpileupcorr_cfi.py` and `python/ssdigimultpileupcorr_cfi.py`
* if `wantVtxPosCorrHist` is true the correlation of the multiplcities with the (MC) main vertex z position are produced. The configuration ust contain the name of the mc vertex collection and a `wantedSubDets` parameter in the `PSet` `digiVtxPosCorrConfig`. Examples of configurations are: `python/spclusmultvtxposcorr_cfi.py`, `python/ssclusmultvtxposcorr_cfi.py` and `python/ssdigimultvtxposcorr_cfi.py`.

### MultiplicityCorrelator
It correlates two multiplicity values from different part of the detectors. The configuration contains a `VPSet`, `correlationConfigurations`, which contains a `PSet` for each correlation where the names of the multiplicity maps `xMultiplicityMap` and `yMultiplicityMap`, the selection indices, `xDetSelection` and `yDetSelection`, the labels, `xDetLabel` and `yDetLabel`, the number of bins and the max value of the histogram range are provided. In addition booleans are available to activate the most memory-consuming plots. An example of configuration is `python/multiplicitycorr_cfi.py`.

### MultiplicityTimeCorrelations
It produces histograms to correlate the multiplicities obtained from `MultiplicityProducer` with several parameters like the BX number, the position of the event in the APV cycle, the distance from the previous L1A and combinations of these quantities. It requires a `wantedSubDets` `VPSet` and the name of the multiplicity map collection to define the multiplicity values to be considered, the name of the `EventWithHistory` product and the name of the `APVPhaseCollection` product. Additional parameters are available to define the range and binning of the histograms and to preselect the events to be used (obsolete options now that there are dedicated `EDFilter`s in this package). Examples of configurations are `python/spclusmulttimecorrelations_cfi.py`, `python/ssclusmulttimecorrelations_cfi.py` and `python/ssdigimulttimecorrelations_cfi.py`.

## Configurations
* `test/OOTmultiplicity_cfg.py` to study the multiplicity of pixel and strip clusters in filled and empty bunch crossings using zero bias and random triggers. It requires the macros described below to show its results.
* `test/apvphaseproducertest_cfg.py` to study the correlation of the strip multiplicities with the APV cycle and determine if the knowledge of the APV cycle phase offsets is still under control
* `test/bsvsbpix_cfg.py`to correlate the beamspot position with the average position of the BPIX ladders. It requires the macros described below to show its results.
* `test/OccupancyPlotsTest_cfg.py` to measure the hit occupancy and multiplicity in the different detector region (rZ view). It requires the macros described below to show its results.

## ROOT Macros
This package contains a library of ROOT macros that can be loaded by executing `gSystem->Load("$CMSSW_BASE/lib/$SCRAM_ARCH/libDPGAnalysisSiStripToolsMacros.so")`
in the root interactive section
This package contains a library of ROOT macros that can be loaded by executing `gSystem->Load("libDPGAnalysisSiStripToolsMacros.so")`
in the root interactive section, followed by
`#include "DPGAnalysis/SiStripTools/bin/DPGAnalysisSiStripToolsMacrosLinkDef.h"` in case Root 6 is used.

### BSvsBPIXPlot
`BSvsBPIXPlot(TFile* ff, const char* bsmodule, const char* occumodule, const int run)`

It used the root file produced by `test/bsvsbpix_cfg.py` as input and produces a plot with the average beam spot position and the average BPIX ladder positions in the xy plane.

### ComputeOOTFractionvsFill
`ComputeOOTFractionvsFill(TFile* ff, const char* itmodule, const char* ootmodule, const char* etmodule, const char* hname, OOTSummary* ootsumm)`

It uses the output of `test/OOTmultiplicity_cfg.py` to produce a `OOTSummary` object which contains the trend of the out of time fraction vs the fill number.

### ComputeOOTFractionvsRun
`ComputeOOTFractionvsRun(TFile* ff, const char* itmodule, const char* ootmodule, const char* etmodule, const char* hname, OOTSummary* ootsumm=0)`

It uses the output of `test/OOTmultiplicity_cfg.py` to produce a `OOTSummary` object which contains the trend of the out of time fraction vs the run number.

### ComputerOOTFraction
`ComputeOOTFraction(TFile* ff, const char* itmodule, const char* ootmodule, const char* etmodule, const int run, const char* hname, const bool& perFill=false)`
It uses the output of `test/OOTmultiplicity_cfg.py` to produce a `OOTResult` object with the result of the out of time fraction of a given run or fill.

### PlotOccupancyMap
`PlotOccupancyMap(TFile* ff, const char* module, const float min, const float max, const float mmin, const float mmax, const int color)`
Expand Down
54 changes: 54 additions & 0 deletions DPGAnalysis/SiStripTools/bin/BSvsBPIX.cc
@@ -0,0 +1,54 @@
#include "DPGAnalysis/SiStripTools/bin/BSvsBPIX.h"
#include "TFile.h"
#include "TH1F.h"
#include "TProfile.h"
#include "TGraphErrors.h"
#include "TCanvas.h"
#include "TDirectory.h"
#include <iostream>

void BSvsBPIXPlot(TFile* ff, const char* bsmodule, const char* occumodule, const int run) {

TGraphErrors* bspos = new TGraphErrors();
TGraphErrors* bpixpos = new TGraphErrors();

if(ff) {

char bsfolder[200];
sprintf(bsfolder,"%s/run_%d",bsmodule,run);
if(ff->cd(bsfolder)) {
TH1F* bsx = (TH1F*)gDirectory->Get("bsxrun");
TH1F* bsy = (TH1F*)gDirectory->Get("bsyrun");
if(bsx && bsy) {
std::cout << "beam spot position ("
<< bsx->GetMean() << "+/-" << bsx->GetMeanError() << ","
<< bsy->GetMean() << "+/-" << bsy->GetMeanError() << ")" << std::endl;
bspos->SetPoint(0,bsx->GetMean(),bsy->GetMean());
bspos->SetPointError(0,bsx->GetMeanError(),bsy->GetMeanError());
}
}
char occufolder[200];
sprintf(occufolder,"%s/run_%d",occumodule,run);
if(ff->cd(occufolder)) {
TProfile* xmean = (TProfile*)gDirectory->Get("avex");
TProfile* ymean = (TProfile*)gDirectory->Get("avey");
if(xmean && ymean) {
for(int i=1;i<=xmean->GetNbinsX();++i) {
if(xmean->GetBinEntries(i) >0) {
std::cout << "ladder position " << i << " : ("
<< xmean->GetBinContent(i) << "+/-" << xmean->GetBinError(i) << ","
<< ymean->GetBinContent(i) << "+/-" << ymean->GetBinError(i) << ")" << std::endl;
int point = bpixpos->GetN();
bpixpos->SetPoint(point,xmean->GetBinContent(i),ymean->GetBinContent(i));
bpixpos->SetPointError(point,xmean->GetBinError(i),ymean->GetBinError(i));
}
}
}

}
}
new TCanvas("bsbpix","bsbpix",500,500);
bpixpos->Draw("ap");
bspos->Draw("p");

}
8 changes: 8 additions & 0 deletions DPGAnalysis/SiStripTools/bin/BSvsBPIX.h
@@ -0,0 +1,8 @@
#ifndef DPGAnalysis_SiStripTools_BSvsBPIX_h
#define DPGAnalysis_SiStripTools_BSvsBPIX_h

class TFile;

void BSvsBPIXPlot(TFile* ff, const char* bsmodule, const char* occumodule, const int run);

#endif // DPGAnalysis_SiStripTools_BSvsBPIX_h
Expand Up @@ -9,6 +9,7 @@
#include "TrackPlots.h"
#include "SeedMultiplicityPlots.h"
#include "OOTMultiplicityPlotMacros.h"
#include "BSvsBPIX.h"
#ifdef __CINT__
#pragma link off all functions;
#pragma link C++ function PlotTrackerXsect;
Expand Down Expand Up @@ -51,4 +52,5 @@
#pragma link C++ function ComputeOOTFractionvsFill;
#pragma link C++ class OOTResult;
#pragma link C++ class OOTSummary;
#pragma link C++ function BSvsBPIX;
#endif
8 changes: 4 additions & 4 deletions DPGAnalysis/SiStripTools/interface/DigiBXCorrHistogramMaker.h
Expand Up @@ -370,10 +370,10 @@ void DigiBXCorrHistogramMaker<T>::fill(const T& he, const std::map<int,int>& ndi
}
}

m_ndigivsbx[i]->Fill(he.bx(),digi->second);
if(m_ndigivsbx2D.find(i)!=m_ndigivsbx2D.end()) m_ndigivsbx2D[i]->Fill(he.bx(),digi->second);
if(m_ndigivsbx2Dzoom.find(i)!=m_ndigivsbx2Dzoom.end()) m_ndigivsbx2Dzoom[i]->Fill(he.bx(),digi->second);
if(m_ndigivsbx2Dzoom2.find(i)!=m_ndigivsbx2Dzoom2.end()) m_ndigivsbx2Dzoom2[i]->Fill(he.bx(),digi->second);
m_ndigivsbx[i]->Fill(he.bx()%3564,digi->second);
if(m_ndigivsbx2D.find(i)!=m_ndigivsbx2D.end()) m_ndigivsbx2D[i]->Fill(he.bx()%3564,digi->second);
if(m_ndigivsbx2Dzoom.find(i)!=m_ndigivsbx2Dzoom.end()) m_ndigivsbx2Dzoom[i]->Fill(he.bx()%3564,digi->second);
if(m_ndigivsbx2Dzoom2.find(i)!=m_ndigivsbx2Dzoom2.end()) m_ndigivsbx2Dzoom2[i]->Fill(he.bx()%3564,digi->second);


if(he.depth()>0) {
Expand Down
6 changes: 3 additions & 3 deletions DPGAnalysis/SiStripTools/plugins/EventTimeDistribution.cc
Expand Up @@ -187,9 +187,9 @@ EventTimeDistribution::analyze(const edm::Event& iEvent, const edm::EventSetup&
(*(*dbxhist))->Fill(he->deltaBX(indices->first,indices->second));
}

(*_bx)->Fill(iEvent.bunchCrossing());
(*_bx)->Fill(iEvent.bunchCrossing()%3564);
(*_orbit)->Fill(iEvent.orbitNumber());
if(_dbxvsbx && *_dbxvsbx) (*_dbxvsbx)->Fill(iEvent.bunchCrossing(),he->deltaBX());
if(_dbxvsbx && *_dbxvsbx) (*_dbxvsbx)->Fill(iEvent.bunchCrossing()%3564,he->deltaBX());
if(m_ewhdepth && *m_ewhdepth) (*m_ewhdepth)->Fill(he->depth());

edm::Handle<APVCyclePhaseCollection> apvphase;
Expand All @@ -205,7 +205,7 @@ EventTimeDistribution::analyze(const edm::Event& iEvent, const edm::EventSetup&
tbx -= thephase;
(*_bxincycle)->Fill(tbx%70);
if(_dbxvsbxincycle && *_dbxvsbxincycle) (*_dbxvsbxincycle)->Fill(tbx%70,he->deltaBX());
if(_bxincyclevsbx && *_bxincyclevsbx) (*_bxincyclevsbx)->Fill(iEvent.bunchCrossing(),tbx%70);
if(_bxincyclevsbx && *_bxincyclevsbx) (*_bxincyclevsbx)->Fill(iEvent.bunchCrossing()%3564,tbx%70);
if(_orbitvsbxincycle && *_orbitvsbxincycle) (*_orbitvsbxincycle)->Fill(tbx%70,iEvent.orbitNumber());

}
Expand Down
72 changes: 63 additions & 9 deletions DPGAnalysis/SiStripTools/plugins/L1ABCDebugger.cc
Expand Up @@ -21,8 +21,10 @@
#include <memory>

// user include files
#include "TH1F.h"
#include "TH2F.h"
#include "TProfile.h"
#include "DPGAnalysis/SiStripTools/interface/RunHistogramManager.h"

#include <vector>
#include <string>

Expand All @@ -49,14 +51,25 @@ class L1ABCDebugger : public edm::EDAnalyzer {
~L1ABCDebugger();


private:
virtual void beginJob() override ;
virtual void analyze(const edm::Event&, const edm::EventSetup&) override;
virtual void endJob() override ;
private:
virtual void beginJob() override ;
virtual void analyze(const edm::Event&, const edm::EventSetup&) override;
virtual void beginRun(const edm::Run&, const edm::EventSetup&) override;
virtual void endJob() override ;

// ----------member data ---------------------------

edm::EDGetTokenT<L1AcceptBunchCrossingCollection> _l1abccollectionToken;
edm::EDGetTokenT<L1AcceptBunchCrossingCollection> m_l1abccollectionToken;
const unsigned int m_maxLS;
const unsigned int m_LSfrac;

RunHistogramManager m_rhm;

TH2F** m_hoffsets;
TProfile** m_horboffvsorb;
TProfile** m_hbxoffvsorb;


};

//
Expand All @@ -71,10 +84,17 @@ class L1ABCDebugger : public edm::EDAnalyzer {
// constructors and destructor
//
L1ABCDebugger::L1ABCDebugger(const edm::ParameterSet& iConfig):
_l1abccollectionToken(consumes<L1AcceptBunchCrossingCollection>(iConfig.getParameter<edm::InputTag>("l1ABCCollection")))
m_l1abccollectionToken(consumes<L1AcceptBunchCrossingCollection>(iConfig.getParameter<edm::InputTag>("l1ABCCollection"))),
m_maxLS(iConfig.getUntrackedParameter<unsigned int>("maxLSBeforeRebin",250)),
m_LSfrac(iConfig.getUntrackedParameter<unsigned int>("startingLSFraction",16)),
m_rhm(consumesCollector())
{
//now do what ever initialization is needed

m_hoffsets = m_rhm.makeTH2F("offsets","Orbit vs BX offsets between SCAL and Event",2*3564+1,-3564.5,3564.5,201,-100.5,100.5);
m_horboffvsorb = m_rhm.makeTProfile("orboffvsorb","SCAL Orbit offset vs orbit number",m_LSfrac*m_maxLS,0,m_maxLS*262144);
m_hbxoffvsorb = m_rhm.makeTProfile("bxoffvsorb","SCAL BX offset vs orbit number",m_LSfrac*m_maxLS,0,m_maxLS*262144);

}


Expand All @@ -98,18 +118,52 @@ L1ABCDebugger::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup)
using namespace edm;

Handle<L1AcceptBunchCrossingCollection > pIn;
iEvent.getByToken(_l1abccollectionToken,pIn);
iEvent.getByToken(m_l1abccollectionToken,pIn);

// offset computation
for(L1AcceptBunchCrossingCollection::const_iterator l1abc=pIn->begin();l1abc!=pIn->end();++l1abc) {
if(l1abc->l1AcceptOffset()==0) {
if(m_hoffsets && *m_hoffsets)
(*m_hoffsets)->Fill((int)l1abc->bunchCrossing()-(int)iEvent.bunchCrossing(),
(long long)l1abc->orbitNumber()-(long long)iEvent.orbitNumber());
if(m_horboffvsorb && *m_horboffvsorb)
(*m_horboffvsorb)->Fill(iEvent.orbitNumber(),(long long)l1abc->orbitNumber()-(long long)iEvent.orbitNumber());
if(m_hbxoffvsorb && *m_hbxoffvsorb)
(*m_hbxoffvsorb)->Fill(iEvent.orbitNumber(),(int)l1abc->bunchCrossing()-(int)iEvent.bunchCrossing());
}
}


edm::LogInfo("L1ABCDebug") << "Dump of L1AcceptBunchCrossing Collection";
// dump of L1ABC collection

edm::LogInfo("L1ABCDebug") << "Dump of L1AcceptBunchCrossing Collection for event in orbit "
<< iEvent.orbitNumber() << " and BX " << iEvent.bunchCrossing();

for(L1AcceptBunchCrossingCollection::const_iterator l1abc=pIn->begin();l1abc!=pIn->end();++l1abc) {
edm::LogVerbatim("L1ABCDebug") << *l1abc;
}

}

void
L1ABCDebugger::beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup) {

m_rhm.beginRun(iRun);

if(m_hoffsets && *m_hoffsets) {
(*m_hoffsets)->GetXaxis()->SetTitle("#Delta BX (SCAL-Event)"); (*m_hoffsets)->GetYaxis()->SetTitle("#Delta orbit (SCAL-Event)");
}
if(m_horboffvsorb && *m_horboffvsorb) {
(*m_horboffvsorb)->GetXaxis()->SetTitle("Orbit"); (*m_horboffvsorb)->GetYaxis()->SetTitle("#Delta orbit (SCAL-Event)");
(*m_horboffvsorb)->SetCanExtend(TH1::kXaxis);
}
if(m_hbxoffvsorb && *m_hbxoffvsorb) {
(*m_hbxoffvsorb)->GetXaxis()->SetTitle("Orbit"); (*m_hbxoffvsorb)->GetYaxis()->SetTitle("#Delta BX (SCAL-Event)");
(*m_hbxoffvsorb)->SetCanExtend(TH1::kXaxis);
}


}
// ------------ method called once each job just before starting event loop ------------
void
L1ABCDebugger::beginJob()
Expand Down
Expand Up @@ -11,7 +11,7 @@
cms.PSet(
ParameterName = cms.string("defaultPhases"),
ParameterType = cms.string("vint32"),
ParameterValue = cms.vint32(63,63,63,63),
ParameterValue = cms.vint32(66,66,66,66),
),
cms.PSet(
ParameterName = cms.string("useEC0"),
Expand All @@ -26,7 +26,7 @@
cms.PSet(
ParameterName = cms.string("magicOffset"),
ParameterType = cms.string("int"),
ParameterValue = cms.int32(8),
ParameterValue = cms.int32(9),
),
)

Expand Down

0 comments on commit 4504c50

Please sign in to comment.