Belle II Software development
SectorMapBootstrapModule.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 <iostream>
10
11#include <tracking/trackFindingVXD/filterMap/map/FiltersContainer.h>
12#include "tracking/trackFindingVXD/environment/VXDTFFilters.h"
13#include "tracking/modules/vxdtfRedesign/SectorMapBootstrapModule.h"
14//#include "tracking/dataobjects/VXDTFSecMap.h"
15#include "tracking/dataobjects/SectorMapConfig.h"
16#include <tracking/spacePointCreation/SpacePoint.h>
17
18// needed for complicated parameter types to not get an undefined reference error
19#include <framework/core/ModuleParam.templateDetails.h>
20
21#include <vxd/geometry/GeoCache.h>
22#include <vxd/geometry/SensorInfoBase.h>
23
24#include <TString.h>
25#include <TFile.h>
26#include <TTree.h>
27
28#include <algorithm>
29#include <fstream>
30
31
32using namespace Belle2;
33
34REG_MODULE(SectorMapBootstrap);
35
37{
38
40
41 setDescription("Create the VXDTF SectorMap for the following modules."
42 );
43
44 addParam("SectorMapsInputFile", m_sectorMapsInputFile,
45 "File from which the SectorMaps will be retrieved if\
46 ReadSectorMap is set to true", m_sectorMapsInputFile);
47
48 addParam("SectorMapsOutputFile", m_sectorMapsOutputFile,
49 "File into which the SectorMaps will be written if\
50 WriteSectorMap is set to true", m_sectorMapsOutputFile);
51
52 addParam("ReadSectorMap", m_readSectorMap, "If set to true \
53retrieve the SectorMaps from SectorMapsInputFile during initialize.", m_readSectorMap);
54
55 addParam("WriteSectorMap", m_writeSectorMap, "If set to true \
56at endRun write the SectorMaps to SectorMapsOutputFile.", m_writeSectorMap);
57
58 addParam("SetupToRead", m_setupToRead, "If non empty only the setup with the given name will be read"
59 " from the from the root file. All other will be ignored. If empty \"\" (default) all setups are read. Will "
60 "only used if sectormap is retrieved from root file. Case will be ignored!",
61 std::string(""));
62
63 addParam("ReadSecMapFromDB", m_readSecMapFromDB, "If set to true the sector map will be read from the Data Base. NOTE: this will "
64 "override the parameter ReadSectorMap (reading sector map from file)!!!", m_readSecMapFromDB);
65
66
67 // dummy vector needed to get the current structure of the filter
68 std::vector< std::pair<char, void*> > dummyVector = {};
69
71 // the structure is the same for all specializations of the template
72 std::string structure2HitFilter = empty2HitFilter.getNameAndReference(&dummyVector);
73 dummyVector.clear();
74 addParam("twoHitFilterAdjustFunctions", m_twoHitFilterAdjustFunctions,
75 "Vector of vectors containing expressions used to "
76 "alter the 2-hit filters. The inner vector should contain exactly two strings. The first entry is interpreted as index (integer). "
77 "The second entry is interpreted as function used to create a TF1. The variable to be altered will be assumed to be called \"x\" "
78 "and in addition one can use \"[0]\" can be used which will be interpreted as FullSecID of the static sector the filter is attached to. "
79 "No other parameter is allowed. The structure of the 2-hit filter is as follows: " + structure2HitFilter +
80 " Example: [(1, \"12\"), (3, \"sin(x)\"), (4, \"x + [0]\")] PS: use this feature only if you know what you are doing!",
82
84 // the structure is the same for all specializations of the template
85 std::string structure3HitFilter = empty3HitFilter.getNameAndReference(&dummyVector);
86 dummyVector.clear();
87 addParam("threeHitFilterAdjustFunctions", m_threeHitFilterAdjustFunctions,
88 "Vector of vectors containing expressions used to "
89 "alter the 3-hit filters. The inner vector should contain exactly two strings. The first entry is interpreted as index (integer). "
90 "The second entry is interpreted as function used to create a TF1. The variable to be altered will be assumed to be called \"x\" "
91 "and in addition \"[0]\" can be used which will be interpreted as FullSecID of the static sector the filter is attached to. No other "
92 "parameter is allowd. The structure of the 2-hit filter is as follows: " + structure3HitFilter +
93 " Example: [(1, \"12\"), (3, \"sin(x)\"), (4, \"x + [0]\")] PS: use this feature only if you know what you are doing!",
95}
96
97void
99{
100
101 // in case sector map is read from the DB one needs to set the DB pointer
102 if (m_readSecMapFromDB) {
103 B2DEBUG(29, "SectorMapBootstrapModule: Retrieving sectormap from DB. Filename: " << m_sectorMapsInputFile);
105 if (m_ptrDBObjPtr == nullptr) B2FATAL("SectorMapBootstrapModule: the DBObjPtr is not initialized");
106 // add a callback function so that the sectormap is updated each time the DBObj changes
108 }
109 // retrieve the SectorMap or create an empty one
112 else
114
115 // security measurement: test if output file exists so that existing sector maps are not overwritten
116 if (m_writeSectorMap) {
117 if (std::ifstream(m_sectorMapsOutputFile.c_str())) {
118 B2FATAL("Detected existing output file! Please delete or move before proceeding! File name: " << m_sectorMapsOutputFile);
119 } else {
120 B2DEBUG(29, "Checked that output file does not exist!");
121 }
122 }
123
124
125
126}
127
128void
130{
131}
132
133
134void
136{
137}
138
139void
141{
142
143
144 // TODO: Most of these informations are not used at all.
145 // It seems to me (EP) that only the SectorDividers are used.
146
147 // TODO: find a better way to put the configs into the framework
148
149 // WARNING: chose the names of the configs in that way that they are not contained in each other!
150 // E.g. having two configs with names "BobTheGreat" and "Bob" is not allowed as it will cause problems in some modules!
151
152
153 // for now declare this as default config for SVD only tracking!
154 SectorMapConfig config1;
155// config1.pTmin = 0.02;
156// config1.pTmax = 0.08;
157 config1.pTmin = 0.02; // minimal relevant version
158 config1.pTmax = 6.0; // minimal relevant version // Feb18-onePass-Test
159 config1.pTSmear = 0.;
160 config1.allowedLayers = {0, 3, 4, 5, 6};
161// config1.uSectorDivider = { .15, .5, .85, 1.};
162// config1.vSectorDivider = { .1, .3, .5, .7, .9, 1.};
163 config1.uSectorDivider = {.25, .5, .75, 1.}; // standard relevant version
164 config1.vSectorDivider = {.25, .5, .75, 1.}; // standard relevant version
165// config1.uSectorDivider = { .5, 1.}; // small relevant version
166// config1.vSectorDivider = { .5, 1.}; // small relevant version
167// config1.uSectorDivider = { 1.}; // minimal relevant version
168// config1.vSectorDivider = { 1.}; // minimal relevant version
169 config1.pdgCodesAllowed = {};
170 config1.seedMaxDist2IPXY = 23.5;
171 config1.seedMaxDist2IPZ = 23.5;
172 config1.nHitsMin = 3;
173 config1.vIP = B2Vector3D(0, 0, 0);
174 config1.secMapName = "SVDOnlyDefault"; // has been: "lowTestRedesign";
175 config1.mField = 1.5;
176 config1.rarenessThreshold = 0.; //0.001;
177 config1.quantiles = {0., 1.}; //{0.005, 1. - 0.005};
178 // TODO: still missing: minimal sample-size, quantiles for smaller samplesizes, threshshold small <-> big sampleSize.
179 bootstrapSectorMap(config1);
180
181
182 // same as config1 but allows the PXD layers
183 // default for VXD tracking (SVD+PXD)
184 SectorMapConfig config1point1;
185 config1point1.pTmin = 0.02; // minimal relevant version
186 config1point1.pTmax = 6.0; // minimal relevant version // Feb18-onePass-Test
187 config1point1.pTSmear = 0.;
188 config1point1.allowedLayers = {0, 1, 2, 3, 4, 5, 6};
189 config1point1.uSectorDivider = { .3, .7, 1.}; // standard relevant version
190 config1point1.vSectorDivider = { .3, .7, 1.}; // standard relevant version
191 config1point1.pdgCodesAllowed = {};
192 config1point1.seedMaxDist2IPXY = 23.5;
193 config1point1.seedMaxDist2IPZ = 23.5;
194 config1point1.nHitsMin = 3;
195 config1point1.vIP = B2Vector3D(0, 0, 0);
196 config1point1.secMapName = "SVDPXDDefault"; // has been: "lowTestSVDPXD";
197 config1point1.mField = 1.5;
198 config1point1.rarenessThreshold = 0.; //0.001;
199 config1point1.quantiles = {0., 1.}; //{0.005, 1. - 0.005};
200 bootstrapSectorMap(config1point1);
201
202}
203
204void
206{
209}
210
211void
213{
214
215 // TODO: change naming! This is poor naming as these include also Triplet filters!
217 segmentFilters->setConfig(config);
218
219 // TO DO: All these informations must be retrieved from the geometry
220 CompactSecIDs compactSecIds;
221
222 std::vector< double > uDividersMinusLastOne = config.uSectorDivider;
223 uDividersMinusLastOne.pop_back();
224 std::vector< double > vDividersMinusLastOne = config.vSectorDivider;
225 vDividersMinusLastOne.pop_back();
226
227
228 std::vector< std::vector< FullSecID > > sectors;
229
230 sectors.resize(config.uSectorDivider.size());
231 unsigned nSectorsInU = config.uSectorDivider.size(),
232 nSectorsInV = config.vSectorDivider.size();
233
234 // retrieve the full list of sensors from the geometry
235 const VXD::GeoCache& geometry = VXD::GeoCache::getInstance();
236 std::vector<VxdID> listOfSensors = geometry.getListOfSensors();
237 for (VxdID aSensorId : listOfSensors) {
238
239 // filter only those sensors on layers which are specified in the config
240 if (std::find(config.allowedLayers.begin(), config.allowedLayers.end(),
241 aSensorId.getLayerNumber()) == config.allowedLayers.end()) continue;
242
243 // for testbeams there might be other sensors in the geometry so filter for SVD and PXD only, as the CompactSecID dont like those!
244 VXD::SensorInfoBase::SensorType type = geometry.getSensorInfo(aSensorId).getType();
245 if (type != VXD::SensorInfoBase::SVD && type != VXD::SensorInfoBase::PXD) {
246 B2WARNING("Found sensor which is not PXD or SVD with VxdID: " << aSensorId << " ! Will skip that sensor ");
247 continue;
248 }
249
250 int counter = 0;
251 for (unsigned int i = 0; i < nSectorsInU; i++) {
252 sectors.at(i).resize(nSectorsInV);
253 for (unsigned int j = 0; j < nSectorsInV ; j++) {
254 sectors.at(i).at(j) = FullSecID(aSensorId, false, counter);
255 counter ++;
256 }
257 }
258 segmentFilters->addSectorsOnSensor(uDividersMinusLastOne,
259 vDividersMinusLastOne,
260 sectors) ;
261 }//end loop over sensors
262
263
264 // if layer 0 is specified in the config then the virtual IP is added
265 if (std::find(config.allowedLayers.begin(), config.allowedLayers.end(), 0) != config.allowedLayers.end()) {
266 std::vector<double> uCuts4vIP = {}, vCuts4vIP = {};
267 sectors.clear();
268 sectors = {{ FullSecID(0) }};
269 segmentFilters->addSectorsOnSensor(uCuts4vIP, vCuts4vIP, sectors);
270 }
271
272 // put config into the container
273 FiltersContainer<SpacePoint>::getInstance().assignFilters(config.secMapName, segmentFilters);
274
275}
276
277
279void
281{
282
283 // the "CREATE" option results in the root file not being opened if it already exists (to prevent overwriting existing sectormaps)
284 TFile rootFile(m_sectorMapsOutputFile.c_str(), "CREATE");
285 if (!rootFile.IsOpen()) B2FATAL("Unable to open rootfile! This could be caused by an already existing file of the same name: "
286 << m_sectorMapsOutputFile.c_str());
287
288 TTree* tree = new TTree(c_setupKeyNameTTreeName.c_str(),
290
291 TString setupKeyName;
292
293 tree->Branch(c_setupKeyNameBranchName.c_str(),
294 & setupKeyName);
295
297 for (auto singleSetupFilters : allSetupsFilters) {
298
299 setupKeyName = TString(singleSetupFilters.first.c_str());
300
301 tree->Fill();
302
303 rootFile.mkdir(setupKeyName, setupKeyName);
304 rootFile.cd(setupKeyName);
305
306 singleSetupFilters.second->persistOnRootFile();
307
308 rootFile.cd("..");
309
310 }
311
312 rootFile.Write();
313 rootFile.Close();
314
315
316}
317
318
320void
322{
323
324 std::string rootFileName = m_sectorMapsInputFile;
325 // if reading from the DB get the root file name from the DB object ptr
326 if (m_readSecMapFromDB) {
327 if (m_ptrDBObjPtr == nullptr) B2FATAL("SectorMapBootstrapModule: the pointer to the DB payload is not set!");
328 if (!(*m_ptrDBObjPtr).isValid()) B2FATAL("SectorMapBootstrapModule the DB object is not valid!");
329
330 rootFileName = (*m_ptrDBObjPtr)->getFileName();
331 }
332
333 B2DEBUG(29, "SectorMapBootstrapModule: retrieving new SectorMap. New file name: " << rootFileName);
334 TFile rootFile(rootFileName.c_str());
335
336 // some cross check that the file is open
337 if (!rootFile.IsOpen()) B2FATAL("The root file: " << rootFileName << " was not found.");
338
339 TTree* tree = nullptr;
340 rootFile.GetObject(c_setupKeyNameTTreeName.c_str(), tree);
341 if (tree == nullptr) B2FATAL("SectorMapBootstrapModule: tree not found! tree name: " << c_setupKeyNameTTreeName.c_str());
342
343 TString* setupKeyName = nullptr;
344 // cppcheck-suppress nullPointerRedundantCheck
345 tree->SetBranchAddress(c_setupKeyNameBranchName.c_str(),
346 & setupKeyName);
347 if (setupKeyName == nullptr) B2FATAL("SectorMapBootstrapModule: setupKeyName not found");
348
349 // ignore case, so only upper case
350 TString setupToRead_upper = m_setupToRead;
351 setupToRead_upper.ToUpper();
352
353 // to monitor if anything was read from the root files
354 bool read_something = false;
355
357 auto nEntries = tree->GetEntriesFast();
358 for (int i = 0; i < nEntries ; i++) {
359 tree->GetEntry(i);
360
361 // if a setup name is specified only read that one
362 if (setupToRead_upper != "") {
363 TString buff = setupKeyName->Data();
364 buff.ToUpper();
365 if (buff != setupToRead_upper) continue;
366 }
367
368 rootFile.cd(setupKeyName->Data());
369
370 B2DEBUG(29, "Retrieving SectorMap with name " << setupKeyName->Data());
371
373
374 std::string setupKeyNameStd = std::string(setupKeyName->Data());
375 segmentFilters->retrieveFromRootFile(setupKeyName);
376
377 // if the m_twoHitFilterAdjustFunctions m_threeHitFilterAdjustFunctions are non empty filters will be altered
378 if (m_twoHitFilterAdjustFunctions.size() > 0) {
379 B2WARNING("The 2-hit filters will be altered from the default!");
380 B2INFO("The following set of indizes and functions will be used to alter the 2-hit filters:");
381 for (auto& entry : m_twoHitFilterAdjustFunctions) {
382 B2INFO("index=" << std::get<0>(entry) << " function=" << std::get<1>(entry));
383 }
385 }
386 if (m_threeHitFilterAdjustFunctions.size() > 0) {
387 B2WARNING("The 3-hit filters will be altered from the default!");
388 B2INFO("The following set of indizes and functions will be used to alter the 3-hit filters:");
389 for (auto& entry : m_threeHitFilterAdjustFunctions) {
390 B2INFO("index=" << std::get<0>(entry) << " function=" << std::get<1>(entry));
391 }
393 }
394
395 // locks all functions that can modify the filters
396 segmentFilters->lockFilters();
397
398 B2DEBUG(29, "Retrieved map with name: " << setupKeyNameStd << " from rootfie.");
399 filtersContainer.assignFilters(setupKeyNameStd, segmentFilters);
400
401 rootFile.cd("..");
402
403 setupKeyName->Clear();
404
405 read_something = true;
406 }
407
408 if (!read_something) B2FATAL("SectorMapBootstrapModule: No setup was read from the root file! " <<
409 "The requested setup name was: " << m_setupToRead);
410
411 rootFile.Close();
412
413 // delete the TString which was allocated by ROOT but not cleaned up
414 if (setupKeyName != nullptr) {
415 delete setupKeyName;
416 }
417
418}
419
420
This class provides a computer convenient numbering scheme for the sectors in the sector map and for ...
Definition: CompactSecIDs.h:28
Class for accessing objects in the database.
Definition: DBObjPtr.h:21
This class contains everything needed by the VXDTF that is not going to change during a RUN,...
static FiltersContainer & getInstance()
one and only way to access the singleton object
void assignFilters(const std::string &setupName, VXDTFFilters< point_t > *filters)
assigns filters.
const setupNameToFilters_t & getAllSetups(void)
returns all the available setups.
Class to identify a sector inside of the VXD.
Definition: FullSecID.h:33
Base class for Modules.
Definition: Module.h:72
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
bool m_readSecMapFromDB
if true the sector map will be read from the DB. NOTE: this will override m_readSectorMap (read from ...
std::string m_sectorMapsInputFile
the name of the input root file the sectormaps are read from
void initialize() override
Initializer.
void event() override
This method is called for each event.
void endRun() override
This method is called if the current run ends.
std::vector< std::tuple< int, std::string > > m_twoHitFilterAdjustFunctions
vector of tuple<int, string> specifying how 2-hit filters are altered.
void bootstrapSectorMap(void)
puts several empty sectormaps into the framework
void beginRun() override
Called when entering a new run.
bool m_readSectorMap
if true a sectormap will be read from a file. NOTE: this will be overridden by m_readSecMapFromDB!
DBObjPtr< PayloadFile > * m_ptrDBObjPtr
pointer to the DBObjPtr for the payloadfile from which the sectormap is read
const std::string c_setupKeyNameBranchName
the name of the branch the setupt are stored in the tree
std::vector< std::tuple< int, std::string > > m_threeHitFilterAdjustFunctions
vector of tuple<int, string> specifying how 3-hit filters are altered.
const std::string c_setupKeyNameTTreeName
the name of the tree the setups are stored in in the root file
std::string m_setupToRead
if specified (non "") ONLY the setup with this name will be read. Else all setups in the root file wi...
std::string m_sectorMapsOutputFile
the name of the ouput root file the sectormaps are written to
void persistSectorMap(void)
writes a sectormap to a root file
void retrieveSectorMap(void)
retrieves SectorMap from file or from the DB
bool m_writeSectorMap
if true the sectormap will be written to an output file
Class that contains all the static sectors to which the filters are attached.
Definition: VXDTFFilters.h:63
int addSectorsOnSensor(const std::vector< double > &normalizedUsup, const std::vector< double > &normalizedVsup, const std::vector< std::vector< FullSecID > > &sectorIds)
To add an array of sectors on a sensor.
Definition: VXDTFFilters.h:142
bool retrieveFromRootFile(const TString *dirName)
Retrieves from the current TDirectory all the VXDTFFilters.
Definition: VXDTFFilters.h:307
decltype((0.<=DistanceInTimeUside< point_t >()<=0. &&0.<=DistanceInTimeVside< point_t >()<=0. &&0.<=Distance3DSquared< point_t >()<=0.&&0.<=Distance2DXYSquared< point_t >()<=0.&&0.<=Distance1DZ< point_t >()<=0.&&0.<=SlopeRZ< point_t >()<=0.&&0.<=Distance3DNormed< point_t >()<=0.)) twoHitFilter_t
minimal working 2-hits-example used for redesign of VXDTF.
Definition: VXDTFFilters.h:82
void modify2SPFilters(const std::vector< std::tuple< int, std::string > > &adjustFunctions)
modifies the 2SP-filters according to the functions given
Definition: VXDTFFilters.h:356
void lockFilters()
This function should be called only AFTER all adjustments to the filters have been performed.
Definition: VXDTFFilters.h:351
void setConfig(const SectorMapConfig &config)
set the configuration which is used to create this filter
Definition: VXDTFFilters.h:278
decltype((0.<=DistanceInTime< point_t >()<=0. &&0.<=Angle3DSimple< point_t >()<=0.&&0.<=CosAngleXY< point_t >()<=0.&&0.<=AngleRZSimple< point_t >()<=0.&&CircleDist2IP< point_t >()<=0.&&0.<=DeltaSlopeRZ< point_t >()<=0.&&0.<=DeltaSlopeZoverS< point_t >()<=0.&&0.<=DeltaSoverZ< point_t >()<=0.&&0.<=HelixParameterFit< point_t >()<=0.&&0.<=Pt< point_t >()<=0.&&0.<=CircleRadius< point_t >()<=0.)) threeHitFilter_t
minimal working example for 3-hits:
Definition: VXDTFFilters.h:112
void modify3SPFilters(const std::vector< std::tuple< int, std::string > > &adjustFunctions)
modifies the 3SP-filters according to the functions given
Definition: VXDTFFilters.h:373
Class to faciliate easy access to sensor information of the VXD like coordinate transformations or pi...
Definition: GeoCache.h:39
static GeoCache & getInstance()
Return a reference to the singleton instance.
Definition: GeoCache.cc:214
SensorType
Enum specifing the type of sensor the SensorInfo represents.
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
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:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
B2Vector3< double > B2Vector3D
typedef for common usage with double
Definition: B2Vector3.h:516
Abstract base class for different kinds of events.
simple struct containing all the configuration data needed for the SecMapTrainer.
double pTmin
stores pTCuts for min pT allowed for this .
std::vector< double > vSectorDivider
Defines the sectors boundaries in normalized v coordinates (i.e.
double pTSmear
allows smearing of the cuts.
std::vector< int > pdgCodesAllowed
Stores all the pdgCodes which are allowed to be used by the SecMap.
double mField
Magnetic field value to be set for the filters.
double seedMaxDist2IPXY
Stores a cut for maximum distance of the seed in xy of the given virtual IP.
std::pair< double, double > quantiles
the quantiles to be chosen in the end for determining the cuts first is quantile, second is 1-quantil...
std::vector< double > uSectorDivider
Defines the sectors boundaries in normalized u coordinates (i.e.
double rarenessThreshold
defined 1 == 100%, if relative frequency of sec-combi to the outer-sector is less than threshold,...
std::string secMapName
Sets the human readable proto-name of the sectorMap.
B2Vector3D vIP
Stores the position of the assumed position of the interaction point - The virtual IP.
double seedMaxDist2IPZ
Stores a cut for maximum distance of the seed in z of the given virtual IP.
double pTmax
stores pTCuts for min (.first) and max (.second) ptCut.
unsigned nHitsMin
Stores the minimal number of hits a TC must have to be accepted as TC (vIP-Hits are ignored).
std::vector< int > allowedLayers
stores allowed layers to be used (including virtual IP with layer 0).