Belle II Software  release-06-02-00
WireHitCreator.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 #include <tracking/trackFindingCDC/findlets/minimal/WireHitCreator.h>
9 
10 #include <tracking/trackFindingCDC/eventdata/hits/CDCWireHit.h>
11 #include <tracking/trackFindingCDC/eventdata/utils/FlightTimeEstimator.h>
12 
13 #include <tracking/trackFindingCDC/findlets/minimal/EPreferredDirection.h>
14 
15 #include <tracking/trackFindingCDC/topology/CDCWireTopology.h>
16 
17 #include <tracking/trackFindingCDC/utilities/StringManipulation.h>
18 
19 #include <cdc/translators/RealisticTDCCountTranslator.h>
20 #include <cdc/translators/LinearGlobalADCCountTranslator.h>
21 #include <cdc/geometry/CDCGeometryPar.h>
22 
23 #include <cdc/dataobjects/CDCHit.h>
24 
25 #include <framework/datastore/StoreArray.h>
26 #include <framework/core/ModuleParamList.templateDetails.h>
27 
28 #include <mdst/dataobjects/MCParticle.h>
29 
30 using namespace Belle2;
31 using namespace TrackFindingCDC;
32 
35 
37 {
38  return "Combines the geometrical information and the raw hit information into wire hits, "
39  "which can be used from all modules after that";
40 }
41 
42 void WireHitCreator::exposeParameters(ModuleParamList* moduleParamList, const std::string& prefix)
43 {
44  moduleParamList->addParameter(prefixed(prefix, "wirePosition"),
46  "Set of geometry parameters to be used in the track finding. "
47  "Either 'base', 'misaligned' or 'aligned'.",
49 
50  moduleParamList->addParameter(prefixed(prefix, "ignoreWireSag"),
52  "Assume a wire sag coefficient of zero "
53  "such that the wires appear to be straight for "
54  "the track finders",
56 
57  moduleParamList->addParameter(prefixed(prefix, "flightTimeEstimation"),
59  "Option which flight direction should be assumed for "
60  "an initial time of flight estimation. Options are: "
61  "'none' (no TOF correction), "
62  "'outwards', "
63  "'downwards'.",
65 
66  moduleParamList->addParameter(prefixed(prefix, "triggerPoint"),
68  "Point relative to which the flight times are calculated",
70 
71  moduleParamList->addParameter(prefixed(prefix, "useSuperLayers"),
73  "List of super layers to be used.",
75 
76  moduleParamList->addParameter(prefixed(prefix, "useLayers"),
78  "List of layers to be used. "
79  "If a layer number is given in 'ignoreLayers', too, this will result on a B2FATAL. "
80  "Either use 'useLayers' and provide a set of layers to be used, "
81  "or use 'ignoreLayers' and provide a list of layers to be ignored, but not both at the same time.",
83 
84  moduleParamList->addParameter(prefixed(prefix, "ignoreLayers"),
86  "List of layers to be ignored. "
87  "If a layer number is given in 'useLayers', too, this will result on a B2FATAL. "
88  "Either use 'useLayers' and provide a set of layers to be used, "
89  "or use 'ignoreLayers' and provide a list of layers to be ignored, but not both at the same time.",
91 
92  moduleParamList->addParameter(prefixed(prefix, "useSecondHits"),
94  "Use the second hit information in the track finding.",
96 
97  moduleParamList->addParameter(prefixed(prefix, "useBadWires"),
99  "Also create the hits that are on bad wires.",
101 
102  moduleParamList->addParameter(prefixed(prefix, "useDegreeSector"),
104  "To angles in degrees for which hits should be created - mostly for debugging",
106 
107  moduleParamList->addParameter(prefixed(prefix, "useMCParticleIds"),
109  "Ids of the MC particles to use. Default does not look at the MCParticles - most for debugging",
111 }
112 
114 {
115  StoreArray<CDCHit> hits;
116  hits.isRequired();
117 
118  // Create the wires and layers once during initialisation
120 
121  if (m_param_wirePosition == "base") {
122  m_wirePosition = EWirePosition::c_Base;
123  } else if (m_param_wirePosition == "misaligned") {
124  m_wirePosition = EWirePosition::c_Misaligned;
125  } else if (m_param_wirePosition == "aligned") {
126  m_wirePosition = EWirePosition::c_Aligned;
127  } else {
128  B2ERROR("Received unknown wirePosition " << m_param_wirePosition);
129  }
130 
133 
134  if (m_param_flightTimeEstimation != std::string("")) {
135  try {
136  m_flightTimeEstimation = getPreferredDirection(m_param_flightTimeEstimation);
137  } catch (std::invalid_argument& e) {
138  B2ERROR("Unexpected 'flightTimeEstimation' parameter : '" << m_param_flightTimeEstimation);
139  }
140  }
141 
143  std::get<1>(m_param_triggerPoint),
144  std::get<2>(m_param_triggerPoint));
145 
146  if (m_flightTimeEstimation == EPreferredDirection::c_Symmetric) {
147  B2ERROR("Unexpected 'flightTimeEstimation' parameter : '" << m_param_flightTimeEstimation);
148  } else if (m_flightTimeEstimation == EPreferredDirection::c_Downwards) {
149  FlightTimeEstimator::instance(std::make_unique<CosmicRayFlightTimeEstimator>(m_triggerPoint));
150  } else if (m_flightTimeEstimation == EPreferredDirection::c_Outwards) {
151  FlightTimeEstimator::instance(std::make_unique<BeamEventFlightTimeEstimator>());
152  }
153 
154  if (not m_param_useSuperLayers.empty()) {
155  for (const ISuperLayer iSL : m_param_useSuperLayers) {
156  m_useSuperLayers.at(iSL) = true;
157  }
158  } else {
159  m_useSuperLayers.fill(true);
160  }
161 
162  // Check for common value in the two vectors for using / ignoring layers
163  for (const uint useLayer : m_param_useLayers) {
164  for (const uint ingoreLayer : m_param_ignoreLayers) {
165  if (useLayer == ingoreLayer) {
166  B2FATAL("You chose to use and ignore CDC layer " << useLayer << " at the same time. "
167  "Please decide to either use or to ignore the layer.");
168  }
169  }
170  }
171 
172  // fill all layers that should be used
173  if (not m_param_useLayers.empty()) {
174  for (const uint layer : m_param_useLayers) {
175  m_useLayers.at(layer) = true;
176  }
177  } else {
178  m_useLayers.fill(true);
179  }
180  // set layers that should be ignored to false
181  if (not m_param_ignoreLayers.empty()) {
182  for (const uint layer : m_param_ignoreLayers) {
183  m_useLayers.at(layer) = false;
184  }
185  }
186 
187  if (std::isfinite(std::get<0>(m_param_useDegreeSector))) {
190  }
191 
193 }
194 
196 {
197  Super::beginRun();
200 }
201 
202 void WireHitCreator::apply(std::vector<CDCWireHit>& outputWireHits)
203 {
204  // Wire hits have been created before
205  if (not outputWireHits.empty()) return;
206 
207  const CDCWireTopology& wireTopology = CDCWireTopology::getInstance();
208  CDC::TDCCountTranslatorBase& tdcCountTranslator = *m_tdcCountTranslator;
209  CDC::ADCCountTranslatorBase& adcCountTranslator = *m_adcCountTranslator;
211 
212  // Create the wire hits into a vector
213  StoreArray<CDCHit> hits;
214  std::size_t nHits = hits.getEntries();
215  if (nHits == 0) {
216  B2WARNING("Event with no hits");
217  outputWireHits.clear();
218  }
219 
220  std::map<int, size_t> nHitsByMCParticleId;
221 
222  outputWireHits.reserve(nHits);
223  for (const CDCHit& hit : hits) {
224 
225  // ignore this hit if it contains the information of a 2nd hit
226  if (!m_param_useSecondHits && hit.is2ndHit()) {
227  continue;
228  }
229 
230  // Only use some MCParticles if request - mostly for debug
231  if (not m_param_useMCParticleIds.empty()) {
232  MCParticle* mcParticle = hit.getRelated<MCParticle>();
233  int mcParticleId = mcParticle->getArrayIndex();
234  if (mcParticle) {
235  nHitsByMCParticleId[mcParticleId]++;
236  }
237  bool useMCParticleId = std::count(m_param_useMCParticleIds.begin(),
239  mcParticleId);
240  if (not useMCParticleId) continue;
241  }
242 
243  WireID wireID(hit.getID());
244  if (not wireTopology.isValidWireID(wireID)) {
245  B2WARNING("Skip invalid wire id " << hit.getID());
246  continue;
247  }
248 
249  // ignore hit if it is on a bad wire
250  if (not m_param_useBadWires and geometryPar.isBadWire(wireID)) {
251  continue;
252  }
253 
254  ISuperLayer iSL = wireID.getISuperLayer();
255  if (not m_useSuperLayers[iSL]) continue;
256  unsigned short layer = wireID.getICLayer();
257  if (not m_useLayers[layer]) continue;
258 
259  const CDCWire& wire = wireTopology.getWire(wireID);
260 
261  const Vector2D& pos2D = wire.getRefPos2D();
262 
263  // Check whether the position is outside the selected sector
264  if (pos2D.isBetween(m_useSector[1], m_useSector[0])) continue;
265 
266  // Only use some MCParticles if request - mostly for debug
267  if (not m_param_useMCParticleIds.empty()) {
268  MCParticle* mcParticle = hit.getRelated<MCParticle>();
269  int mcParticleId = mcParticle->getArrayIndex();
270  if (mcParticle) {
271  nHitsByMCParticleId[mcParticleId]++;
272  }
273  bool useMCParticleId = std::count(m_param_useMCParticleIds.begin(),
275  mcParticleId);
276  if (not useMCParticleId) continue;
277  }
278 
279 
280 
281  // Consider the particle as incoming in the top part of the CDC for a downwards flight direction
282  bool isIncoming = m_flightTimeEstimation == EPreferredDirection::c_Downwards and pos2D.y() > 0;
283  const double alpha = isIncoming ? M_PI : 0;
284  const double beta = 1;
285  const double flightTimeEstimate =
286  FlightTimeEstimator::instance().getFlightTime2D(pos2D, alpha, beta);
287 
288  const double driftTime = tdcCountTranslator.getDriftTime(hit.getTDCCount(),
289  wire.getWireID(),
290  flightTimeEstimate,
291  wire.getRefZ(),
292  hit.getADCCount());
293  const bool left = false;
294  const bool right = true;
295  const double theta = M_PI / 2;
296 
297  const double leftRefDriftLength =
298  tdcCountTranslator.getDriftLength(hit.getTDCCount(),
299  wire.getWireID(),
300  flightTimeEstimate,
301  left,
302  wire.getRefZ(),
303  alpha,
304  theta);
305 
306  const double rightRefDriftLength =
307  tdcCountTranslator.getDriftLength(hit.getTDCCount(),
308  wire.getWireID(),
309  flightTimeEstimate,
310  right,
311  wire.getRefZ(),
312  alpha,
313  theta);
314 
315  const double refDriftLength =
316  (leftRefDriftLength + rightRefDriftLength) / 2.0;
317 
318  const double leftRefDriftLengthVariance =
319  tdcCountTranslator.getDriftLengthResolution(refDriftLength,
320  wire.getWireID(),
321  left,
322  wire.getRefZ(),
323  alpha,
324  theta);
325 
326  const double rightRefDriftLengthVariance =
327  tdcCountTranslator.getDriftLengthResolution(refDriftLength,
328  wire.getWireID(),
329  right,
330  wire.getRefZ(),
331  alpha,
332  theta);
333 
334  const double refDriftLengthVariance =
335  (leftRefDriftLengthVariance + rightRefDriftLengthVariance) / 2.0;
336 
337  const double leftRefChargeDeposit =
338  adcCountTranslator.getCharge(hit.getADCCount(),
339  wire.getWireID(),
340  left,
341  wire.getRefZ(),
342  theta);
343 
344  const double rightRefChargeDeposit =
345  adcCountTranslator.getCharge(hit.getADCCount(),
346  wire.getWireID(),
347  right,
348  wire.getRefZ(),
349  theta);
350 
351  const double refChargeDeposit =
352  (leftRefChargeDeposit + rightRefChargeDeposit) / 2.0;
353 
354  outputWireHits.emplace_back(&hit, refDriftLength, refDriftLengthVariance, refChargeDeposit, driftTime);
355  }
356 
357  std::sort(outputWireHits.begin(), outputWireHits.end());
358 
359  if (not m_param_useMCParticleIds.empty()) {
360  for (const std::pair<int, size_t> nHitsForMCParticleId : nHitsByMCParticleId) {
361  B2DEBUG(100,
362  "MC particle " << nHitsForMCParticleId.first << " #hits "
363  << nHitsForMCParticleId.second);
364  }
365  }
366 }
Class containing the result of the unpacker in raw data and the result of the digitizer in simulation...
Definition: CDCHit.h:40
Abstract Base class for the ADC count translator.
virtual float getCharge(unsigned short adcCount=0, const WireID &wireID=WireID(), bool ambiguityDiscriminator=false, float z=0, float theta=static_cast< float >(TMath::Pi()/2.))=0
Function, for which this actually was meant.
The Class for CDC Geometry Parameters.
bool isBadWire(const WireID &wid)
Inquire if the wire is totally-dead.
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
This class simply assumes a linear translation through (0,0)
Translator mirroring the realistic Digitization.
Base class for translation of Drift Time into Drift Length.
virtual double getDriftLength(unsigned short tdcCount=0, const WireID &wireID=WireID(), double timeOfFlightEstimator=0., bool ambiguityDiscriminator=false, double z=0, double alpha=0, double theta=static_cast< double >(TMath::Pi()/2.), unsigned short adcCount=0)=0
Function for getting a drift length estimation.
virtual double getDriftLengthResolution(double driftLength=0., const WireID &wireID=WireID(), bool ambiguityDiscriminator=false, double z=0, double alpha=0, double theta=static_cast< double >(TMath::Pi()/2.))=0
Uncertainty corresponding to drift length from getDriftLength of this class.
virtual double getDriftTime(unsigned short tdcCount, const WireID &wireID, double timeOfFlightEstimator, double z, unsigned short adcCount)=0
Get Drift time.
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:32
int getArrayIndex() const
Get 0-based index of the particle in the corresponding MCParticle list.
Definition: MCParticle.h:244
The Module parameter list class.
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
Class representating the sense wire arrangement in the whole of the central drift chamber.
void reinitialize(EWirePosition wirePosition, bool ignoreWireSag)
Reload all geometry parameters form the CDCGeometryPar to adjust to changes in geometry.
static CDCWireTopology & getInstance()
Getter for the singleton instance of the wire topology.
bool isValidWireID(const WireID &wireID) const
Checks the validity of a wireID convinience object.
const CDCWire & getWire(const WireID &wireId) const
Getter for wire getter by wireID object.
Class representing a sense wire in the central drift chamber.
Definition: CDCWire.h:58
const Vector2D & getRefPos2D() const
Getter for the wire reference position for 2D tracking Gives the wire's reference position projected ...
Definition: CDCWire.h:229
const WireID & getWireID() const
Getter for the wire id.
Definition: CDCWire.h:122
double getRefZ() const
Getter for the wire reference z coordinate Gives the wire's reference z coordinate.
Definition: CDCWire.h:236
void initialize() override
Receive and dispatch signal before the start of the event processing.
void beginRun() override
Receive and dispatch signal for the beginning of a new run.
static const FlightTimeEstimator & instance(std::unique_ptr< FlightTimeEstimator > replacement=nullptr)
Getter for the instance.
virtual double getFlightTime2D(const Vector2D &, double, double=1) const
Default estimator for the flight time.
A two dimensional vector which is equipped with functions for correct handeling of orientation relat...
Definition: Vector2D.h:35
bool isBetween(const Vector2D &lower, const Vector2D &upper) const
Checks if this vector is between two other vectors Between means here that when rotating the lower ve...
Definition: Vector2D.h:537
double y() const
Getter for the y coordinate.
Definition: Vector2D.h:617
static Vector2D Phi(const double phi)
Constucts a unit vector with azimuth angle equal to phi.
Definition: Vector2D.h:71
std::string m_param_wirePosition
Parameter : Geometry set to be used. Either "base", "misalign" or " aligned".
EPreferredDirection m_flightTimeEstimation
Method for the initial time of flight estimation.
std::array< bool, ISuperLayerUtil::c_N > m_useSuperLayers
Bits for the used super layers.
void initialize() final
Signals the beginning of the event processing.
void beginRun() final
Signal the beginning of a new run.
EWirePosition m_wirePosition
Geometry set to be used.
std::array< bool, 56 > m_useLayers
Bits for the used layers ATTENTION: hardcoded value for number of layers.
std::vector< int > m_param_useMCParticleIds
Parameter : Indices of the Monte Carlo particles for which hits should be used.
std::tuple< double, double, double > m_param_triggerPoint
Parameter : Location of the flight time zero.
std::unique_ptr< CDC::TDCCountTranslatorBase > m_tdcCountTranslator
TDC Count translator to be used to calculate the initial dirft length estiamtes.
std::string getDescription() final
Short description of the findlet.
std::string m_param_flightTimeEstimation
Parameter : Method for the initial time of flight estimation as string.
std::vector< uint > m_param_useLayers
Parameter : List of layers to be used.
std::vector< uint > m_param_ignoreLayers
Parameter : List of layers to be ignored in tracking e.g. for simulating too high occupancy.
void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix) final
Expose the parameters to a module.
std::tuple< double, double > m_param_useDegreeSector
Parameter : Angular range in degrees for which hits should be unpacked.
std::unique_ptr< CDC::ADCCountTranslatorBase > m_adcCountTranslator
ADC Count translator to be used to calculate the charge deposit in the drift cell.
std::vector< int > m_param_useSuperLayers
Parameter : List of super layers to be used - mostly for debugging.
bool m_param_ignoreWireSag
Parameter : Switch to deactivate the sag of the wires for the concerns of the track finders.
void apply(std::vector< CDCWireHit > &outputWireHits) final
Main algorithm creating the wire hits.
std::array< Vector2D, 2 > m_useSector
Unit vectors denoting the sector for which hits should be created.
bool m_param_useBadWires
Parameter : If true, the hits on bad wires are not ignored.
bool m_param_useSecondHits
Parameter : If true, the second hit information will be used to create Wire Hits.
Vector3D m_triggerPoint
Central location of the flight time zero position. Usually the location of the trigger.
static const double deg
degree to radians
Definition: Unit.h:109
Class to identify a wire inside the CDC.
Definition: WireID.h:34
unsigned short getICLayer() const
Getter for continuous layer numbering.
Definition: WireID.cc:24
unsigned short getISuperLayer() const
Getter for Super-Layer.
Definition: WireID.h:130
void addParameter(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module list.
HepGeom::Vector3D< double > Vector3D
3D Vector
Definition: Cell.h:34
Abstract base class for different kinds of events.