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 storeDigit->getCharge() <= PXDPixelMasker::getInstance().getPixelThreshold(storeDigit->getSensorID(), storeDigit->getUCellID(),
105 storeDigit->getVCellID())) {
106 continue;
107 }
108
109 // Trim digits
110 if (!m_trimDigits || goodDigit(storeDigit)) {
111 Pixel px(storeDigit, i);
112 sensors[sensorID].insert(px);
113 } else {
114 B2DEBUG(20, "Encountered a malformed digit in PXDDigit sorter: " << endl
115 << "VxdID: " << sensorID.getLayerNumber() << "/"
116 << sensorID.getLadderNumber() << "/"
117 << sensorID.getSensorNumber() << " u = " << storeDigit->getUCellID() << "v = " << storeDigit->getVCellID()
118 << " DISCARDED.");
119 }
120 }
121
122 // Now we loop over sensors and reorder the digits list
123 // To do this, we create a copy of the existing digits
124 m_digitcopy.clear();
125 m_digitcopy.insert(end(m_digitcopy), begin(storeDigits), end(storeDigits));
126 // and a vector to remember which index changed into what
127 unsigned int index(0);
128 // And just loop over the sensors and assign the digits at the correct position
129 for (const auto& sensor : sensors) {
130 const PXD::Pixel* lastpx(0);
131 for (const PXD::Pixel& px : sensor.second) {
132 //Normal case: pixel has different address
133 if (!lastpx || px > *lastpx) {
134 //Overwrite the digit
135 *storeDigits[index] = m_digitcopy[px.getIndex()];
136 //Remember old and new index
137 relationIndices[px.getIndex()] = std::make_pair(index, false);
138 //increment next index
139 ++index;
140 } else {
141 //We already have a pixel at this address, see if we merge or drop the new one
142 if (m_mergeDuplicates) {
143 //Merge the two pixels. As the PXDDigit does not have setters we have to create a new object.
144 const PXDDigit& old = *storeDigits[index - 1];
145 // FIXME: Does it really make sense to add the charge of duplicate pixels?
146 *storeDigits[index - 1] = PXDDigit(old.getSensorID(), old.getUCellID(), old.getVCellID(),
147 old.getCharge() + m_digitcopy[px.getIndex()].getCharge());
148 relationIndices[px.getIndex()] = std::make_pair(index - 1, false);
149 } else {
150 //Otherwise delete the second pixel by omitting it here and removing relation elements on consolidation
151 relationIndices[px.getIndex()] = std::make_pair(0, true);
152 }
153 }
154 lastpx = &px;
155 }
156 }
157 //Resize if we omitted/merged one or more elements
158 storeDigits.getPtr()->ExpandCreate(index);
159
160 // Finally we just need to reorder the RelationArrays and delete elements
161 // referencing pixels which were ignored because that address was set more
162 // than once
163 RelationArray::ReplaceVec<> from(relationIndices);
165 if (relDigitMCParticle) relDigitMCParticle.consolidate(from, to, RelationArray::c_deleteElement);
166 if (relDigitTrueHit) relDigitTrueHit.consolidate(from, to, RelationArray::c_deleteElement);
167}
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
Module()
Constructor.
Definition Module.cc:30
@ 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:88
unsigned short getUCellID() const
Get cell ID in u.
Definition PXDDigit.h:83
unsigned short getCharge() const
Get collected charge.
Definition PXDDigit.h:93
VxdID getSensorID() const
Get the sensor ID.
Definition PXDDigit.h:78
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 occurrence.
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.
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:74
Struct to replace indices based on a sequential container.
Low-level class to create/modify relations between StoreArrays.
void consolidate()
Consolidate Relation Elements.
@ c_deleteElement
Delete the whole relation element if the original element got re-attributed.
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 facilitate easy access to sensor information of the VXD like coordinate transformations or p...
Definition GeoCache.h:38
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:32
baseType getID() const
Get the unique id.
Definition VxdID.h:93
baseType getSensorNumber() const
Get the sensor id.
Definition VxdID.h:99
baseType getLadderNumber() const
Get the ladder id.
Definition VxdID.h:97
baseType getLayerNumber() const
Get the layer id.
Definition VxdID.h:95
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:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
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.