Belle II Software  release-08-01-10
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 
34 REG_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 \
53 retrieve the SectorMaps from SectorMapsInputFile during initialize.", m_readSectorMap);
54 
55  addParam("WriteSectorMap", m_writeSectorMap, "If set to true \
56 at 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 
97 void
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 
128 void
130 {
131 }
132 
133 
134 void
136 {
137 }
138 
139 void
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 
204 void
206 {
207  if (m_writeSectorMap)
209 }
210 
211 void
213 {
214 
215  // TODO: change naming! This is poor naming as these include also Triplet filters!
216  VXDTFFilters<SpacePoint>* segmentFilters = new VXDTFFilters<SpacePoint>();
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 
279 void
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(),
289  c_setupKeyNameTTreeName.c_str());
290 
291  TString setupKeyName;
292 
293  tree->Branch(c_setupKeyNameBranchName.c_str(),
294  & setupKeyName);
295 
296  auto allSetupsFilters = FiltersContainer<SpacePoint>::getInstance().getAllSetups();
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 
320 void
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 
372  VXDTFFilters<SpacePoint>* segmentFilters = new VXDTFFilters<SpacePoint>();
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
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
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
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: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
REG_MODULE(arichBtest)
Register the Module.
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
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).