Belle II Software development
SVDDQMEfficiencyModule.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <svd/modules/svdDQM/SVDDQMEfficiencyModule.h>
10#include <hlt/softwaretrigger/core/FinalTriggerDecisionCalculator.h>
11#include <svd/dataobjects/SVDEventInfo.h>
12
13#include "TDirectory.h"
14
15#include <cmath>
16
17using namespace Belle2;
18using namespace SoftwareTrigger;
19
20//-----------------------------------------------------------------
21// Register the Module
22//-----------------------------------------------------------------
23REG_MODULE(SVDDQMEfficiency);
24
25//-----------------------------------------------------------------
26// Implementation
27//-----------------------------------------------------------------
28
30{
31 // Set module properties
32 setDescription("Create basic histograms to compute the average sensor efficiency.");
33
34 // What exactly is needed for this to be true?
36
37 // Parameter definitions
38 addParam("Clusters", m_svdClustersName, "name of StoreArray with SVD cluster.", std::string(""));
39 addParam("Intercepts", m_interceptsName, "name of StoreArray with SVDIntercepts.", std::string(""));
40
41 addParam("histogramDirectoryName", m_histogramDirectoryName, "Name of the directory where histograms will be placed.",
42 std::string("SVDEfficiency"));
43
44 addParam("binsU", m_u_bins, "histogram bins in u direction.", int(4));
45 addParam("binsV", m_v_bins, "histogram bins in v direction.", int(6));
46
47
48 addParam("saveExpertHistos", m_saveExpertHistos, "if True, save additional histograms.", bool(false));
49
50 addParam("minSVDHits", m_minSVDHits, "Number of SVD hits required in a track to be considered.", 1u);
51 addParam("minCDCHits", m_minCDCHits, "Number of CDC hits required in a track to be considered.", 20u);
52
53 addParam("pValCut", m_pcut, "Set a cut on the track p-value.", double(0));
54 // addParam("d0Cut", m_d0cut, "|d0| smaller than the cut", double(0.5));
55 // addParam("z0Cut", m_z0cut, "|z0| smaller than the cut", double(2));
56
57 addParam("momCut", m_momCut, "Set a cut on the track momentum.", double(0));
58 addParam("ptCut", m_ptCut, "Set a cut on the track transverse momentum.", double(1));
59
60 addParam("fiducialU", m_fiducialU, "Fiducial Area, U direction.", float(0.5));
61 addParam("fiducialV", m_fiducialV, "Fiducial Area, V direction.", float(0.5));
62 addParam("maxHalfResidU", m_maxResidU, "half window for cluster search around intercept, U direction.", float(0.05));
63 addParam("maxHalfResidV", m_maxResidV, "half window for cluster search around intercept, V direction.", float(0.05));
64 addParam("useParamFromDB", m_useParamFromDB, "use SVDDQMPlotsConfiguration from DB", bool(true));
65 addParam("skipHLTRejectedEvents", m_skipRejectedEvents, "If True, skip events rejected by HLT.", bool(false));
66 addParam("samples3", m_3Samples, "if True 3 samples histograms analysis is performed", bool(false));
67}
68
69
71{
72 //calls the define histogram function
73 REG_HISTOGRAM;
74
75 //register the required arrays
76 //Register as optional so validation for cases where they are not available still succeeds, but module will not do any meaningful work without them
79 m_recoTracks.isOptional();
80
81}
82
83
85{
88 if (!eventAccepted) return;
89 }
90
91 if (!m_svdClusters.isValid()) {
92 B2INFO("SVDClusters array is missing, no SVD efficiencies");
93 return;
94 }
95 if (!m_intercepts.isValid()) {
96 B2INFO("SVDIntercepts array is missing, no SVD efficiencies");
97 return;
98 }
99
100 if (!m_recoTracks.isValid()) {
101 B2INFO("RecoTracks array is missing, no SVD efficiencies");
102 return;
103 }
104
105 std::string m_svdEventInfoName = "SVDEventInfo";
106 StoreObjPtr<SVDEventInfo> eventinfo(m_svdEventInfoName);
107
108 int nSamples = 0;
109 if (eventinfo.isValid())
110 nSamples = eventinfo->getNSamples();
111 else
112 return;
113
114 //intercepts
115 for (int inter = 0 ; inter < m_intercepts.getEntries(); inter++) {
116
117 if (!isGoodIntercept(m_intercepts[inter]))
118 continue;
119
120 B2DEBUG(10, "this intercept is related to a good track");
121
122 VxdID::baseType theVxdID = (VxdID::baseType)m_intercepts[inter]->getSensorID();
123 double coorU = m_intercepts[inter]->getCoorU();
124 double coorV = m_intercepts[inter]->getCoorV();
125 VXD::SensorInfoBase info = m_geoCache.getSensorInfo(theVxdID);
126 int cellU = info.getUCellID(coorU);
127 int cellV = info.getVCellID(coorV);
128
129 const VXD::SensorInfoBase& theSensorInfo = m_geoCache.getSensorInfo(theVxdID);
130 if (theSensorInfo.inside(coorU, coorV, -m_fiducialU, -m_fiducialV)) {
131
132 //This track should be on the sensor
134 m_h_track_hits[theVxdID]->Fill(cellU, cellV);
135
136 m_TrackHits->fill(theVxdID, 0, 1);
137 m_TrackHits->fill(theVxdID, 1, 1);
138
139 if (m_3Samples) {
140 if (nSamples == 3) {
141 m_TrackHits3Sample->fill(theVxdID, 0, 1);
142 m_TrackHits3Sample->fill(theVxdID, 1, 1);
143 } else {
144 m_TrackHits6Sample->fill(theVxdID, 0, 1);
145 m_TrackHits6Sample->fill(theVxdID, 1, 1);
146 }
147 }
148
149 bool foundU = false;
150 bool foundV = false;
151
152 //loop on clusters
153 for (int cls = 0 ; cls < m_svdClusters.getEntries(); cls++) {
154
155 VxdID::baseType clVxdID = (VxdID::baseType)m_svdClusters[cls]->getSensorID();
156 if (clVxdID != theVxdID)
157 continue;
158
159 double maxResid = m_maxResidV;
160 double interCoor = coorV;
161 double resid = interCoor - m_svdClusters[cls]->getPosition();
162 if (m_svdClusters[cls]->isUCluster()) {
163 interCoor = coorU;
164 maxResid = m_maxResidU;
165 resid = interCoor - m_svdClusters[cls]->getPosition(coorV);
166 }
167
168
169 if (std::abs(resid) < maxResid) {
170 if (m_svdClusters[cls]->isUCluster()) {
171 foundU = true;
172 } else
173 foundV = true;
174 }
175
176 if (foundU && foundV)
177 break;
178 }
179
180 if (foundU) {
181 m_MatchedHits->fill(theVxdID, 1, 1);
182 if (m_3Samples) {
183 if (nSamples == 3)
184 m_MatchedHits3Sample->fill(theVxdID, 1, 1);
185 else
186 m_MatchedHits6Sample->fill(theVxdID, 1, 1);
187 }
188
189 if (m_saveExpertHistos) {
190 m_h_matched_clusterU[theVxdID]->Fill(cellU, cellV);
191 if (m_3Samples) {
192 if (nSamples == 3)
193 m_h_matched3_clusterU[theVxdID]->Fill(cellU, cellV);
194 else
195 m_h_matched6_clusterU[theVxdID]->Fill(cellU, cellV);
196 }
197 }
198 }
199
200 if (foundV) {
201 m_MatchedHits->fill(theVxdID, 0, 1);
202 if (m_3Samples) {
203 if (nSamples == 3)
204 m_MatchedHits3Sample->fill(theVxdID, 0, 1);
205 else
206 m_MatchedHits6Sample->fill(theVxdID, 0, 1);
207 }
208
209 if (m_saveExpertHistos) {
210 m_h_matched_clusterV[theVxdID]->Fill(cellU, cellV);
211 if (m_3Samples) {
212 if (nSamples == 3)
213 m_h_matched3_clusterV[theVxdID]->Fill(cellU, cellV);
214 else
215 m_h_matched6_clusterV[theVxdID]->Fill(cellU, cellV);
216 }
217 }
218 }
219
220 }
221 }
222}
223
225{
226 if (m_useParamFromDB) {
227 if (!m_svdPlotsConfig.isValid())
228 B2FATAL("no valid configuration found for SVD reconstruction");
229 else {
230 B2DEBUG(20, "SVDRecoConfiguration: from now on we are using " << m_svdPlotsConfig->get_uniqueID());
231 m_3Samples = m_svdPlotsConfig->isPlotsFor3SampleMonitoring();
232 m_skipRejectedEvents = m_svdPlotsConfig->isSkipHLTRejectedEvents();
233 }
234 }
235
236 // Create a separate histogram directory and cd into it.
237 TDirectory* oldDir = gDirectory;
238 if (m_histogramDirectoryName != "") {
239 oldDir->mkdir(m_histogramDirectoryName.c_str());
240 oldDir->cd(m_histogramDirectoryName.c_str());
241 }
242 m_TrackHits = new SVDSummaryPlots("TrackHits@view", "Number of Tracks intercepting the @view/@side Side");
243 m_MatchedHits = new SVDSummaryPlots("MatchedHits@view", "Number of Matched Clusters on the @view/@side Side");
244
245 if (m_3Samples) {
246 m_TrackHits3Sample = new SVDSummaryPlots("TrackHits3@view", "Number of Tracks intercepting the @view/@side Side for 3 samples");
247 m_TrackHits6Sample = new SVDSummaryPlots("TrackHits6@view", "Number of Tracks intercepting the @view/@side Side for 6 samples");
248 m_MatchedHits3Sample = new SVDSummaryPlots("MatchedHits3@view", "Number of Matched Clusters on the @view/@side Side for 3 samples");
249 m_MatchedHits6Sample = new SVDSummaryPlots("MatchedHits6@view", "Number of Matched Clusters on the @view/@side Side for 6 samples");
250 }
251
252 if (!m_saveExpertHistos) {
253 oldDir->cd();
254 return;
255 }
256
257 std::vector<VxdID> sensors = m_geoCache.getListOfSensors();
258 for (VxdID& avxdid : sensors) {
259 VXD::SensorInfoBase info = m_geoCache.getSensorInfo(avxdid);
260 if (info.getType() != VXD::SensorInfoBase::SVD) continue;
261 //Only interested in SVD sensors
262
263 TString buff = (std::string)avxdid;
264 buff.ReplaceAll(".", "_");
265
266 int nu = info.getUCells();
267 int nv = info.getVCells();
268
269 m_h_track_hits[avxdid] = new TH2D("track_hits_" + buff, "tracks through sensor " + buff,
270 m_u_bins, -0.5, nu - 0.5, m_v_bins, -0.5, nv - 0.5);
271 m_h_matched_clusterU[avxdid] = new TH2D("matched_clusterU_" + buff, "track intersections with a matched U cluster" + buff,
272 m_u_bins, -0.5, nu - 0.5, m_v_bins, -0.5, nv - 0.5);
273 m_h_matched_clusterV[avxdid] = new TH2D("matched_clusterV_" + buff, "track intersections with a matched V cluster" + buff,
274 m_u_bins, -0.5, nu - 0.5, m_v_bins, -0.5, nv - 0.5);
275
276 if (m_3Samples) {
277 m_h_matched3_clusterU[avxdid] = new TH2D("matched3_clusterU_" + buff,
278 "track intersections with a matched U cluster for 3 samples" + buff,
279 m_u_bins, -0.5, nu - 0.5, m_v_bins, -0.5, nv - 0.5);
280 m_h_matched3_clusterV[avxdid] = new TH2D("matched3_clusterV_" + buff,
281 "track intersections with a matched V cluster for 3 samples" + buff,
282 m_u_bins, -0.5, nu - 0.5, m_v_bins, -0.5, nv - 0.5);
283
284 m_h_matched6_clusterU[avxdid] = new TH2D("matched6_clusterU_" + buff,
285 "track intersections with a matched U cluster for 6 samples" + buff,
286 m_u_bins, -0.5, nu - 0.5, m_v_bins, -0.5, nv - 0.5);
287 m_h_matched6_clusterV[avxdid] = new TH2D("matched6_clusterV_" + buff,
288 "track intersections with a matched V cluster for 6 samples" + buff,
289 m_u_bins, -0.5, nu - 0.5, m_v_bins, -0.5, nv - 0.5);
290 }
291 }
292 // cd back to root directory
293 oldDir->cd();
294}
295
296
297
299{
300
302
303 if (theRC.size() == 0)
304 return false;
305
306 //If fit failed assume position pointed to is useless anyway
307 if (!theRC[0]->wasFitSuccessful()) return false;
308
309 if (theRC[0]->getNumberOfSVDHits() < m_minSVDHits) return false;
310
311 if (theRC[0]->getNumberOfCDCHits() < m_minCDCHits) return false;
312
313 const genfit::FitStatus* fitstatus = theRC[0]->getTrackFitStatus();
314 if (fitstatus->getPVal() < m_pcut) return false;
315
316 genfit::MeasuredStateOnPlane trackstate;
317 trackstate = theRC[0]->getMeasuredStateOnPlaneFromFirstHit();
318 if (trackstate.getMom().Mag() < m_momCut) return false;
319
320 if (trackstate.getMom().Perp() < m_ptCut) return false;
321
322 return true;
323
324}
static RelationVector< T > getRelationsWithObj(const TObject *object, const std::string &name="", const std::string &namedRelation="")
Get the relations between an object and other objects in a store array.
Definition DataStore.h:412
HistoModule()
Constructor.
Definition HistoModule.h:32
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition Module.h:80
Class for type safe access to objects that are referred to in relations.
size_t size() const
Get number of relations.
float m_fiducialV
stay away from the U border by m_fiducialU (in cm)
bool m_useParamFromDB
if true read back from DB configuration parameters
SVDDQMEfficiencyModule()
Constructor: Sets the description, the properties and the parameters of the module.
std::string m_svdClustersName
SVDClusters StoreArray name.
std::map< VxdID, TH2D * > m_h_track_hits
track hits histogram map to sensorID
void initialize() override final
initializes the need store arrays, trees and histograms
unsigned int m_minCDCHits
Required hits in CDC for tracks.
bool m_saveExpertHistos
save additional histograms id set True
std::map< VxdID, TH2D * > m_h_matched6_clusterV
matched V-hits histogram map to sensorID for 6 samples
StoreArray< SVDIntercept > m_intercepts
SVDIntercept StoreArray.
bool m_skipRejectedEvents
if true skip events rejected by HLT
SVDSummaryPlots * m_MatchedHits3Sample
matched hits summary plot for 3 samples
VXD::GeoCache & m_geoCache
BelleII Geometry.
std::map< VxdID, TH2D * > m_h_matched3_clusterV
matched V-hits histogram map to sensorID for 3 samples
unsigned int m_minSVDHits
Required hits in SVD strips for tracks.
StoreArray< SVDCluster > m_svdClusters
SVDCluster StoreArray.
double m_momCut
Cut on fitted track momentum.
int m_u_bins
number of U-bins for expert histogram
std::map< VxdID, TH2D * > m_h_matched_clusterU
matched U-hits histogram map to sensorID
std::map< VxdID, TH2D * > m_h_matched6_clusterU
matched U-hits histogram map to sensorID for 6 samples
float m_fiducialU
stay away from the U border by m_fiducialU (in cm)
void defineHisto() override final
actually defines the trees and histograms
DBObjPtr< SVDDQMPlotsConfiguration > m_svdPlotsConfig
SVD DQM plots configuration.
double m_pcut
pValue-Cut for tracks
bool isGoodIntercept(SVDIntercept *inter)
returns true if the track related to the intercept passes the selection cuts
void event() override final
main function which fills trees and histograms
std::string m_histogramDirectoryName
name of the directory where to store the histograms
float m_maxResidV
max distance cut in cm V side
bool m_3Samples
if true enable 3 samples histograms analysis
SVDSummaryPlots * m_MatchedHits6Sample
matched hits summary plot for 6 samples
std::map< VxdID, TH2D * > m_h_matched3_clusterU
matched U-hits histogram map to sensorID for 3 samples
int m_v_bins
number of V-bins for expert histogram
SVDSummaryPlots * m_MatchedHits
matched hits summary plot
SVDSummaryPlots * m_TrackHits
track hits summary plot
StoreArray< RecoTrack > m_recoTracks
RecoTrack StoreArray.
double m_ptCut
Cut on fitted track pt.
StoreObjPtr< SoftwareTriggerResult > m_resultStoreObjectPointer
Store Object for reading the trigger decision.
std::string m_interceptsName
SVDIntercepts StoreArray name.
SVDSummaryPlots * m_TrackHits3Sample
track hits summary plot for 3 samples
std::map< VxdID, TH2D * > m_h_matched_clusterV
matched V-hits histogram map to sensorID
SVDSummaryPlots * m_TrackHits6Sample
track hits summary plot for 6 samples
float m_maxResidU
max distance cut in cm U side
SVDIntercept stores the U,V coordinates and uncertainties of the intersection of a track with an SVD ...
class to summarize SVD quantities per sensor and side
static bool getFinalTriggerDecision(const SoftwareTriggerResult &result, bool forgetTotalResult=false)
Calculate the final cut decision using all "total_results" of all sub triggers in the software trigge...
Type-safe access to single objects in the data store.
Definition StoreObjPtr.h:96
Base class to provide Sensor Information for PXD and SVD.
bool inside(double u, double v, double uTolerance=DBL_EPSILON, double vTolerance=DBL_EPSILON) const
Check whether a given point is inside the active area.
Class to uniquely identify a any structure of the PXD and SVD.
Definition VxdID.h:33
unsigned short baseType
The base integer type for VxdID.
Definition VxdID.h:36
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition Module.h:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
Namespace to provide code needed by both Vertex Detectors, PXD and SVD, and also testbeam telescopes.
Definition GeoCache.h:34
Abstract base class for different kinds of events.