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 allowed. 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 the information is 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 // 11th Oct. 2023: removed to prevent that corresponding training samples are generated. Still want to keep it to not forget how it is done.
183 /*
184 // same as config1 but allows the PXD layers
185 // default for VXD tracking (SVD+PXD)
186 SectorMapConfig config1point1;
187 config1point1.pTmin = 0.02; // minimal relevant version
188 config1point1.pTmax = 6.0; // minimal relevant version // Feb18-onePass-Test
189 config1point1.pTSmear = 0.;
190 config1point1.allowedLayers = {0, 1, 2, 3, 4, 5, 6};
191 config1point1.uSectorDivider = { .3, .7, 1.}; // standard relevant version
192 config1point1.vSectorDivider = { .3, .7, 1.}; // standard relevant version
193 config1point1.pdgCodesAllowed = {};
194 config1point1.seedMaxDist2IPXY = 23.5;
195 config1point1.seedMaxDist2IPZ = 23.5;
196 config1point1.nHitsMin = 3;
197 config1point1.vIP = B2Vector3D(0, 0, 0);
198 config1point1.secMapName = "SVDPXDDefault"; // has been: "lowTestSVDPXD";
199 config1point1.mField = 1.5;
200 config1point1.rarenessThreshold = 0.; //0.001;
201 config1point1.quantiles = {0., 1.}; //{0.005, 1. - 0.005};
202 bootstrapSectorMap(config1point1);
203 */
204}
205
206void
208{
211}
212
213void
215{
216
217 // TODO: change naming! This is poor naming as these include also Triplet filters!
219 segmentFilters->setConfig(config);
220
221 // TO DO: The whole information must be retrieved from the geometry
222 CompactSecIDs compactSecIds;
223
224 std::vector< double > uDividersMinusLastOne = config.uSectorDivider;
225 uDividersMinusLastOne.pop_back();
226 std::vector< double > vDividersMinusLastOne = config.vSectorDivider;
227 vDividersMinusLastOne.pop_back();
228
229
230 std::vector< std::vector< FullSecID > > sectors;
231
232 sectors.resize(config.uSectorDivider.size());
233 unsigned nSectorsInU = config.uSectorDivider.size(),
234 nSectorsInV = config.vSectorDivider.size();
235
236 // retrieve the full list of sensors from the geometry
237 const VXD::GeoCache& geometry = VXD::GeoCache::getInstance();
238 std::vector<VxdID> listOfSensors = geometry.getListOfSensors();
239 for (VxdID aSensorId : listOfSensors) {
240
241 // filter only those sensors on layers which are specified in the config
242 if (std::find(config.allowedLayers.begin(), config.allowedLayers.end(),
243 aSensorId.getLayerNumber()) == config.allowedLayers.end()) continue;
244
245 // for testbeams there might be other sensors in the geometry so filter for SVD and PXD only, as the CompactSecID dont like those!
246 VXD::SensorInfoBase::SensorType type = geometry.getSensorInfo(aSensorId).getType();
247 if (type != VXD::SensorInfoBase::SVD && type != VXD::SensorInfoBase::PXD) {
248 B2WARNING("Found sensor which is not PXD or SVD with VxdID: " << aSensorId << " ! Will skip that sensor ");
249 continue;
250 }
251
252 int counter = 0;
253 for (unsigned int i = 0; i < nSectorsInU; i++) {
254 sectors.at(i).resize(nSectorsInV);
255 for (unsigned int j = 0; j < nSectorsInV ; j++) {
256 sectors.at(i).at(j) = FullSecID(aSensorId, false, counter);
257 counter ++;
258 }
259 }
260 segmentFilters->addSectorsOnSensor(uDividersMinusLastOne,
261 vDividersMinusLastOne,
262 sectors) ;
263 }//end loop over sensors
264
265
266 // if layer 0 is specified in the config then the virtual IP is added
267 if (std::find(config.allowedLayers.begin(), config.allowedLayers.end(), 0) != config.allowedLayers.end()) {
268 std::vector<double> uCuts4vIP = {}, vCuts4vIP = {};
269 sectors.clear();
270 sectors = {{ FullSecID(0) }};
271 segmentFilters->addSectorsOnSensor(uCuts4vIP, vCuts4vIP, sectors);
272 }
273
274 // put config into the container
275 FiltersContainer<SpacePoint>::getInstance().assignFilters(config.secMapName, segmentFilters);
276
277}
278
279
281void
283{
284
285 // the "CREATE" option results in the root file not being opened if it already exists (to prevent overwriting existing sectormaps)
286 TFile rootFile(m_sectorMapsOutputFile.c_str(), "CREATE");
287 if (!rootFile.IsOpen()) B2FATAL("Unable to open rootfile! This could be caused by an already existing file of the same name: "
288 << m_sectorMapsOutputFile.c_str());
289
290 TTree* tree = new TTree(c_setupKeyNameTTreeName.c_str(),
292
293 TString setupKeyName;
294
295 tree->Branch(c_setupKeyNameBranchName.c_str(),
296 & setupKeyName);
297
299 for (auto singleSetupFilters : allSetupsFilters) {
300
301 setupKeyName = TString(singleSetupFilters.first.c_str());
302
303 tree->Fill();
304
305 rootFile.mkdir(setupKeyName, setupKeyName);
306 rootFile.cd(setupKeyName);
307
308 singleSetupFilters.second->persistOnRootFile();
309
310 rootFile.cd("..");
311
312 }
313
314 rootFile.Write();
315 rootFile.Close();
316
317
318}
319
320
322void
324{
325
326 std::string rootFileName = m_sectorMapsInputFile;
327 // if reading from the DB get the root file name from the DB object ptr
328 if (m_readSecMapFromDB) {
329 if (m_ptrDBObjPtr == nullptr) B2FATAL("SectorMapBootstrapModule: the pointer to the DB payload is not set!");
330 if (!(*m_ptrDBObjPtr).isValid()) B2FATAL("SectorMapBootstrapModule the DB object is not valid!");
331
332 rootFileName = (*m_ptrDBObjPtr)->getFileName();
333 }
334
335 B2DEBUG(29, "SectorMapBootstrapModule: retrieving new SectorMap. New file name: " << rootFileName);
336 TFile rootFile(rootFileName.c_str());
337
338 // some cross check that the file is open
339 if (!rootFile.IsOpen()) B2FATAL("The root file: " << rootFileName << " was not found.");
340
341 TTree* tree = nullptr;
342 rootFile.GetObject(c_setupKeyNameTTreeName.c_str(), tree);
343 if (tree == nullptr) B2FATAL("SectorMapBootstrapModule: tree not found! tree name: " << c_setupKeyNameTTreeName.c_str());
344
345 TString* setupKeyName = nullptr;
346 // cppcheck-suppress nullPointerRedundantCheck
347 tree->SetBranchAddress(c_setupKeyNameBranchName.c_str(),
348 & setupKeyName);
349 if (setupKeyName == nullptr) B2FATAL("SectorMapBootstrapModule: setupKeyName not found");
350
351 // ignore case, so only upper case
352 TString setupToRead_upper = m_setupToRead;
353 setupToRead_upper.ToUpper();
354
355 // to monitor if anything was read from the root files
356 bool read_something = false;
357
359 auto nEntries = tree->GetEntriesFast();
360 for (int i = 0; i < nEntries ; i++) {
361 tree->GetEntry(i);
362
363 // if a setup name is specified only read that one
364 if (setupToRead_upper != "") {
365 TString buff = setupKeyName->Data();
366 buff.ToUpper();
367 if (buff != setupToRead_upper) continue;
368 }
369
370 rootFile.cd(setupKeyName->Data());
371
372 B2DEBUG(29, "Retrieving SectorMap with name " << setupKeyName->Data());
373
375
376 std::string setupKeyNameStd = std::string(setupKeyName->Data());
377 segmentFilters->retrieveFromRootFile(setupKeyName);
378
379 // if the m_twoHitFilterAdjustFunctions m_threeHitFilterAdjustFunctions are non empty filters will be altered
380 if (m_twoHitFilterAdjustFunctions.size() > 0) {
381 B2WARNING("The 2-hit filters will be altered from the default!");
382 B2INFO("The following set of indizes and functions will be used to alter the 2-hit filters:");
383 for (auto& entry : m_twoHitFilterAdjustFunctions) {
384 B2INFO("index=" << std::get<0>(entry) << " function=" << std::get<1>(entry));
385 }
387 }
388 if (m_threeHitFilterAdjustFunctions.size() > 0) {
389 B2WARNING("The 3-hit filters will be altered from the default!");
390 B2INFO("The following set of indizes and functions will be used to alter the 3-hit filters:");
391 for (auto& entry : m_threeHitFilterAdjustFunctions) {
392 B2INFO("index=" << std::get<0>(entry) << " function=" << std::get<1>(entry));
393 }
395 }
396
397 // locks all functions that can modify the filters
398 segmentFilters->lockFilters();
399
400 B2DEBUG(29, "Retrieved map with name: " << setupKeyNameStd << " from rootfie.");
401 filtersContainer.assignFilters(setupKeyNameStd, segmentFilters);
402
403 rootFile.cd("..");
404
405 setupKeyName->Clear();
406
407 read_something = true;
408 }
409
410 if (!read_something) B2FATAL("SectorMapBootstrapModule: No setup was read from the root file! " <<
411 "The requested setup name was: " << m_setupToRead);
412
413 rootFile.Close();
414
415 // delete the TString which was allocated by ROOT but not cleaned up
416 if (setupKeyName != nullptr) {
417 delete setupKeyName;
418 }
419
420}
421
422
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 output 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).