Belle II Software  release-08-01-10
PXDDigitSorterModule.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 <pxd/modules/pxdReconstruction/PXDDigitSorterModule.h>
10 #include <framework/datastore/StoreArray.h>
11 #include <framework/datastore/RelationArray.h>
12 #include <framework/logging/Logger.h>
13 #include <vxd/geometry/GeoCache.h>
14 
15 #include <mdst/dataobjects/MCParticle.h>
16 #include <pxd/dataobjects/PXDTrueHit.h>
17 #include <pxd/reconstruction/Pixel.h>
18 #include <pxd/reconstruction/PXDPixelMasker.h>
19 
20 using namespace std;
21 using namespace Belle2;
22 using namespace Belle2::PXD;
23 using namespace boost::python;
24 
25 
26 //-----------------------------------------------------------------
27 // Register the Module
28 //-----------------------------------------------------------------
29 REG_MODULE(PXDDigitSorter);
30 
31 //-----------------------------------------------------------------
32 // Implementation
33 //-----------------------------------------------------------------
34 
35 PXDDigitSorterModule::PXDDigitSorterModule() : Module()
36 {
37  //Set module properties
38  setDescription("This module sorts the existing PXDDigits collection and also "
39  "updates the corresponding Relation to MCParticles and TrueHits. This is "
40  "needed for unsorted pixel data as the Clusterizer expects sorted input.");
42  addParam("merge", m_mergeDuplicates, "If true, merge Pixel information if more than one digit exists for the same address", true);
43  addParam("trimDigits", m_trimDigits, "If true, pixel data will be checked to detect malformed pixels. Such pixels will be scarded.",
44  true);
45  addParam("digits", m_storeDigitsName, "PXDDigit collection name", string(""));
46  addParam("truehits", m_storeTrueHitsName, "PXDTrueHit collection name", string(""));
47  addParam("particles", m_storeMCParticlesName, "MCParticle collection name", string(""));
48  addParam("digitsToTrueHits", m_relDigitTrueHitName, "Digits to TrueHit relation name",
49  string(""));
50  addParam("digitsToMCParticles", m_relDigitMCParticleName, "Digits to MCParticles relation name",
51  string(""));
52 }
53 
55 {
56  //Register collections
60  storeDigits.isRequired();
61  storeMCParticles.isOptional();
62  storeTrueHits.isOptional();
63 
64  RelationArray relDigitMCParticles(storeDigits, storeMCParticles, m_relDigitMCParticleName);
65  RelationArray relDigitTrueHits(storeDigits, storeTrueHits, m_relDigitTrueHitName);
66  relDigitMCParticles.isOptional();
67  relDigitTrueHits.isOptional();
68 
69  m_storeDigitsName = storeDigits.getName();
70  m_storeTrueHitsName = storeTrueHits.getName();
71  m_storeMCParticlesName = storeMCParticles.getName();
72 
73  m_relDigitTrueHitName = relDigitTrueHits.getName();
74  m_relDigitMCParticleName = relDigitMCParticles.getName();
75 }
76 
78 {
80  // If not digits, nothing to do
81  if (!storeDigits || !storeDigits.getEntries()) return;
82 
84 
85  RelationArray relDigitMCParticle(m_relDigitMCParticleName);
86  RelationArray relDigitTrueHit(m_relDigitTrueHitName);
87 
88  //List of mappings from old indices to new indices
89  std::vector<RelationArray::consolidation_type> relationIndices(storeDigits.getEntries());
90  //Mapping of Pixel information to sort according to VxdID, row, column
91  std::map<VxdID, std::multiset<Pixel>> sensors;
92 
93  // Fill sensor information to get sorted PXDDigit indices
94  const int nPixels = storeDigits.getEntries();
95  for (int i = 0; i < nPixels; i++) {
96  const PXDDigit* const storeDigit = storeDigits[i];
97  VxdID sensorID = storeDigit->getSensorID();
98  if (!geo.validSensorID(sensorID)) {
99  B2DEBUG(20, "Malformed PXDDigit, VxdID $" << hex << sensorID.getID() << ", dropping. (" << sensorID << ")");
100  continue;
101  }
102 
103  if (PXDPixelMasker::getInstance().pixelDead(storeDigit->getSensorID(), storeDigit->getUCellID(), storeDigit->getVCellID())
104  || !PXDPixelMasker::getInstance().pixelOK(storeDigit->getSensorID(), storeDigit->getUCellID(), storeDigit->getVCellID())) {
105  continue;
106  }
107  // Trim digits
108  if (!m_trimDigits || goodDigit(storeDigit)) {
109  Pixel px(storeDigit, i);
110  sensors[sensorID].insert(px);
111  } else {
112  B2DEBUG(20, "Encountered a malformed digit in PXDDigit sorter: " << endl
113  << "VxdID: " << sensorID.getLayerNumber() << "/"
114  << sensorID.getLadderNumber() << "/"
115  << sensorID.getSensorNumber() << " u = " << storeDigit->getUCellID() << "v = " << storeDigit->getVCellID()
116  << " DISCARDED.");
117  }
118  }
119 
120  // Now we loop over sensors and reorder the digits list
121  // To do this, we create a copy of the existing digits
122  m_digitcopy.clear();
123  m_digitcopy.insert(end(m_digitcopy), begin(storeDigits), end(storeDigits));
124  // and a vector to remember which index changed into what
125  unsigned int index(0);
126  // And just loop over the sensors and assign the digits at the correct position
127  for (const auto& sensor : sensors) {
128  const PXD::Pixel* lastpx(0);
129  for (const PXD::Pixel& px : sensor.second) {
130  //Normal case: pixel has different address
131  if (!lastpx || px > *lastpx) {
132  //Overwrite the digit
133  *storeDigits[index] = m_digitcopy[px.getIndex()];
134  //Remember old and new index
135  relationIndices[px.getIndex()] = std::make_pair(index, false);
136  //increment next index
137  ++index;
138  } else {
139  //We already have a pixel at this address, see if we merge or drop the new one
140  if (m_mergeDuplicates) {
141  //Merge the two pixels. As the PXDDigit does not have setters we have to create a new object.
142  const PXDDigit& old = *storeDigits[index - 1];
143  // FIXME: Does it really make sense to add the charge of duplicate pixels?
144  *storeDigits[index - 1] = PXDDigit(old.getSensorID(), old.getUCellID(), old.getVCellID(),
145  old.getCharge() + m_digitcopy[px.getIndex()].getCharge());
146  relationIndices[px.getIndex()] = std::make_pair(index - 1, false);
147  } else {
148  //Otherwise delete the second pixel by omitting it here and removing relation elements on consolidation
149  relationIndices[px.getIndex()] = std::make_pair(0, true);
150  }
151  }
152  lastpx = &px;
153  }
154  }
155  //Resize if we omitted/merged one or more elements
156  storeDigits.getPtr()->ExpandCreate(index);
157 
158  // Finally we just need to reorder the RelationArrays and delete elements
159  // referencing pixels which were ignored because that adress was set more
160  // than once
161  RelationArray::ReplaceVec<> from(relationIndices);
163  if (relDigitMCParticle) relDigitMCParticle.consolidate(from, to, RelationArray::c_deleteElement);
164  if (relDigitTrueHit) relDigitTrueHit.consolidate(from, to, RelationArray::c_deleteElement);
165 }
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
The PXD digit class.
Definition: PXDDigit.h:27
unsigned short getVCellID() const
Get cell ID in v.
Definition: PXDDigit.h:74
unsigned short getUCellID() const
Get cell ID in u.
Definition: PXDDigit.h:69
unsigned short getCharge() const
Get collected charge.
Definition: PXDDigit.h:79
VxdID getSensorID() const
Get the sensor ID.
Definition: PXDDigit.h:64
virtual void initialize() override
Initialize the module.
bool m_mergeDuplicates
Mode: if true, merge duplicate pixels, otherwise delete all but the first occurence.
std::string m_relDigitMCParticleName
Name of the relation between PXDDigits and MCParticles.
virtual void event() override
do the sorting
std::string m_storeTrueHitsName
Name of the collection to use for the PXDTrueHits.
std::string m_storeMCParticlesName
Name of the collection to use for the MCParticles.
std::vector< PXDDigit > m_digitcopy
Copy of the Digits needed for sorting.
std::string m_storeDigitsName
Name of the collection to use for the PXDDigits.
bool goodDigit(const PXDDigit *const digit) const
Utility function to check pixel coordinates.
std::string m_relDigitTrueHitName
Name of the relation between PXDDigits and PXDTrueHits.
bool m_trimDigits
if true, check digit data and discard malformed digits.
bool pixelOK(VxdID id, unsigned int uid, unsigned int vid) const
Check whether a pixel on a given sensor is OK or not.
static PXDPixelMasker & getInstance()
Main (and only) way to access the PXDPixelMasker.
Class to represent one pixel, used in clustering for fast access.
Definition: Pixel.h:36
unsigned int getIndex() const
Return the Index of the digit.
Definition: Pixel.h:72
Struct to replace indices based on a sequential container.
Low-level class to create/modify relations between StoreArrays.
Definition: RelationArray.h:62
void consolidate()
Consolidate Relation Elements.
@ c_deleteElement
Delete the whole relation element if the original element got re-attributed.
Definition: RelationArray.h:81
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
bool isOptional(const std::string &name="")
Tell the DataStore about an optional input.
const std::string & getName() const
Return name under which the object is saved in the DataStore.
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
int getEntries() const
Get the number of objects in the array.
Definition: StoreArray.h:216
TClonesArray * getPtr() const
Raw access to the underlying TClonesArray.
Definition: StoreArray.h:311
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
bool validSensorID(Belle2::VxdID id) const
Check that id is a valid sensor number.
Definition: GeoCache.cc:52
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
baseType getID() const
Get the unique id.
Definition: VxdID.h:94
baseType getSensorNumber() const
Get the sensor id.
Definition: VxdID.h:100
baseType getLadderNumber() const
Get the ladder id.
Definition: VxdID.h:98
baseType getLayerNumber() const
Get the layer id.
Definition: VxdID.h:96
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Namespace to encapsulate code needed for simulation and reconstrucion of the PXD.
Abstract base class for different kinds of events.
Struct for identity transformation on indices.
Definition: RelationArray.h:94