Belle II Software  release-05-01-25
CurlingTrackCandSplitterModule.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2014 Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Thomas Madlener *
7  * *
8  **************************************************************************/
9 
10 #include <tracking/modules/spacePointCreator/CurlingTrackCandSplitterModule.h>
11 
12 // DataStore Stuff
13 #include <framework/datastore/StoreArray.h>
14 #include <framework/dataobjects/EventMetaData.h>
15 #include <framework/datastore/StoreObjPtr.h>
16 
17 // Clusters and TrueHits
18 #include <pxd/dataobjects/PXDCluster.h>
19 #include <pxd/dataobjects/PXDTrueHit.h>
20 #include <svd/dataobjects/SVDCluster.h>
21 #include <svd/dataobjects/SVDTrueHit.h>
22 
23 // SpacePoint related stuff
24 #include <tracking/spacePointCreation/SpacePoint.h>
25 #include <tracking/spacePointCreation/SpacePointTrackCand.h>
26 
27 #include <boost/format.hpp>
28 
29 #include <algorithm> // sort & unique
30 
31 using namespace std;
32 using namespace Belle2;
33 
34 REG_MODULE(CurlingTrackCandSplitter)
35 
36 // COULDDO: somehow retrieve the names under which Clusters and TrueHits are stored in the StoreArray (possible?) Or make them a parameter of the module. Otherwise it can happen, that, if more than one StoreArray of XYZCluster is present, all of them get searched, which might be unintended (or even undefined behaviour)
37 
39 {
40  setDescription("Module for checking SpacePointTrackCands for curling behaviour and (if wanted) splitting them into SpacePointTrackCands that no longer show curling behaviour. WARNING: MODULE IS DEPRECATED use SPTCReferee instead!");
41 
42  addParam("splitCurlers", m_PARAMsplitCurlers,
43  "Split curling SpacePointTrackCands into non-curling SpacePointTrackCands and store them", true);
44  addParam("nTrackStubs", m_PARAMnTrackStubs,
45  "Maximum number of SpacePointTrackCand Stubs to be created from a curling SpacePointTrackCand. Set to 0 if you want all possible TrackCand Stubs",
46  0);
47 
48  addParam("SpacePointTCName", m_PARAMsptcName, "Collection name of the SpacePointTrackCands to be analyzed for curling behaviour",
49  std::string(""));
50  addParam("curlingFirstOutName", m_PARAMcurlingOutFirstName,
51  "Collection name under which the first outgoing part of a curling TrackCand will be stored in the StoreArray. The first part of a curling Track has its origin at the interaction point.",
52  std::string(""));
53  addParam("curlingAllInName", m_PARAMcurlingAllInName,
54  "Collection name under which all ingoing parts of a curling TrackCand will be stored in the StoreArray", std::string(""));
55  addParam("curlingRestOutName", m_PARAMcurlingOutRestName,
56  "Collection name under which all but the first outgoing parts of a curling TrackCand will be stored in the StoreArray",
57  std::string(""));
58  addParam("completeCurlerName", m_PARAMcompleteCurlerName,
59  "Collection name under which all parts of a curling TrackCand will be stored in the StoreArray together. NOTE: only if this parameter is set to a non-empty string a complete (but splitted) curling TrackCand will be stored!",
60  std::string(""));
61 
62  // WARNING TODO: find out the units that are used internally!!!
63  std::vector<double> defaultOrigin = { 0., 0., 0. };
64  addParam("setOrigin", m_PARAMsetOrigin,
65  "WARNING: still need to find out the units that are used internally! Reset origin to given point. Used for determining the direction of flight of a particle for a given hit. Needs to be reset for e.g. testbeam, where origin is not at (0,0,0)",
66  defaultOrigin);
67 
68  addParam("positionAnalysis", m_PARAMpositionAnalysis,
69  "Set to true to investigate the positions of SpacePoints and TrueHits and write them to a ROOT file", false);
70 
71  std::vector<std::string> defaultRootFName;
72  defaultRootFName.push_back("PositionResiduals");
73  defaultRootFName.push_back("RECREATE");
74 
75  addParam("rootFileName", m_PARAMrootFileName,
76  "Filename and write-mode ('RECREATE' or 'UPDATE'). If given more than 2 strings this module will cause termination",
77  defaultRootFName);
78 
79 
80  addParam("useNonSingleTHinPA", m_PARAMuseNonSingleTHinPA,
81  "Switch for using SpacePoints in position Analysis that are related to more than one TrueHit", false);
82 
83  initializeCounters(); // NOTE: they get initialized in initialize again!!
84 
85  // initialize other variables to some default values to avoid unintended behaviour
86  m_saveCompleteCurler = false;
87  m_treePtr = NULL;
88  m_rootFilePtr = NULL;
89 }
90 
91 // ================================================= INITIALIZE =========================================================
92 void CurlingTrackCandSplitterModule::initialize()
93 {
94  initializeCounters();
95  B2INFO("CurlingTrackCandSplitter ----------------------------- initialize() -------------------------------------");
96  B2WARNING("CurlingTrackCandSplitter is deprecated and will be removed from framework in the near future! use SPTCReferee instead!");
97  // check if all necessary StoreArrays are present
98  StoreArray<SpacePointTrackCand> spacePointTCs(m_PARAMsptcName);
99  spacePointTCs.isRequired(m_PARAMsptcName);
100 
101  // count all empty input parameter strings, and issue a warning if more than one is empty (COULDDO: B2FATAL instead of warning)
102  int emptyCtr = 0;
103  if (m_PARAMcurlingOutFirstName.empty()) { emptyCtr++; }
104  if (m_PARAMcurlingAllInName.empty()) { emptyCtr++; }
105  if (m_PARAMcurlingOutRestName.empty()) { emptyCtr++; }
106 
107  if (emptyCtr > 1) {
108  B2WARNING("CurlingTrackCandSplitter::initialize: More than one of your input strings for the collection names is empty. This can lead to undeterministic behaviour since two or more collections will be stored under the same name!");
109  }
110 
111  // register new StoreArrays, and relation to original TrackCand
112  StoreArray<SpacePointTrackCand> curlingFirstOuts(m_PARAMcurlingOutFirstName);
113  curlingFirstOuts.registerInDataStore(m_PARAMcurlingOutFirstName, DataStore::c_ErrorIfAlreadyRegistered);
114  curlingFirstOuts.registerRelationTo(spacePointTCs);
115 
116  StoreArray<SpacePointTrackCand> curlingAllIns(m_PARAMcurlingAllInName);
117  curlingAllIns.registerInDataStore(m_PARAMcurlingAllInName, DataStore::c_ErrorIfAlreadyRegistered);
118  curlingAllIns.registerRelationTo(spacePointTCs);
119 
120  StoreArray<SpacePointTrackCand> curlingRestOuts(m_PARAMcurlingOutRestName);
121  curlingRestOuts.registerInDataStore(m_PARAMcurlingOutRestName, DataStore::c_ErrorIfAlreadyRegistered);
122  curlingRestOuts.registerRelationTo(spacePointTCs);
123 
124  // have to do this here, because in event() I do not want to check every time if this string is empty or not and act accordingly. If I register this with an empty string here, I can use it with an empty string in event() and only store stuff into it, when it is actually named with a non-empty string
125  StoreArray<SpacePointTrackCand> curlingCompletes(m_PARAMcompleteCurlerName);
126  curlingCompletes.registerInDataStore(m_PARAMcompleteCurlerName, DataStore::c_ErrorIfAlreadyRegistered);
127  curlingCompletes.registerRelationTo(spacePointTCs);
128 
129  if (!m_PARAMcompleteCurlerName.empty()) {
130  m_saveCompleteCurler = true;
131  B2DEBUG(1, "You put in " << m_PARAMcompleteCurlerName <<
132  " as collection name for complete curling TrackCands. Complete curling TrackCands will hence be stored.");
133  } else {
134  B2DEBUG(1,
135  "You did not put in any under which complete curling TrackCands should be stored, hence curling TrackCands will only be stored in parts.");
136  m_saveCompleteCurler = false;
137  }
138 
139  // check value for nTrackStubs and reset if necessary
140  if (m_PARAMnTrackStubs < 0) {
141  B2WARNING("CurlingTrackCandSplitter::initialize> Value of nTrackStubs is below 0: nTrackStubs = " << m_PARAMnTrackStubs <<
142  ". Resetting this value to 0 now! This means that all parts of curling TrackCands will be stored.");
143  m_PARAMnTrackStubs = 0;
144  } else { B2DEBUG(1, "Entered value for nTrackStubs = " << m_PARAMnTrackStubs); }
145 
146  B2DEBUG(1, "Entered Value for splitCurlers: " << m_PARAMsplitCurlers);
147 
148  if (m_PARAMsetOrigin.size() != 3) {
149  B2WARNING("CurlingTrackCandSplitter::initialize: Provided origin is not a 3D point! Please provide 3 values (x,y,z). Rejecting user input and setting origin to (0,0,0) for now!");
150  m_PARAMsetOrigin.clear();
151  m_PARAMsetOrigin.assign(3, 0);
152  }
153  m_origin.SetXYZ(m_PARAMsetOrigin.at(0), m_PARAMsetOrigin.at(1), m_PARAMsetOrigin.at(2));
154  B2DEBUG(10, "Set origin to (x,y,z): (" << m_origin.X() << "," << m_origin.Y() << "," << m_origin.Z() << ")");
155 
156  if (m_PARAMpositionAnalysis) {
157  // check if there are two entries and if the second value is either UPDATE or RECREATE
158  if (m_PARAMrootFileName.size() != 2 || (m_PARAMrootFileName[1] != "UPDATE" && m_PARAMrootFileName[1] != "RECREATE")) {
159  string output;
160  // cppcheck-suppress useStlAlgorithm
161  for (string entry : m_PARAMrootFileName) { output += "'" + entry + "' "; }
162  B2FATAL("CurlingTrackCandSplitter::initialize() : rootFileName is set wrong: entries are: " << output);
163  }
164  // create ROOT file
165  m_PARAMrootFileName[0] += ".root";
166  m_rootFilePtr = new TFile(m_PARAMrootFileName[0].c_str(), m_PARAMrootFileName[1].c_str());
167  m_treePtr = new TTree("m_treePtr", "aTree");
168 
169  // link everything to the according variables
170  for (int layer = 0; layer < c_nPlanes; ++layer) {
171  string layerString = (boost::format("%1%") % (layer +
172  1)).str(); // layer numbering starts at 1 this way (plus cppcheck complains about division by zero otherwise)
173 
174  string name = "SpacePointXGlobal_" + layerString;
175  m_treePtr->Branch(name.c_str(), &m_rootSpacePointXGlobals.at(layer));
176  name = "SpacePointYGlobal_" + layerString;
177  m_treePtr->Branch(name.c_str(), &m_rootSpacePointYGlobals.at(layer));
178  name = "SpacePointZGlobal_" + layerString;
179  m_treePtr->Branch(name.c_str(), &m_rootSpacePointZGlobals.at(layer));
180 
181  name = "SpacePointULocal_" + layerString;
182  m_treePtr->Branch(name.c_str(), &m_rootSpacePointULocals.at(layer));
183  name = "SpacePointVlocal_" + layerString;
184  m_treePtr->Branch(name.c_str(), &m_rootSpacePointVLocals.at(layer));
185 
186  name = "TrueHitXGlobal_" + layerString;
187  m_treePtr->Branch(name.c_str(), &m_rootTrueHitXGlobals.at(layer));
188  name = "TrueHitYGlobal_" + layerString;
189  m_treePtr->Branch(name.c_str(), &m_rootTrueHitYGlobals.at(layer));
190  name = "TrueHitZGlobal_" + layerString;
191  m_treePtr->Branch(name.c_str(), &m_rootTrueHitZGlobals.at(layer));
192 
193  name = "TrueHitULocal_" + layerString;
194  m_treePtr->Branch(name.c_str(), &m_rootTrueHitULocals.at(layer));
195  name = "TrueHitVLocal_" + layerString;
196  m_treePtr->Branch(name.c_str(), &m_rootTrueHitVLocals.at(layer));
197 
198  name = "PosResidualsXGlobal_" + layerString;
199  m_treePtr->Branch(name.c_str(), &m_rootPosResidueXGlobal.at(layer));
200  name = "PosResidualsYGlobal_" + layerString;
201  m_treePtr->Branch(name.c_str(), &m_rootPosResidueYGlobal.at(layer));
202  name = "PosResidualsZGlobal_" + layerString;
203  m_treePtr->Branch(name.c_str(), &m_rootPosResidueZGlobal.at(layer));
204 
205  name = "PosResidualsULocal_" + layerString;
206  m_treePtr->Branch(name.c_str(), &m_rootPosResidueULocal.at(layer));
207  name = "PosResidualsVLocal_" + layerString;
208  m_treePtr->Branch(name.c_str(), &m_rootPosResidueVLocal.at(layer));
209 
210 
211  name = "LocalPositionResiduals_" + layerString;
212  m_treePtr->Branch(name.c_str(), &m_rootLocalPosResiduals.at(layer));
213  name = "GlobalPositionResiduals_" + layerString;
214  m_treePtr->Branch(name.c_str(), &m_rootGlobalPosResiduals.at(layer));
215 
216  name = "MisMatchPosDistance_" + layerString;
217  m_treePtr->Branch(name.c_str(), &m_rootMisMatchPosDistance.at(layer));
218  name = "MisMatchPosX_" + layerString;
219  m_treePtr->Branch(name.c_str(), &m_rootMisMatchPosX.at(layer));
220  name = "MisMatchPosY_" + layerString;
221  m_treePtr->Branch(name.c_str(), &m_rootMisMatchPosY.at(layer));
222  name = "MisMatchPosZ_" + layerString;
223  m_treePtr->Branch(name.c_str(), &m_rootMisMatchPosZ.at(layer));
224 
225  name = "MisMatchPosU_" + layerString;
226  m_treePtr->Branch(name.c_str(), &m_rootMisMatchPosU.at(layer));
227  name = "MisMatchPosV_" + layerString;
228  m_treePtr->Branch(name.c_str(), &m_rootMisMatchPosV.at(layer));
229 
230  name = "MisMatchMomX_" + layerString;
231  m_treePtr->Branch(name.c_str(), &m_rootMisMatchMomX.at(layer));
232  name = "MisMatchMomY_" + layerString;
233  m_treePtr->Branch(name.c_str(), &m_rootMisMatchMomY.at(layer));
234  name = "MisMatchMomZ_" + layerString;
235  m_treePtr->Branch(name.c_str(), &m_rootMisMatchMomZ.at(layer));
236  }
237  } else {
238  m_rootFilePtr = NULL;
239  m_treePtr = NULL;
240  }
241 }
242 
243 // =================================================== EVENT ============================================================
244 void CurlingTrackCandSplitterModule::event()
245 {
246  StoreObjPtr<EventMetaData> eventMetaDataPtr("EventMetaData", DataStore::c_Event);
247  const int eventCounter = eventMetaDataPtr->getEvent();
248  B2DEBUG(10, "CurlingTrackCandSplitter::event(). -------------- Processing event " << eventCounter << " ----------------");
249 
250  // StoreArrays that will be used for storing
251  StoreArray<SpacePointTrackCand> outgoingFirstTCs(m_PARAMcurlingOutFirstName);
252  StoreArray<SpacePointTrackCand> ingoingAllTCs(m_PARAMcurlingAllInName);
253  StoreArray<SpacePointTrackCand> outgoingRestTCs(m_PARAMcurlingOutRestName);
254  StoreArray<SpacePointTrackCand> completeCurlingTCs(m_PARAMcompleteCurlerName);
255 
256 
257  StoreArray<SpacePointTrackCand> spacePointTCs(m_PARAMsptcName);
258  int nTCs = spacePointTCs.getEntries();
259 
260  B2DEBUG(15, "Found " << nTCs << " SpacePointTrackCands in StoreArray " << spacePointTCs.getName() << " for this event");
261 
262  RootVariables rootVariables;
263 
264  for (int iTC = 0; iTC < nTCs; ++iTC) {
265  SpacePointTrackCand* spacePointTC = spacePointTCs[iTC];
266  m_spacePointTCCtr++;
267 
268  B2DEBUG(15, "=========================== Processing SpacePointTrackCand " << iTC << " ===============================");
269  try {
270  const std::vector<int> splittingIndices = checkTrackCandForCurling(*spacePointTC, rootVariables);
271 
272  if (splittingIndices.empty()) {
273  B2DEBUG(15, "This SpacePointTrackCand shows no curling behaviour and will be added to collection: " << m_PARAMcurlingOutFirstName);
274  spacePointTC->setTrackStubIndex(0); // set TrackStubIndex to 0 (indicates, that this TrackCandidate shows no curling behaviour)
275  // add this spacePoint to the StoreArray with the first outgoing parts since the whole TC is outgoing
276  SpacePointTrackCand* newSPTC = outgoingFirstTCs.appendNew(*spacePointTC);
277  newSPTC->addRelationTo(spacePointTC);
278  m_NoCurlingTCsCtr++;
279  } else {
280  B2DEBUG(15, "This SpacePointTrackCand shows curling behaviour");
281  if (!m_PARAMsplitCurlers) {
282  B2DEBUG(15, "This SpacePointTrackCand could be split into " << splittingIndices.size() + 1 <<
283  " but will not, because splitCurlers is set to false");
284  continue; // should jump to enclosing for-loop!!! (process the next SpacePointTrackCand)
285  }
286  m_curlingTCCtr++;
287  // get the TrackCand Stubs
288  std::vector<SpacePointTrackCand> trackStubs = splitCurlingTrackCand(*spacePointTC, m_PARAMnTrackStubs, splittingIndices);
289 
290  // add the stubs to the appropriate StoreArray
291  for (SpacePointTrackCand trackStub : trackStubs) {
292  m_createdTrackStubsCtr++;
293  if (m_saveCompleteCurler) {
294  SpacePointTrackCand* newSPTC = completeCurlingTCs.appendNew(trackStub);
295  newSPTC->addRelationTo(spacePointTC);
296  B2DEBUG(25, "Added SpacePointTrackCand " << newSPTC->getArrayIndex() << " to StoreArray " << newSPTC->getArrayName());
297  }
298  if (!trackStub.isOutgoing()) {
299  SpacePointTrackCand* newSPTC = ingoingAllTCs.appendNew(trackStub);
300  newSPTC->addRelationTo(spacePointTC);
301  B2DEBUG(25, "Added SpacePointTrackCand " << newSPTC->getArrayIndex() << " to StoreArray " << newSPTC->getArrayName());
302  } else { // if not ingoing differentiate between first part and all of the rest
303  if (trackStub.getTrackStubIndex() > 1) {
304  SpacePointTrackCand* newSPTC = outgoingRestTCs.appendNew(trackStub);
305  newSPTC->addRelationTo(spacePointTC);
306  B2DEBUG(25, "Added SpacePointTrackCand " << newSPTC->getArrayIndex() << " to StoreArray " << newSPTC->getArrayName());
307  } else {
308  SpacePointTrackCand* newSPTC = outgoingFirstTCs.appendNew(trackStub);
309  newSPTC->addRelationTo(spacePointTC);
310  B2DEBUG(25, "Added SpacePointTrackCand " << newSPTC->getArrayIndex() << " to StoreArray " << newSPTC->getArrayName());
311  }
312  }
313  }
314  }
315  } catch (FoundNoTrueHit& anE) {
316  B2WARNING("Caught an exception during checking for curling behaviour: " << anE.what() <<
317  " This TrackCandidate cannot be checked for curling behaviour");
318  m_noDecisionPossibleCtr++;
319  } catch (FoundNoCluster& anE) {
320  B2WARNING("Caught an exception during checking for curling behaviour: " << anE.what() <<
321  " This TrackCandidate cannot be checked for curling behaviour");
322  m_noDecisionPossibleCtr++;
323  } catch (TrueHitsNotMatching& anE) {
324  B2WARNING("Caught an exception during checking for curling behaviour: " << anE.what() <<
325  " This TrackCandidate cannot be checked for curling behaviour");
326  m_noDecisionPossibleCtr++;
327  } catch (SpacePointTrackCand::UnsupportedDetType& anE) {
328  B2WARNING("Caught an exception during checking for curling behaviour: " << anE.what() <<
329  " This TrackCandidate cannot be checked for curling behaviour");
330  m_noDecisionPossibleCtr++;
331  }
332  }
333  // only write to root once per event
334  if (m_PARAMpositionAnalysis) { writeToRoot(rootVariables); }
335 }
336 
337 // =================================================== TERMINATE ========================================================
338 void CurlingTrackCandSplitterModule::terminate()
339 {
340  B2INFO("CurlingTrackCandSplitter::terminate(): checked " << m_spacePointTCCtr << " SpacePointTrackCands for curling behaviour. " <<
341  m_curlingTCCtr << " of them were curling and " << m_createdTrackStubsCtr << " TrackStubs were created. " << m_NoCurlingTCsCtr <<
342  " SPTCs were not curling and were merely copied into StoreArray " << m_PARAMcurlingOutFirstName << ". In " <<
343  m_noDecisionPossibleCtr << " cases no decision could be made. There were " << m_NoSingleTrueHitCtr <<
344  " SpacePoints that were related to more than one TrueHit");
345  // do ROOT file stuff
346  if (m_treePtr != NULL) {
347  m_rootFilePtr->cd(); //important! without this the famework root I/O (SimpleOutput etc) could mix with the root I/O of this module
348  m_treePtr->Write();
349  m_rootFilePtr->Close();
350  }
351 }
352 
353 // ============================================== CHECK FOR CURLING ======================================================
354 const std::vector<int> CurlingTrackCandSplitterModule::checkTrackCandForCurling(const Belle2::SpacePointTrackCand& SPTrackCand,
355  RootVariables& rootVariables)
356 {
357  const std::vector<const Belle2::SpacePoint*>& tcSpacePoints = SPTrackCand.getHits();
358  unsigned int nHits = SPTrackCand.getNHits();
359 
360  B2DEBUG(70, "SpacePointTrackCand contains " << nHits << " SpacePoints");
361 
362  std::vector<int> returnVector; // fill this vector with indices, if no indices can be found, leave it empty
363 
364  std::pair<bool, bool>
365  directions; // only store the last two directions to decide if it has changed or not. .first is always last hit, .second is present hit.
366  directions.first =
367  true; // assume that the track points outwards from the interaction point at first. NOTE: this assumption is not dangerous here (it is in other places because it does not have to be the case). The information on the direction of flight for the first hit is stored in the returnVector itself. If the first entry is 0 (this means that the trackCand first 'pointed' towards the interaction point)
368 
369  for (unsigned int iHit = 0; iHit < nHits; ++iHit) {
370  const SpacePoint* spacePoint = tcSpacePoints[iHit];
371  auto detType = spacePoint->getType();
372 
373  B2DEBUG(100, "Now checking SpacePoint " << iHit << " in SPTC. This SpacePoint has Index " << spacePoint->getArrayIndex() <<
374  " in StoreArray " << spacePoint->getArrayName());
375 
376  // get global position and momentum for every spacePoint in the SpacePointTrackCand
377  std::pair<B2Vector3<double>, B2Vector3<double> > hitGlobalPosMom;
378 
379  if (detType == VXD::SensorInfoBase::PXD) {
380  // first get PXDCluster, from that get TrueHit
381  PXDCluster* pxdCluster =
382  spacePoint->getRelatedTo<PXDCluster>("ALL"); // COULDDO: search only certain Cluster Arrays -> get name somehow
383  // CAUTION: only looking for one TrueHit here, but there could actually be more of them 'molded' into one Cluster
384  PXDTrueHit* pxdTrueHit =
385  pxdCluster->getRelatedTo<PXDTrueHit>("ALL"); // COULDDO: search only certain PXDTrueHit arrays -> new parameter for module
386 
387  if (pxdTrueHit == NULL) {
388  B2DEBUG(1, "Found no PXDTrueHit for PXDCluster " << pxdCluster->getArrayIndex() << " from Array " << pxdCluster->getArrayName() <<
389  ". This PXDCluster is related with SpacePoint " << spacePoint->getArrayIndex() << " from Array " << spacePoint->getArrayName());
390  throw FoundNoTrueHit();
391  }
392 
393  B2DEBUG(100, "Found PXDCluster " << pxdCluster->getArrayIndex() << " and " << " PXDTrueHit " << pxdTrueHit->getArrayIndex() <<
394  " from StoreArray " << pxdTrueHit->getArrayName() << " related to this SpacePoint");
395 
396  B2DEBUG(100, "Now getting global position and momentum for PXDCluster " << pxdCluster->getArrayIndex() << " from Array " <<
397  pxdCluster->getArrayName());
398  hitGlobalPosMom = getGlobalPositionAndMomentum(pxdTrueHit);
399 
400  // if position analysis is set to true, print to root file
401  if (m_PARAMpositionAnalysis) { getValuesForRoot(spacePoint, pxdTrueHit, rootVariables); }
402 
403  } else if (detType == VXD::SensorInfoBase::SVD) {
404  // get all related SVDClusters and do some sanity checks, before getting the SVDTrueHits and then using them to get global position and momentum
405  RelationVector<SVDCluster> svdClusters =
406  spacePoint->getRelationsTo<SVDCluster>("ALL"); // COULDDO: search only certain Cluster Arrays -> get name somehow (addidional parameter?)
407  if (svdClusters.size() == 0) {
408  B2WARNING("Found no related clusters for SpacePoint " << spacePoint->getArrayIndex() << " from Array " << spacePoint->getArrayName()
409  << ". With no Cluster no information if a track is curling or not can be obtained");
410  throw FoundNoCluster(); // this should also never happen, as the vice versa way is used to get to the SpacePoints in the first place (in the GFTC2SPTCConverterModule e.g.)
411  } else {
412  // collect the TrueHits, if there is more than one compare them, to see if both Clusters point to the same TrueHit
413  // WARNING there can be more! more than one TrueHit can be 'hidden' in one Cluster!!!
414  // TODO: look at this again, this seems not to work properly at the moment!!!
415  std::vector<const SVDTrueHit*> svdTrueHits;
416  for (const SVDCluster& aCluster : svdClusters) {
417  // CAUTION: there can be more than one TrueHit for a given Cluster!!!
418  RelationVector<SVDTrueHit> relTrueHits =
419  aCluster.getRelationsTo<SVDTrueHit>("ALL"); // COULDDO: search only certain SVDTrueHit arrays -> new parameter for module
420  if (relTrueHits.size() == 0) {
421  B2DEBUG(1, "Found no SVDTrueHit for SVDCluster " << aCluster.getArrayIndex() << " from Array " << aCluster.getArrayName() <<
422  ". This SVDCluster is related with SpacePoint " << spacePoint->getArrayIndex() << " from Array " << spacePoint->getArrayName());
423  throw FoundNoTrueHit();
424  }
425 
426  B2DEBUG(100, "Found " << relTrueHits.size() << " TrueHits for SVDCluster " << aCluster.getArrayIndex() << " from Array " <<
427  aCluster.getArrayName());
428  for (unsigned int i = 0; i < relTrueHits.size(); ++i) { svdTrueHits.push_back(relTrueHits[i]); }
429  }
430 
431  // if there is only one cluster related to the SpacePoint simply check if one (or more TrueHits are present). Additionally checking the size for svdTrueHits again is not necessary here, because if there was only one Cluster and no TrueHits were found this part is never reached!
432  // WARNING: It is not guaranteed that this actually leads to a valid relation between SpacePoint and TrueHit!!
433  // TODO: continuing with next SpacePoint skips check for curling behavior!!! FIX this!!!
434 // if (svdClusters.size() == 1) {
435 // stringstream inds;
436 // for (const SVDTrueHit * trueHit : svdTrueHits) { inds << trueHit->getArrayIndex() << ", "; }
437 // B2DEBUG(150, "Found only one Cluster related to SpacePoint " << spacePoint->getArrayIndex() << " from Array " << spacePoint->getArrayName() << ". To this Cluster " << svdTrueHits.size() << " related TrueHits were found. Indices: " << inds.str());
438 // m_NoSingleTrueHitCtr++;
439 // continue; // start over with next SpacePoint
440 // }
441 
442  // if there is at least one TrueHit in the vector check how many unique TrueHits there are
443  if (svdTrueHits.size() >= 1) {
444  B2DEBUG(150, "Found " << svdTrueHits.size() << " SVDTrueHits related to Clusters related to SpacePoint " <<
445  spacePoint->getArrayIndex() << " from Array " << spacePoint->getArrayName() << ". Now checking if they are compatible");
446 
447  // sort & unique to find the unique entries of the relation vector
448  std::sort(svdTrueHits.begin(), svdTrueHits.end());
449  unsigned int oldSize = svdTrueHits.size();
450  auto newEnd = std::unique(svdTrueHits.begin(), svdTrueHits.end());
451  svdTrueHits.resize(std::distance(svdTrueHits.begin(), newEnd));
452 
453  // If there is no overlapping TrueHit get all indices of the TrueHits and print a warning. If position Analysis is enabled calculate the position differences of the TrueHits. In the end throw an Exception (only if the TrueHits belong to a non-single Cluster SVD SpacePoint)
454  if (svdTrueHits.size() == oldSize) {
455  stringstream trueHitInds;
456  for (const SVDTrueHit* trueHit : svdTrueHits) { trueHitInds << trueHit->getArrayIndex() << ", "; }
457  B2DEBUG(1, "There is no overlapping TrueHit for SpacePoint " << spacePoint->getArrayIndex() << " from Array " <<
458  spacePoint->getArrayName() << ". The Indices of the TrueHits are: " << trueHitInds.str());
459 
460  // Only do these calculations if output to root is is enabled
461  if (m_PARAMpositionAnalysis) {
462  std::vector<B2Vector3<double> > globalPositions;
463  std::vector<B2Vector3<double> > globalMomenta;
464  // collect all values
465  for (unsigned int i = 0; i < svdTrueHits.size(); ++i) {
466  auto posMom = getGlobalPositionAndMomentum(svdTrueHits[i]);
467  globalPositions.push_back(posMom.first);
468  globalMomenta.push_back(posMom.second);
469  }
470  // WARNING: getting only layer number of first TrueHit in vector here. Although this should not change, this is never actually checked!!
471  int layer = svdTrueHits[0]->getSensorID().getLayerNumber() - 1; // layer numbering starts at 1, indexing of array at 0
472  // do the calculations (starting from one because of comparison of two elements in each run through loop)
473  for (unsigned int i = 1; i < globalPositions.size(); ++i) {
474  rootVariables.MisMatchPosResiduals.at(layer).push_back((globalPositions[i] - globalPositions[i - 1]).Mag());
475 
476  rootVariables.MisMatchPosX.at(layer).push_back((globalPositions[i] - globalPositions[i - 1]).X());
477  rootVariables.MisMatchPosY.at(layer).push_back((globalPositions[i] - globalPositions[i - 1]).Y());
478  rootVariables.MisMatchPosZ.at(layer).push_back((globalPositions[i] - globalPositions[i - 1]).Z());
479 
480  rootVariables.MisMatchPosU.at(layer).push_back((svdTrueHits[i]->getU() - svdTrueHits[i - 1]->getU()));
481  rootVariables.MisMatchPosV.at(layer).push_back((svdTrueHits[i]->getV() - svdTrueHits[i - 1]->getV()));
482 
483  B2Vector3<double> momDiff = globalMomenta[i] - globalMomenta[i - 1];
484  rootVariables.MisMatchMomX.at(layer).push_back(momDiff.X());
485  rootVariables.MisMatchMomY.at(layer).push_back(momDiff.Y());
486  rootVariables.MisMatchMomZ.at(layer).push_back(momDiff.Z());
487  }
488  }
489  // if the TrueHits are related from a singleCluster SVD SpacePoint (i.e. more than one TrueHits are molded into one Cluster) do not throw this exception but continue with the curling checking
490  if (svdClusters.size() > 1) { TrueHitsNotMatching(); }
491  }
492  }
493 
494  // if there is more than one TrueHit remaining for one SpacePoint increase the counter
495  if (svdTrueHits.size() > 1) {
496  m_NoSingleTrueHitCtr++;
497  }
498 
499  // WARNING if there are more than one matching TrueHits only the first TrueHit is used for comparison and for position analysis
500  B2DEBUG(100, "Now getting global position and momentum for SVDCluster " << svdClusters[0]->getArrayIndex() << " from Array " <<
501  svdClusters[0]->getArrayName() << " via SVDTrueHit " << svdTrueHits[0]->getArrayIndex() << " from StoreArray " <<
502  svdTrueHits[0]->getArrayName());
503  hitGlobalPosMom = getGlobalPositionAndMomentum(svdTrueHits[0]);
504 
505  // if position analysis is set to true, print to root file
506  // only do so if there is only one TrueHit (this is only for the moment!!!) OR if the switch is set to do so even if there is more than one TrueHit
507  // TODO: Decide how to handle such cases where more than one TrueHit is left and implement accordingly
508  if (m_PARAMpositionAnalysis && (svdTrueHits.size() == 1 || m_PARAMuseNonSingleTHinPA)) { getValuesForRoot(spacePoint, svdTrueHits[0], rootVariables); }
509  }
510  } else { // this should never be reached, because it should be caught in the creation of the SpacePointTrackCand which is passed to this function!
511  throw SpacePointTrackCand::UnsupportedDetType();
512  }
513 
514  // get the direction of flight for the present SpacePoint
515  directions.second = getDirectionOfFlight(hitGlobalPosMom, m_origin);
516 
517  // check if the directions have changed since the last hit, if so, add the number of the SpacePoint (inside the SpacePointTrackCand) to the returnVector
518  if (directions.first != directions.second) {
519  B2DEBUG(75, "The direction of flight has changed for SpacePoint " << iHit <<
520  " in SpacePointTrackCand. The StoreArray index of this SpacePoint is " << spacePoint->getArrayIndex() << " in " <<
521  spacePoint->getArrayName());
522  returnVector.push_back(iHit);
523  }
524  // assign old value to .first, for next comparison
525  directions.first = directions.second;
526  }
527  return returnVector;
528 }
529 
530 // ======================================= GET GLOBAL POSITION AND MOMENTUM ============================================================
531 
533 template<class TrueHit>
534 std::pair<const Belle2::B2Vector3<double>, const Belle2::B2Vector3<double> >
535 CurlingTrackCandSplitterModule::getGlobalPositionAndMomentum(TrueHit* aTrueHit)
536 {
537  // get sensor stuff (needed for pointToGlobal)
538  VxdID aVxdId = aTrueHit->getSensorID();
539 
540  B2DEBUG(100, "Getting global position and momentum vectors for TrueHit " << aTrueHit->getArrayIndex() << " from Array " <<
541  aTrueHit->getArrayName() << ". This hit has VxdID " << aVxdId);
542 
543  const VXD::GeoCache& geometry = VXD::GeoCache::getInstance();
544  const VXD::SensorInfoBase& sensorInfoBase = geometry.getSensorInfo(aVxdId);
545 
546  // get position
547  B2Vector3<double> hitLocal = B2Vector3<double>(aTrueHit->getU(), aTrueHit->getV(), 0);
548  B2Vector3<double> hitGlobal = sensorInfoBase.pointToGlobal(
549  hitLocal, true); // should work like this, since local coordinates are only 2D
550  B2DEBUG(100, "Local position of hit is (" << hitLocal.X() << "," << hitLocal.Y() << "," << hitLocal.Z() <<
551  "), Global position of hit is (" << hitGlobal.X() << "," << hitGlobal.Y() << "," << hitGlobal.Z() << ")");
552 
553  // get momentum
554  B2Vector3<double> pGlobal = sensorInfoBase.vectorToGlobal(aTrueHit->getMomentum(), true);
555  B2DEBUG(100, "Global momentum of hit is (" << pGlobal.X() << "," << pGlobal.Y() << "," << pGlobal.Z() << ")");
556 
557  return std::make_pair(hitGlobal, pGlobal);
558 }
559 
560 // ======================================= GET DIRECTION OF FLIGHT ======================================================================
561 bool CurlingTrackCandSplitterModule::getDirectionOfFlight(const
562  std::pair<const B2Vector3<double>, const B2Vector3<double>>& hitPosAndMom,
563  const B2Vector3<double>& origin)
564 {
565  B2Vector3<double> originToHit = hitPosAndMom.first - origin;
566  B2Vector3<double> momentumAtHit = hitPosAndMom.second + originToHit;
567 
568 
569  B2DEBUG(100, "Position of hit relative to origin is (" << originToHit.X() << "," << originToHit.Y() << "," << originToHit.Z() <<
570  "). Momentum relative to hit (relative to origin) (" << momentumAtHit.X() << "," << momentumAtHit.Y() << "," << momentumAtHit.Z() <<
571  ")");
572 
573  // cylindrical coordinates (?) -> use B2Vector3.Perp() to get the radial component of a given vector
574  // for spherical coordinates -> use B2Vector3.Mag() for the same purposes
575  double hitRadComp = originToHit.Perp(); // radial component of hit coordinates
576  double hitMomRadComp =
577  momentumAtHit.Perp(); // radial component of the tip of the momentum vector, when its origin would be the hit position (as it is only the direction of the momentum that matters here, units are completely ignored -> COULDDO: use the unit() method from B2Vector3
578 
579  B2DEBUG(250, " radial component of hit coordinates: " << hitRadComp <<
580  ", radial component of tip of momentum vector with its origin set to hit position: " << hitMomRadComp);
581 
582  if (hitMomRadComp < hitRadComp) {
583  B2DEBUG(100, "Direction of flight is inwards for this hit");
584  return false;
585  } else {
586  B2DEBUG(100, "Direction of flight is outwards for this hit");
587  return true;
588  }
589 }
590 
591 // ================================================ SPLIT CURLING TRACK CAND =========================================================
592 const std::vector<Belle2::SpacePointTrackCand>
593 CurlingTrackCandSplitterModule::splitCurlingTrackCand(const Belle2::SpacePointTrackCand& SPTrackCand, int NTracklets,
594  const std::vector<int>& splitIndices)
595 {
596  std::vector<SpacePointTrackCand> spacePointTCs;
597 
598  std::vector<std::pair<int, int> >
599  rangeIndices; // store pairs of Indices indicating the first and the last index of a TrackStub inside a SpacePointTrackCand
600 
601  int firstIndex = 0; // first 'first index' is 0
602  for (int index : splitIndices) {
603  rangeIndices.push_back({firstIndex, index});
604  firstIndex = index + 1; // next first index is last index + 1
605  }
606  rangeIndices.push_back({firstIndex, SPTrackCand.getNHits() - 1}); // the last TrackStub contains all hits from the last splitIndex to the end of the SpacePointTrackCand
607 
608  // NOTE: if the first index of splitIndices is zero, this means that the direction of flight for the first SpacePoint (i.e. TrueHit) of the TrackCand was not outgoing.
609  // WARNING: This is only true as long as this behaviour is not changed in checkTrackCandForCurling(...), as there the assumption is made that the direction of flight of the first hit is outgoing, and only if it is not 0 is the first entry of the returnVector of the latter.
610  bool outgoing = splitIndices[0] != 0;
611 
612  // return NTracklets (user defined) at most, or if NTracklets is 0, return all
613  // if NTracklets is 0 set it to the appropriate size for the following for-loop
614  if (NTracklets < 1) { NTracklets = rangeIndices.size(); }
615  for (unsigned iTr = 0; iTr < rangeIndices.size() && iTr < uint(NTracklets); ++iTr) {
616 
617  int lastInd = rangeIndices[iTr].second;
618  int firstInd = rangeIndices[iTr].first;
619 
620  B2DEBUG(75, "Creating Track Stub " << iTr << " of " << splitIndices.size() <<
621  " possible Track Stub for this SpacePointTrackCand. The indices for this Tracklet are (first,last): (" << firstInd << "," << lastInd
622  << "). This SpacePointTrackCand contains " << SPTrackCand.getNHits() << " SpacePoints in total.");
623 
624  // encapsulate these functions into a try-clause since both throw
625  try {
626  const std::vector<const SpacePoint*> trackletSpacePoints = SPTrackCand.getHitsInRange(firstInd, lastInd);
627  const std::vector<double> trackletSortingParams = SPTrackCand.getSortingParametersInRange(firstInd, lastInd);
628 
629  SpacePointTrackCand newSPTrackCand = SpacePointTrackCand(trackletSpacePoints, SPTrackCand.getPdgCode(), SPTrackCand.getChargeSeed(),
630  SPTrackCand.getMcTrackID());
631  newSPTrackCand.setSortingParameters(trackletSortingParams);
632 
633  // TODO: set state seed and cov seed for all but the first tracklets (first is just the seed of the original TrackCand)
634  if (iTr < 1) {
635  newSPTrackCand.set6DSeed(SPTrackCand.getStateSeed());
636  newSPTrackCand.setCovSeed(SPTrackCand.getCovSeed());
637  }
638 
639  // set direction of flight and flip it for the next track stub (track is split where the direction of flight changes so this SHOULD not introduce any errors)
640  newSPTrackCand.setFlightDirection(outgoing);
641  outgoing = !outgoing;
642 
643  // if the TrackCandidate curls this index starts at 1, if it is a curling TrackCand
644  newSPTrackCand.setTrackStubIndex(iTr + 1);
645 
646  spacePointTCs.push_back(newSPTrackCand);
647  } catch (SpacePointTrackCand::SPTCIndexOutOfBounds& anE) {
648  B2WARNING("Caught an exception while trying to split SpacePointTrackCands: " << anE.what() <<
649  " This SPTC will be skipped from splitting!");
650  }
651  }
652 
653  return spacePointTCs;
654 }
655 
656 // ======================================================= GET ROOT VALUES =========================================================
657 template <class TrueHit>
658 void CurlingTrackCandSplitterModule::getValuesForRoot(const Belle2::SpacePoint* spacePoint, const TrueHit* trueHit,
659  RootVariables& rootVariables)
660 {
661  B2DEBUG(100, "Getting positions (for ROOT output) of SpacePoint " << spacePoint->getArrayIndex() << " from Array " <<
662  spacePoint->getArrayName() << " and TrueHit " << trueHit->getArrayIndex() << " from Array " << trueHit->getArrayName());
663 
664  // get VxdIDs of spacePoint and trueHit (and their according layer numbers for storing the information in the appropriate arrays)
665  VxdID spacePointVxdId = spacePoint->getVxdID();
666  VxdID trueHitVxdId = trueHit->getSensorID();
667 
668  // get positions from SpacePoint
669  const B2Vector3<double>& spacePointGlobal =
670  spacePoint->getPosition(); // COULDDO: uneccesary, spacePoint->X(), etc. returns the same information!
671 // std::pair<double, double> spacePointUV = getUV(spacePoint);
672  TaggedUVPos spacePointUV = getUV(spacePoint);
673  const B2Vector3<double> spacePointLocal = B2Vector3<double>(spacePointUV.m_U, spacePointUV.m_V, 0);
674 
675  // get local position from TrueHit
676  const B2Vector3<double> trueHitLocal = B2Vector3<double>(trueHit->getU(), trueHit->getV(), 0);
677 
678  // get sensor Info for global position of TrueHit
679  const VXD::GeoCache& geometry = VXD::GeoCache::getInstance();
680  const VXD::SensorInfoBase& sensorInfoBase = geometry.getSensorInfo(trueHitVxdId);
681 
682  // get global position from TrueHit
683  const B2Vector3<double> trueHitGlobal = sensorInfoBase.pointToGlobal(trueHitLocal, true);
684 
685  // Layer numbering starts at 1 not at 0 so deduce layer by one to access array
686  int spLayer = spacePointVxdId.getLayerNumber() - 1;
687  int thLayer = trueHitVxdId.getLayerNumber() - 1;
688 
689  if (spLayer != thLayer) {
690  B2FATAL("Layer numbers of TrueHit and SpacePoint do not match!"); // this should never happen -> FATAL if it does, because something has gone amiss then
691  }
692 
693  // all positions collected, but only write the values to ROOT that have been set appropriately!
694  bool singleCluster = true; // for debug output
695  if (spacePointUV.m_setU) {
696  rootVariables.SpacePointULocal.at(spLayer).push_back(spacePointUV.m_U);
697  rootVariables.TrueHitULocal.at(thLayer).push_back(trueHit->getU());
698  rootVariables.PosResidueULocal.at(spLayer).push_back((spacePointUV.m_U - trueHit->getU()));
699  }
700  if (spacePointUV.m_setV) {
701  rootVariables.SpacePointVLocal.at(spLayer).push_back(spacePointUV.m_V);
702  rootVariables.TrueHitVLocal.at(thLayer).push_back(trueHit->getV());
703  rootVariables.PosResidueVLocal.at(spLayer).push_back((spacePointUV.m_V - trueHit->getV()));
704  }
705  if (spacePointUV.m_setU && spacePointUV.m_setV) {
706  rootVariables.SpacePointXGlobal.at(spLayer).push_back(spacePoint->X());
707  rootVariables.SpacePointYGlobal.at(spLayer).push_back(spacePoint->Y());
708  rootVariables.SpacePointZGlobal.at(spLayer).push_back(spacePoint->Z());
709 
710  rootVariables.TrueHitXGlobal.at(thLayer).push_back(trueHitGlobal.X());
711  rootVariables.TrueHitYGlobal.at(thLayer).push_back(trueHitGlobal.Y());
712  rootVariables.TrueHitZGlobal.at(thLayer).push_back(trueHitGlobal.Z());
713 
714  rootVariables.PosResidueXGlobal.at(spLayer).push_back((spacePointGlobal - trueHitGlobal).X());
715  rootVariables.PosResidueYGlobal.at(spLayer).push_back((spacePointGlobal - trueHitGlobal).Y());
716  rootVariables.PosResidueZGlobal.at(spLayer).push_back((spacePointGlobal - trueHitGlobal).Z());
717 
718  rootVariables.PosResiduesGlobal.at(spLayer).push_back((spacePointGlobal - trueHitGlobal).Mag());
719  rootVariables.PosResiduesLocal.at(spLayer).push_back((spacePointLocal - trueHitLocal).Mag());
720 
721  singleCluster = false;
722  }
723 
724  B2DEBUG(200, "Global (x,y,z)/Local (U,V) positions of SpacePoint: (" << spacePointGlobal.X() << "," << spacePointGlobal.Y() << ","
725  << spacePointGlobal.Z() << ")/(" << spacePointLocal.X() << "," << spacePointLocal.Y() << "). This was a singleCluster SpacePoint: "
726  << singleCluster);
727 
728  B2DEBUG(200, "Global (x,y,z)/Local (U,V) positions of TrueHit: (" << trueHitGlobal.X() << "," << trueHitGlobal.Y() << "," <<
729  trueHitGlobal.Z() << ")/(" << trueHitLocal.X() << "," << trueHitLocal.Y() << ")");
730 
731  B2DEBUG(200, "This leads to position differences global/local: " << (spacePointGlobal - trueHitGlobal).Mag() << "/" <<
732  (spacePointLocal - trueHitLocal).Mag());
733 
734 }
735 
736 // =================================== WRITE TO ROOT ===============================================================================
737 void CurlingTrackCandSplitterModule::writeToRoot(RootVariables& rootVariables)
738 {
739  m_rootGlobalPosResiduals = rootVariables.PosResiduesGlobal;
740  m_rootLocalPosResiduals = rootVariables.PosResiduesLocal;
741 
742  m_rootSpacePointULocals = rootVariables.SpacePointULocal;
743  m_rootSpacePointVLocals = rootVariables.SpacePointVLocal;
744 
745  m_rootSpacePointXGlobals = rootVariables.SpacePointXGlobal;
746  m_rootSpacePointYGlobals = rootVariables.SpacePointYGlobal;
747  m_rootSpacePointZGlobals = rootVariables.SpacePointZGlobal;
748 
749  m_rootTrueHitULocals = rootVariables.TrueHitULocal;
750  m_rootTrueHitVLocals = rootVariables.TrueHitVLocal;
751 
752  m_rootTrueHitXGlobals = rootVariables.TrueHitXGlobal;
753  m_rootTrueHitYGlobals = rootVariables.TrueHitYGlobal;
754  m_rootTrueHitZGlobals = rootVariables.TrueHitZGlobal;
755 
756  m_rootPosResidueXGlobal = rootVariables.PosResidueXGlobal;
757  m_rootPosResidueYGlobal = rootVariables.PosResidueYGlobal;
758  m_rootPosResidueZGlobal = rootVariables.PosResidueZGlobal;
759  m_rootPosResidueULocal = rootVariables.PosResidueULocal;
760  m_rootPosResidueVLocal = rootVariables.PosResidueVLocal;
761 
762  m_rootMisMatchPosDistance = rootVariables.MisMatchPosResiduals;
763  m_rootMisMatchPosX = rootVariables.MisMatchPosX;
764  m_rootMisMatchPosY = rootVariables.MisMatchPosY;
765  m_rootMisMatchPosZ = rootVariables.MisMatchPosZ;
766 
767  m_rootMisMatchPosU = rootVariables.MisMatchPosU;
768  m_rootMisMatchPosV = rootVariables.MisMatchPosV;
769 
770  m_rootMisMatchMomX = rootVariables.MisMatchMomX;
771  m_rootMisMatchMomY = rootVariables.MisMatchMomY;
772  m_rootMisMatchMomZ = rootVariables.MisMatchMomZ;
773 
774  m_treePtr->Fill();
775 }
776 
777 CurlingTrackCandSplitterModule::TaggedUVPos CurlingTrackCandSplitterModule::getUV(const Belle2::SpacePoint* spacePoint)
778 {
779  TaggedUVPos returnVals; // initialized to: both bools false, both doubles to 0.
780 
781  // get the normalized local coordinates from SpacePoint and convert them to local coordinates (have to do so because at the slanted parts the local U-position is dependant on the local V-position)
782  double normU = spacePoint->getNormalizedLocalU();
783  double normV = spacePoint->getNormalizedLocalV();
784 
785  // convert normalized coordinates to local coordinates (those are already 'unwedged')
786  std::pair<double, double> localUV = SpacePoint::convertNormalizedToLocalCoordinates(std::make_pair(normU, normV),
787  spacePoint->getVxdID());
788  //double unwedgedU = SpacePoint::getUUnwedged(localUV, spacePoint->getVxdID());
789 
790  // set values for return: set both m_U and m_V regardless if they have actually been set in the SpacePoint and simply assign the m_setX tags, as they decide if a value is actually used
791  std::pair<bool, bool> setCoords = spacePoint->getIfClustersAssigned();
792 
793  returnVals.m_setU = setCoords.first;
794  returnVals.m_setV = setCoords.second;
795  returnVals.m_U = localUV.first;
796  returnVals.m_V = localUV.second;
797 
798  return returnVals;
799 }
800 
801 // ====================================================== INITIALIZE COUNTERS =======================================================
802 void CurlingTrackCandSplitterModule::initializeCounters()
803 {
804  m_createdTrackStubsCtr = 0;
805  m_curlingTCCtr = 0;
806  m_noDecisionPossibleCtr = 0;
807  m_spacePointTCCtr = 0;
808  m_NoSingleTrueHitCtr = 0;
809  m_NoCurlingTCsCtr = 0;
810 }
Belle2::RelationVector::size
size_t size() const
Get number of relations.
Definition: RelationVector.h:98
Belle2::StoreArray::appendNew
T * appendNew()
Construct a new T object at the end of the array.
Definition: StoreArray.h:256
Belle2::CurlingTrackCandSplitterModule::TaggedUVPos::m_setU
bool m_setU
indicator if U is set
Definition: CurlingTrackCandSplitterModule.h:135
Belle2::CurlingTrackCandSplitterModule::RootVariables::PosResidueYGlobal
std::array< std::vector< double >, c_nPlanes > PosResidueYGlobal
Y-position (global) difference between TrueHit and SpacePoint (layerwise)
Definition: CurlingTrackCandSplitterModule.h:93
Belle2::B2Vector3::Perp
DataType Perp() const
The transverse component (R in cylindrical coordinate system).
Definition: B2Vector3.h:199
Belle2::VxdID
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:43
Belle2::CurlingTrackCandSplitterModule::RootVariables::MisMatchPosU
std::array< std::vector< double >, c_nPlanes > MisMatchPosU
Difference of U-positions (local) for mismatched TrueHits (layerwise)
Definition: CurlingTrackCandSplitterModule.h:119
Belle2::StoreArray::registerRelationTo
bool registerRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut, const std::string &namedRelation="") const
Register a relation to the given StoreArray.
Definition: StoreArray.h:150
Belle2::PXDTrueHit
Class PXDTrueHit - Records of tracks that either enter or leave the sensitive volume.
Definition: PXDTrueHit.h:35
Belle2::SpacePointTrackCand::getHitsInRange
const std::vector< const Belle2::SpacePoint * > getHitsInRange(int firstInd, int lastInd) const
get hits (SpacePoints) in range (indices of SpacePoint inside SpacePointTrackCand) including first in...
Definition: SpacePointTrackCand.cc:69
Belle2::SpacePoint::X
double X() const
return the x-value of the global position of the SpacePoint
Definition: SpacePoint.h:133
REG_MODULE
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:652
Belle2::CurlingTrackCandSplitterModule::RootVariables::SpacePointULocal
std::array< std::vector< double >, c_nPlanes > SpacePointULocal
local u-positions of SpacePoints (layerwise)
Definition: CurlingTrackCandSplitterModule.h:82
Belle2::CurlingTrackCandSplitterModule::RootVariables::TrueHitZGlobal
std::array< std::vector< double >, c_nPlanes > TrueHitZGlobal
global z-positions of TrueHits (layerwise)
Definition: CurlingTrackCandSplitterModule.h:88
Belle2::SpacePoint::Z
double Z() const
return the z-value of the global position of the SpacePoint
Definition: SpacePoint.h:139
Belle2::CurlingTrackCandSplitterModule::TaggedUVPos::m_setV
bool m_setV
indicator if V is set
Definition: CurlingTrackCandSplitterModule.h:136
Belle2::CurlingTrackCandSplitterModule::RootVariables::MisMatchMomZ
std::array< std::vector< double >, c_nPlanes > MisMatchMomZ
Difference of Momentum in Z-Direction for TrueHits that do not match but are related from one SpacePo...
Definition: CurlingTrackCandSplitterModule.h:128
Belle2::CurlingTrackCandSplitterModule::RootVariables::PosResidueZGlobal
std::array< std::vector< double >, c_nPlanes > PosResidueZGlobal
Z-position (global) difference between TrueHit and SpacePoint (layerwise)
Definition: CurlingTrackCandSplitterModule.h:95
Belle2::SpacePointTrackCand::setSortingParameters
void setSortingParameters(const std::vector< double > &sortParams)
set the sorting parameters
Definition: SpacePointTrackCand.cc:136
Belle2::SpacePoint::getIfClustersAssigned
std::pair< bool, bool > getIfClustersAssigned() const
Returns, if u(v)-coordinate is based on cluster information.
Definition: SpacePoint.h:172
Belle2::VXD::SensorInfoBase::vectorToGlobal
TVector3 vectorToGlobal(const TVector3 &local, bool reco=false) const
Convert a vector from local to global coordinates.
Definition: SensorInfoBase.h:383
Belle2::SVDTrueHit
Class SVDTrueHit - Records of tracks that either enter or leave the sensitive volume.
Definition: SVDTrueHit.h:35
Belle2::CurlingTrackCandSplitterModule
Module for checking SpacePointTrackCandidates for curling behaviour and splitting them into Track Can...
Definition: CurlingTrackCandSplitterModule.h:55
Belle2::RelationsInterface::getArrayName
std::string getArrayName() const
Get name of array this object is stored in, or "" if not found.
Definition: RelationsObject.h:379
Belle2::RelationsInterface::addRelationTo
void addRelationTo(const RelationsInterface< BASE > *object, float weight=1.0, const std::string &namedRelation="") const
Add a relation from this object to another object (with caching).
Definition: RelationsObject.h:144
Belle2::VXD::SensorInfoBase
Base class to provide Sensor Information for PXD and SVD.
Definition: SensorInfoBase.h:40
Belle2::CurlingTrackCandSplitterModule::RootVariables::SpacePointXGlobal
std::array< std::vector< double >, c_nPlanes > SpacePointXGlobal
global x-positions of SpacePoints (layerwise)
Definition: CurlingTrackCandSplitterModule.h:78
Belle2::RelationsInterface::getRelatedTo
TO * getRelatedTo(const std::string &name="", const std::string &namedRelation="") const
Get the object to which this object has a relation.
Definition: RelationsObject.h:250
Belle2::SpacePointTrackCand::setCovSeed
void setCovSeed(const TMatrixDSym &cov)
set the covariance matrix seed
Definition: SpacePointTrackCand.h:313
Belle2::B2Vector3::Z
DataType Z() const
access variable Z (= .at(2) without boundary check)
Definition: B2Vector3.h:434
Belle2::RelationsInterface::getRelationsTo
RelationVector< TO > getRelationsTo(const std::string &name="", const std::string &namedRelation="") const
Get the relations that point from this object to another store array.
Definition: RelationsObject.h:199
Belle2::SpacePoint
SpacePoint typically is build from 1 PXDCluster or 1-2 SVDClusters.
Definition: SpacePoint.h:52
Belle2::CurlingTrackCandSplitterModule::TaggedUVPos
struct for easier handling of getting U- & V-position of SpacePoints and some difficulties that arise...
Definition: CurlingTrackCandSplitterModule.h:134
Belle2::SpacePoint::getPosition
const B2Vector3< double > & getPosition() const
return the position vector in global coordinates
Definition: SpacePoint.h:148
Belle2::SpacePointTrackCand::setTrackStubIndex
void setTrackStubIndex(int trackStubInd)
set TrackStub index
Definition: SpacePointTrackCand.h:338
Belle2::CurlingTrackCandSplitterModule::RootVariables::MisMatchMomX
std::array< std::vector< double >, c_nPlanes > MisMatchMomX
Difference of Momentum in X-Direction for TrueHits that do not match but are related from one SpacePo...
Definition: CurlingTrackCandSplitterModule.h:124
Belle2::CurlingTrackCandSplitterModule::RootVariables::MisMatchPosZ
std::array< std::vector< double >, c_nPlanes > MisMatchPosZ
Difference of Z-positions (global) for mismatched TrueHits (layerwise)
Definition: CurlingTrackCandSplitterModule.h:116
Belle2::B2Vector3< double >
Belle2::SpacePoint::Y
double Y() const
return the y-value of the global position of the SpacePoint
Definition: SpacePoint.h:136
Belle2::SpacePointTrackCand::getNHits
unsigned int getNHits() const
get the number of hits (space points) in the track candidate
Definition: SpacePointTrackCand.h:154
Belle2::CurlingTrackCandSplitterModule::RootVariables::TrueHitYGlobal
std::array< std::vector< double >, c_nPlanes > TrueHitYGlobal
global y-positions of TrueHits (layerwise)
Definition: CurlingTrackCandSplitterModule.h:87
Belle2::SpacePointTrackCand::getSortingParametersInRange
const std::vector< double > getSortingParametersInRange(int firstIndex, int lastIndex) const
get the sorting parameters in range (indices of SpacePoints inside SpacePointTrackCand) including fir...
Definition: SpacePointTrackCand.cc:86
Belle2::CurlingTrackCandSplitterModule::RootVariables::PosResidueVLocal
std::array< std::vector< double >, c_nPlanes > PosResidueVLocal
V-position (local) difference between TrueHit and SpacePoint (layerwise)
Definition: CurlingTrackCandSplitterModule.h:100
Belle2::SpacePointTrackCand::set6DSeed
void set6DSeed(const TVectorD &state6D)
set the 6D state seed
Definition: SpacePointTrackCand.h:308
Belle2::RelationVector
Class for type safe access to objects that are referred to in relations.
Definition: DataStore.h:38
Belle2::SpacePointTrackCand::getPdgCode
int getPdgCode() const
get pdg code
Definition: SpacePointTrackCand.h:164
Belle2::SpacePointTrackCand::getHits
const std::vector< const Belle2::SpacePoint * > & getHits() const
get hits (space points) of track candidate
Definition: SpacePointTrackCand.h:131
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::StoreObjPtr
Type-safe access to single objects in the data store.
Definition: ParticleList.h:33
Belle2::CurlingTrackCandSplitterModule::RootVariables::TrueHitULocal
std::array< std::vector< double >, c_nPlanes > TrueHitULocal
local u-positions of TrueHits (layerwise)
Definition: CurlingTrackCandSplitterModule.h:102
Belle2::SpacePointTrackCand::setFlightDirection
void setFlightDirection(bool direction)
set the direction of flight (true is outgoing, false is ingoing).
Definition: SpacePointTrackCand.h:335
Belle2::CurlingTrackCandSplitterModule::RootVariables::MisMatchPosX
std::array< std::vector< double >, c_nPlanes > MisMatchPosX
Difference of X-positions (global) for mismatched TrueHits (layerwise)
Definition: CurlingTrackCandSplitterModule.h:112
Belle2::CurlingTrackCandSplitterModule::RootVariables::SpacePointZGlobal
std::array< std::vector< double >, c_nPlanes > SpacePointZGlobal
global z-positions of SpacePoints (layerwise)
Definition: CurlingTrackCandSplitterModule.h:80
Belle2::CurlingTrackCandSplitterModule::RootVariables::MisMatchPosY
std::array< std::vector< double >, c_nPlanes > MisMatchPosY
Difference of Y-positions (global) for mismatched TrueHits (layerwise)
Definition: CurlingTrackCandSplitterModule.h:114
Belle2::SpacePoint::getNormalizedLocalV
double getNormalizedLocalV() const
Return normalized local coordinates of the cluster in v (0 <= posV <= 1).
Definition: SpacePoint.h:164
Belle2::PXDCluster
The PXD Cluster class This class stores all information about reconstructed PXD clusters The position...
Definition: PXDCluster.h:41
Belle2::RelationsInterface::getArrayIndex
int getArrayIndex() const
Returns this object's array index (in StoreArray), or -1 if not found.
Definition: RelationsObject.h:387
Belle2::VXD::SensorInfoBase::pointToGlobal
TVector3 pointToGlobal(const TVector3 &local, bool reco=false) const
Convert a point from local to global coordinates.
Definition: SensorInfoBase.h:373
Belle2::SpacePointTrackCand::getChargeSeed
double getChargeSeed() const
get charge
Definition: SpacePointTrackCand.h:169
Belle2::CurlingTrackCandSplitterModule::RootVariables
Internal DataStore for ROOT output variables.
Definition: CurlingTrackCandSplitterModule.h:77
Belle2::CurlingTrackCandSplitterModule::TaggedUVPos::m_V
double m_V
V-position.
Definition: CurlingTrackCandSplitterModule.h:138
Belle2::CurlingTrackCandSplitterModule::RootVariables::TrueHitVLocal
std::array< std::vector< double >, c_nPlanes > TrueHitVLocal
local v-positions of TrueHits (layerwise)
Definition: CurlingTrackCandSplitterModule.h:103
Belle2::SVDCluster
The SVD Cluster class This class stores all information about reconstructed SVD clusters.
Definition: SVDCluster.h:38
Belle2::CurlingTrackCandSplitterModule::TaggedUVPos::m_U
double m_U
U-position.
Definition: CurlingTrackCandSplitterModule.h:137
Belle2::VXD::GeoCache
Class to faciliate easy access to sensor information of the VXD like coordinate transformations or pi...
Definition: GeoCache.h:41
Belle2::CurlingTrackCandSplitterModule::RootVariables::PosResiduesGlobal
std::array< std::vector< double >, c_nPlanes > PosResiduesGlobal
position differences in global coordinates (layerwise)
Definition: CurlingTrackCandSplitterModule.h:107
Belle2::CurlingTrackCandSplitterModule::RootVariables::PosResiduesLocal
std::array< std::vector< double >, c_nPlanes > PosResiduesLocal
position differences in local coordinates (layerwise)
Definition: CurlingTrackCandSplitterModule.h:106
Belle2::CurlingTrackCandSplitterModule::RootVariables::PosResidueXGlobal
std::array< std::vector< double >, c_nPlanes > PosResidueXGlobal
X-position (global) difference between TrueHit and SpacePoint (layerwise)
Definition: CurlingTrackCandSplitterModule.h:91
Belle2::CurlingTrackCandSplitterModule::RootVariables::MisMatchPosResiduals
std::array< std::vector< double >, c_nPlanes > MisMatchPosResiduals
Distance between TrueHits that do not match but are related from one SpacePoint (layerwise)
Definition: CurlingTrackCandSplitterModule.h:110
Belle2::StoreArray< SpacePointTrackCand >
Belle2::VxdID::getLayerNumber
baseType getLayerNumber() const
Get the layer id.
Definition: VxdID.h:106
Belle2::CurlingTrackCandSplitterModule::RootVariables::SpacePointVLocal
std::array< std::vector< double >, c_nPlanes > SpacePointVLocal
local v-positions of SpacePoints (layerwise)
Definition: CurlingTrackCandSplitterModule.h:83
Belle2::SpacePointTrackCand::getStateSeed
const TVectorD & getStateSeed() const
get state seed as 6D vector
Definition: SpacePointTrackCand.h:175
Belle2::SpacePointTrackCand::getCovSeed
const TMatrixDSym & getCovSeed() const
get the covariance matrix seed (6D).
Definition: SpacePointTrackCand.h:172
Belle2::B2Vector3::X
DataType X() const
access variable X (= .at(0) without boundary check)
Definition: B2Vector3.h:430
Belle2::CurlingTrackCandSplitterModule::RootVariables::MisMatchMomY
std::array< std::vector< double >, c_nPlanes > MisMatchMomY
Difference of Momentum in Y-Direction for TrueHits that do not match but are related from one SpacePo...
Definition: CurlingTrackCandSplitterModule.h:126
Belle2::SpacePointTrackCand::getMcTrackID
int getMcTrackID() const
get the MC Track ID
Definition: SpacePointTrackCand.h:201
Belle2::SpacePoint::getType
Belle2::VXD::SensorInfoBase::SensorType getType() const
Return SensorType (PXD, SVD, ...) on which the SpacePoint lives.
Definition: SpacePoint.h:155
Belle2::CurlingTrackCandSplitterModule::RootVariables::PosResidueULocal
std::array< std::vector< double >, c_nPlanes > PosResidueULocal
U-position (local) differnece between TrueHit and SpacePoint (layerwise)
Definition: CurlingTrackCandSplitterModule.h:98
Belle2::StoreArray::getEntries
int getEntries() const
Get the number of objects in the array.
Definition: StoreArray.h:226
Belle2::B2Vector3::Y
DataType Y() const
access variable Y (= .at(1) without boundary check)
Definition: B2Vector3.h:432
Belle2::CurlingTrackCandSplitterModule::RootVariables::SpacePointYGlobal
std::array< std::vector< double >, c_nPlanes > SpacePointYGlobal
global y-positions of SpacePoints (layerwise)
Definition: CurlingTrackCandSplitterModule.h:79
Belle2::SpacePointTrackCand
Storage for (VXD) SpacePoint-based track candidates.
Definition: SpacePointTrackCand.h:51
Belle2::CurlingTrackCandSplitterModule::RootVariables::TrueHitXGlobal
std::array< std::vector< double >, c_nPlanes > TrueHitXGlobal
global x-positions of TrueHits (layerwise)
Definition: CurlingTrackCandSplitterModule.h:86
Belle2::SpacePoint::getVxdID
VxdID getVxdID() const
Return the VxdID of the sensor on which the the cluster of the SpacePoint lives.
Definition: SpacePoint.h:158
Belle2::SpacePoint::getNormalizedLocalU
double getNormalizedLocalU() const
Return normalized local coordinates of the cluster in u (0 <= posU <= 1).
Definition: SpacePoint.h:161
Belle2::CurlingTrackCandSplitterModule::RootVariables::MisMatchPosV
std::array< std::vector< double >, c_nPlanes > MisMatchPosV
Difference of V-positions (local) for mismatched TrueHits (layerwise)
Definition: CurlingTrackCandSplitterModule.h:121