Belle II Software  release-06-00-14
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 
32 using namespace Belle2;
33 using namespace std;
34 
35 REG_MODULE(SectorMapBootstrap);
36 
38 {
39 
41 
42  setDescription("Create the VXDTF SectorMap for the following modules."
43  );
44 
45  addParam("SectorMapsInputFile", m_sectorMapsInputFile,
46  "File from which the SectorMaps will be retrieved if\
47  ReadSectorMap is set to true", m_sectorMapsInputFile);
48 
49  addParam("SectorMapsOutputFile", m_sectorMapsOutputFile,
50  "File into which the SectorMaps will be written if\
51  WriteSectorMap is set to true", m_sectorMapsOutputFile);
52 
53  addParam("ReadSectorMap", m_readSectorMap, "If set to true \
54 retrieve the SectorMaps from SectorMapsInputFile during initialize.", m_readSectorMap);
55 
56  addParam("WriteSectorMap", m_writeSectorMap, "If set to true \
57 at endRun write the SectorMaps to SectorMapsOutputFile.", m_writeSectorMap);
58 
59  addParam("SetupToRead", m_setupToRead, "If non empty only the setup with the given name will be read"
60  " from the from the root file. All other will be ignored. If empty \"\" (default) all setups are read. Will "
61  "only used if sectormap is retrieved from root file. Case will be ignored!",
62  std::string(""));
63 
64  addParam("ReadSecMapFromDB", m_readSecMapFromDB, "If set to true the sector map will be read from the Data Base. NOTE: this will "
65  "override the parameter ReadSectorMap (reading sector map from file)!!!", m_readSecMapFromDB);
66 
67 
68  // dummy vector needed to get the current structure of the filter
69  std::vector< std::pair<char, void*> > dummyVector = {};
70 
72  // the structure is the same for all specializations of the template
73  std::string structure2HitFilter = empty2HitFilter.getNameAndReference(&dummyVector);
74  dummyVector.clear();
75  addParam("twoHitFilterAdjustFunctions", m_twoHitFilterAdjustFunctions,
76  "Vector of vectors containing expressions used to "
77  "alter the 2-hit filters. The inner vector should contain exactly two strings. The first entry is interpreted as index (integer). "
78  "The second entry is interpreted as function used to create a TF1. The variable to be altered will be assumed to be called \"x\" "
79  "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. "
80  "No other parameter is allowed. The structure of the 2-hit filter is as follows: " + structure2HitFilter +
81  " Example: [(1, \"12\"), (3, \"sin(x)\"), (4, \"x + [0]\")] PS: use this feature only if you know what you are doing!",
83 
85  // the structure is the same for all specializations of the template
86  std::string structure3HitFilter = empty3HitFilter.getNameAndReference(&dummyVector);
87  dummyVector.clear();
88  addParam("threeHitFilterAdjustFunctions", m_threeHitFilterAdjustFunctions,
89  "Vector of vectors containing expressions used to "
90  "alter the 3-hit filters. The inner vector should contain exactly two strings. The first entry is interpreted as index (integer). "
91  "The second entry is interpreted as function used to create a TF1. The variable to be altered will be assumed to be called \"x\" "
92  "and in addition \"[0]\" can be used which will be interpreted as FullSecID of the static sector the filter is attached to. No other "
93  "parameter is allowd. The structure of the 2-hit filter is as follows: " + structure3HitFilter +
94  " Example: [(1, \"12\"), (3, \"sin(x)\"), (4, \"x + [0]\")] PS: use this feature only if you know what you are doing!",
96 }
97 
98 void
100 {
101 
102  // in case sector map is read from the DB one needs to set the DB pointer
103  if (m_readSecMapFromDB) {
104  B2DEBUG(1, "SectorMapBootstrapModule: Retrieving sectormap from DB. Filename: " << m_sectorMapsInputFile);
106  if (m_ptrDBObjPtr == nullptr) B2FATAL("SectorMapBootstrapModule: the DBObjPtr is not initialized");
107  // add a callback function so that the sectormap is updated each time the DBObj changes
109  }
110  // retrieve the SectorMap or create an empty one
113  else
115 
116  // security measurement: test if output file exists so that existing sector maps are not overwritten
117  if (m_writeSectorMap) {
118  if (std::ifstream(m_sectorMapsOutputFile.c_str())) {
119  B2FATAL("Detected existing output file! Please delete or move before proceeding! File name: " << m_sectorMapsOutputFile);
120  } else {
121  B2DEBUG(1, "Checked that output file does not exist!");
122  }
123  }
124 
125 
126 
127 }
128 
129 void
131 {
132 }
133 
134 
135 void
137 {
138 }
139 
140 void
142 {
143 
144 
145  // TODO: Most of these informations are not used at all.
146  // It seems to me (EP) that only the SectorDividers are used.
147 
148  // TODO: find a better way to put the configs into the framework
149 
150  // WARNING: chose the names of the configs in that way that they are not contained in each other!
151  // E.g. having two configs with names "BobTheGreat" and "Bob" is not allowed as it will cause problems in some modules!
152 
153 
154  // for now declare this as default config for SVD only tracking!
155  SectorMapConfig config1;
156 // config1.pTmin = 0.02;
157 // config1.pTmax = 0.08;
158  config1.pTmin = 0.02; // minimal relevant version
159  config1.pTmax = 6.0; // minimal relevant version // Feb18-onePass-Test
160  config1.pTSmear = 0.;
161  config1.allowedLayers = {0, 3, 4, 5, 6};
162 // config1.uSectorDivider = { .15, .5, .85, 1.};
163 // config1.vSectorDivider = { .1, .3, .5, .7, .9, 1.};
164  config1.uSectorDivider = {.25, .5, .75, 1.}; // standard relevant version
165  config1.vSectorDivider = {.25, .5, .75, 1.}; // standard relevant version
166 // config1.uSectorDivider = { .5, 1.}; // small relevant version
167 // config1.vSectorDivider = { .5, 1.}; // small relevant version
168 // config1.uSectorDivider = { 1.}; // minimal relevant version
169 // config1.vSectorDivider = { 1.}; // minimal relevant version
170  config1.pdgCodesAllowed = {};
171  config1.seedMaxDist2IPXY = 23.5;
172  config1.seedMaxDist2IPZ = 23.5;
173  config1.nHitsMin = 3;
174  config1.vIP = B2Vector3D(0, 0, 0);
175  config1.secMapName = "SVDOnlyDefault"; // has been: "lowTestRedesign";
176  config1.mField = 1.5;
177  config1.rarenessThreshold = 0.; //0.001;
178  config1.quantiles = {0., 1.}; //{0.005, 1. - 0.005};
179  // TODO: still missing: minimal sample-size, quantiles for smaller samplesizes, threshshold small <-> big sampleSize.
180  bootstrapSectorMap(config1);
181 
182 
183  // same as config1 but allows the PXD layers
184  // default for VXD tracking (SVD+PXD)
185  SectorMapConfig config1point1;
186  config1point1.pTmin = 0.02; // minimal relevant version
187  config1point1.pTmax = 6.0; // minimal relevant version // Feb18-onePass-Test
188  config1point1.pTSmear = 0.;
189  config1point1.allowedLayers = {0, 1, 2, 3, 4, 5, 6};
190  config1point1.uSectorDivider = { .3, .7, 1.}; // standard relevant version
191  config1point1.vSectorDivider = { .3, .7, 1.}; // standard relevant version
192  config1point1.pdgCodesAllowed = {};
193  config1point1.seedMaxDist2IPXY = 23.5;
194  config1point1.seedMaxDist2IPZ = 23.5;
195  config1point1.nHitsMin = 3;
196  config1point1.vIP = B2Vector3D(0, 0, 0);
197  config1point1.secMapName = "SVDPXDDefault"; // has been: "lowTestSVDPXD";
198  config1point1.mField = 1.5;
199  config1point1.rarenessThreshold = 0.; //0.001;
200  config1point1.quantiles = {0., 1.}; //{0.005, 1. - 0.005};
201  bootstrapSectorMap(config1point1);
202 
203 }
204 
205 void
207 {
208  if (m_writeSectorMap)
210 }
211 
212 void
214 {
215 
216  // TODO: change naming! This is poor naming as these include also Triplet filters!
217  VXDTFFilters<SpacePoint>* segmentFilters = new VXDTFFilters<SpacePoint>();
218  segmentFilters->setConfig(config);
219 
220  // TO DO: All these informations must be retrieved from the geometry
221  CompactSecIDs compactSecIds;
222 
223  vector< double > uDividersMinusLastOne = config.uSectorDivider;
224  uDividersMinusLastOne.pop_back();
225  vector< double > vDividersMinusLastOne = config.vSectorDivider;
226  vDividersMinusLastOne.pop_back();
227 
228 
229  vector< vector< FullSecID > > sectors;
230 
231  sectors.resize(config.uSectorDivider.size());
232  unsigned nSectorsInU = config.uSectorDivider.size(),
233  nSectorsInV = config.vSectorDivider.size();
234 
235  // retrieve the full list of sensors from the geometry
236  const VXD::GeoCache& geometry = VXD::GeoCache::getInstance();
237  std::vector<VxdID> listOfSensors = geometry.getListOfSensors();
238  for (VxdID aSensorId : listOfSensors) {
239 
240  // filter only those sensors on layers which are specified in the config
241  if (std::find(config.allowedLayers.begin(), config.allowedLayers.end(),
242  aSensorId.getLayerNumber()) == config.allowedLayers.end()) continue;
243 
244  // for testbeams there might be other sensors in the geometry so filter for SVD and PXD only, as the CompactSecID dont like those!
245  VXD::SensorInfoBase::SensorType type = geometry.getSensorInfo(aSensorId).getType();
246  if (type != VXD::SensorInfoBase::SVD && type != VXD::SensorInfoBase::PXD) {
247  B2WARNING("Found sensor which is not PXD or SVD with VxdID: " << aSensorId << " ! Will skip that sensor ");
248  continue;
249  }
250 
251  int counter = 0;
252  for (unsigned int i = 0; i < nSectorsInU; i++) {
253  sectors.at(i).resize(nSectorsInV);
254  for (unsigned int j = 0; j < nSectorsInV ; j++) {
255  sectors.at(i).at(j) = FullSecID(aSensorId, false, counter);
256  counter ++;
257  }
258  }
259  segmentFilters->addSectorsOnSensor(uDividersMinusLastOne ,
260  vDividersMinusLastOne,
261  sectors) ;
262  }//end loop over sensors
263 
264 
265  // if layer 0 is specified in the config then the virtual IP is added
266  if (std::find(config.allowedLayers.begin(), config.allowedLayers.end(), 0) != config.allowedLayers.end()) {
267  std::vector<double> uCuts4vIP = {}, vCuts4vIP = {};
268  sectors.clear();
269  sectors = {{ FullSecID(0) }};
270  segmentFilters->addSectorsOnSensor(uCuts4vIP, vCuts4vIP, sectors);
271  }
272 
273  // put config into the container
274  FiltersContainer<SpacePoint>::getInstance().assignFilters(config.secMapName, segmentFilters);
275 
276 }
277 
278 
280 void
282 {
283 
284  // the "CREATE" option results in the root file not being opened if it already exists (to prevent overwriting existing sectormaps)
285  TFile rootFile(m_sectorMapsOutputFile.c_str() , "CREATE");
286  if (!rootFile.IsOpen()) B2FATAL("Unable to open rootfile! This could be caused by an already existing file of the same name: "
287  << m_sectorMapsOutputFile.c_str());
288 
289  TTree* tree = new TTree(c_setupKeyNameTTreeName.c_str(),
290  c_setupKeyNameTTreeName.c_str());
291 
292  TString setupKeyName;
293 
294  tree->Branch(c_setupKeyNameBranchName.c_str(),
295  & setupKeyName);
296 
297  auto allSetupsFilters = FiltersContainer<SpacePoint>::getInstance().getAllSetups();
298  for (auto singleSetupFilters : allSetupsFilters) {
299 
300  setupKeyName = TString(singleSetupFilters.first.c_str());
301 
302  tree->Fill();
303 
304  rootFile.mkdir(setupKeyName, setupKeyName);
305  rootFile.cd(setupKeyName);
306 
307  singleSetupFilters.second->persistOnRootFile();
308 
309  rootFile.cd("..");
310 
311  }
312 
313  rootFile.Write();
314  rootFile.Close();
315 
316 
317 }
318 
319 
321 void
323 {
324 
325  std::string rootFileName = m_sectorMapsInputFile;
326  // if reading from the DB get the root file name from the DB object ptr
327  if (m_readSecMapFromDB) {
328  if (m_ptrDBObjPtr == nullptr) B2FATAL("SectorMapBootstrapModule: the pointer to the DB payload is not set!");
329  if (!(*m_ptrDBObjPtr).isValid()) B2FATAL("SectorMapBootstrapModule the DB object is not valid!");
330 
331  rootFileName = (*m_ptrDBObjPtr)->getFileName();
332  }
333 
334  B2DEBUG(1, "SectorMapBootstrapModule: retrieving new SectorMap. New file name: " << rootFileName);
335  TFile rootFile(rootFileName.c_str());
336 
337  // some cross check that the file is open
338  if (!rootFile.IsOpen()) B2FATAL("The root file: " << rootFileName << " was not found.");
339 
340  TTree* tree = nullptr;
341  rootFile.GetObject(c_setupKeyNameTTreeName.c_str(), tree);
342  if (tree == nullptr) B2FATAL("SectorMapBootstrapModule: tree not found! tree name: " << c_setupKeyNameTTreeName.c_str());
343 
344  TString* setupKeyName = nullptr;
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(1, "Retrieving SectorMap with name " << setupKeyName->Data());
371 
372  VXDTFFilters<SpacePoint>* segmentFilters = new VXDTFFilters<SpacePoint>();
373 
374  string setupKeyNameStd = 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(1, "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
Specialization of DBObjPtr in case of PayloadFiles.
Definition: PayloadFile.h:54
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
const setupNameToFilters_t & getAllSetups(void)
returns all the available setups.
void assignFilters(const std::string &setupName, VXDTFFilters< point_t > *filters)
assigns filters.
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
Initialize the Module.
void event() override
This method is the core of the module.
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
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
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:213
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:493
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).