Belle II Software development
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
20using namespace std;
21using namespace Belle2;
22using namespace Belle2::PXD;
23using namespace boost::python;
24
25
26//-----------------------------------------------------------------
27// Register the Module
28//-----------------------------------------------------------------
29REG_MODULE(PXDDigitSorter);
30
31//-----------------------------------------------------------------
32// Implementation
33//-----------------------------------------------------------------
34
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
PXDDigitSorterModule()
Constructor defining the parameters.
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
const std::string & getName() const
Return name under which the object is saved in the DataStore.
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.
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
TClonesArray * getPtr() const
Raw access to the underlying TClonesArray.
Definition: StoreArray.h:311
int getEntries() const
Get the number of objects in the array.
Definition: StoreArray.h:216
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.
STL namespace.
Struct for identity transformation on indices.
Definition: RelationArray.h:94