9#include <pxd/modules/pxdReconstruction/PXDClusterizerModule.h>
10#include <pxd/dbobjects/PXDClusterPositionErrorPar.h>
11#include <pxd/reconstruction/ClusterCache.h>
12#include <pxd/reconstruction/ClusterProjection.h>
14#include <framework/datastore/StoreArray.h>
15#include <framework/datastore/RelationArray.h>
16#include <framework/logging/Logger.h>
18#include <vxd/dataobjects/VxdID.h>
19#include <vxd/geometry/GeoCache.h>
21#include <mdst/dataobjects/MCParticle.h>
22#include <mdst/dataobjects/EventLevelTrackingInfo.h>
23#include <pxd/dataobjects/PXDDigit.h>
24#include <pxd/dataobjects/PXDCluster.h>
25#include <pxd/dataobjects/PXDTrueHit.h>
26#include <pxd/geometry/SensorInfo.h>
28#include <pxd/reconstruction/PXDClusterPositionEstimator.h>
30#include <pxd/utilities/PXDUtilities.h>
54 "Noise added by the electronics, set in ADU",
m_elNoise);
56 "SN for digits to be considered for clustering",
m_cutAdjacent);
61 "Maximum desired number of sensor rows", 0);
63 "Minimum cluster size to switch to Analog head tail algorithm for cluster center",
74 string(
"PXDClusterPositionErrorUPar"));
76 string(
"PXDClusterPositionErrorVPar"));
78 "Create PXDClusters for events where either the SVDSpacePointCreator abort flag or the VXDTF2 and SVDCKF abort flags are set.",
97 RelationArray relClusterTrueHits(storeClusters, storeTrueHits);
98 RelationArray relClusterMCParticles(storeClusters, storeMCParticles);
99 RelationArray relDigitMCParticles(storeDigits, storeMCParticles);
125 "PXDClusterizer Parameters (in default system units, *=cannot be set directly):");
126 B2DEBUG(20,
" --> ElectronicNoise: " <<
m_elNoise);
128 B2DEBUG(20,
" --> SeedSN: " <<
m_cutSeed);
155 B2WARNING(
"You chose to use cluster position errors from DB but did not provide PositionErrorUPayloadName ("
157 <<
"). Disabling DB option.");
163 B2FATAL(
"DB objects for ClusterPositionError not valid");
175 B2FATAL(
"DB objects for ClusterPositionError not valid for this run");
197 storeClusters.
clear();
199 RelationArray relClusterMCParticle(storeClusters, storeMCParticles,
201 if (relClusterMCParticle) relClusterMCParticle.
clear();
205 if (relClusterDigit) relClusterDigit.
clear();
207 RelationArray relClusterTrueHit(storeClusters, storeTrueHits,
209 if (relClusterTrueHit) relClusterTrueHit.
clear();
228 for (
int i = 0; i < nPixels; i++) {
229 const PXDDigit*
const storeDigit = storeDigits[i];
230 Pixel px(storeDigit, i);
237 }
else if (px <= lastPixel) {
239 B2FATAL(
"Pixels are not sorted correctly, please include the "
240 "PXDDigitSorter module before running the Clusterizer or fix "
241 "the input to be ordered by v,u in ascending order");
269 }
catch (std::out_of_range& e) {
270 B2WARNING(
"PXD clustering: Ignoring pixel " << px.
getU() <<
"," << px.
getV() <<
": " << e.what());
280 if (!relation)
return;
282 lookup.resize(digits);
284 lookup[element.getFromIndex()] = &element;
292 if (!lookup.empty() && lookup[index]) {
294 const unsigned int size = element.getSize();
296 for (
unsigned int i = 0; i < size; ++i) {
299 if (element.getWeight(i) < 0)
continue;
300 relation[element.getToIndex(i)] += element.getWeight(i);
315 RelationArray relClusterMCParticle(storeClusters, storeMCParticles,
319 RelationArray relClusterTrueHit(storeClusters, storeTrueHits,
326 map<unsigned int, float> mc_relations;
327 map<unsigned int, float> truehit_relations;
328 vector<pair<unsigned int, float> > digit_weights;
337 mc_relations.clear();
338 truehit_relations.clear();
339 digit_weights.clear();
340 digit_weights.reserve(cls.size());
342 const Pixel& seed = cls.getSeed();
346 projU.
add(px.getU(), info.getUCellPosition(px.getU()), px.getCharge());
347 projV.
add(px.getV(), info.getVCellPosition(px.getV()), px.getCharge());
354 digit_weights.emplace_back(px.getIndex(), px.getCharge());
359 const double pitchU = info.getUPitch();
360 const double pitchV = info.getVPitch(projV.
getPos());
364 double posUU = cls.getCharge() * pitchU * pitchU / 12.0;
365 double posVV = cls.getCharge() * pitchV * pitchV / 12.0;
367 for (
const Pixel& px : cls.pixels()) {
368 const double du = info.getUCellPosition(px.getU()) - projU.
getPos();
369 const double dv = info.getVCellPosition(px.getV()) - projV.
getPos();
370 posUU += px.getCharge() * du * du;
371 posVV += px.getCharge() * dv * dv;
372 posUV += px.getCharge() * du * dv;
374 rho = posUV /
sqrt(posUU * posVV);
383 unsigned int uID = info.getUCellID(projU.
getPos());
384 unsigned int vID = info.getVCellID(projV.
getPos());
392 ROOT::Math::XYZVector lorentzShift = info.getLorentzShift(projU.
getPos(), projV.
getPos());
395 B2DEBUG(20,
"Lorentz shift: " << lorentzShift.X() <<
" " << lorentzShift.Y());
402 set<Pixel> pixelSet(cls.pixels().begin(), cls.pixels().end());
405 vector<float> sectorEtaValues = {0, 0, 0, 0};
415 vector<int> sectorShapeIndices = { -1, -1, -1, -1};
428 rho, cls.getCharge(), seed.getCharge(),
430 sectorEtaValues, sectorShapeIndices
434 if (!mc_relations.empty()) relClusterMCParticle.
add(clsIndex, mc_relations.begin(), mc_relations.end());
435 if (!truehit_relations.empty()) relClusterTrueHit.
add(clsIndex, truehit_relations.begin(), truehit_relations.end());
436 relClusterDigit.
add(clsIndex, digit_weights.begin(), digit_weights.end());
443 const ClusterProjection& secondary,
double minPitch,
double centerPitch,
double maxPitch)
451 + (maxCharge * maxPitch - minCharge * minPitch) / centerCharge));
454 const double landauHead = minCharge / centerCharge * minPitch;
455 const double landauTail = maxCharge / centerCharge * maxPitch;
456 primary.
setError(0.5 *
sqrt(1.0 / snHead / snHead + 1.0 / snTail / snTail
457 + 0.5 * landauHead * landauHead + 0.5 * landauTail * landauTail));
458 }
else if (primary.
getSize() <= 2) {
463 primary.
setError(2.0 * centerPitch / sn);
468 VxdID sensorID,
unsigned int uCell,
unsigned int vCell,
double centerPitch,
469 bool isAtUEdge,
bool isAtVEdge,
bool isAdjacentDead)
482 if (error) primary.
setError(sf * error * centerPitch);
@ c_ErrorIfAlreadyRegistered
If the object/array was already registered, produce an error (aborting initialisation).
static std::string arrayName(const TClass *t, const std::string &name)
Return the storage name for an object of the given TClass and name.
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
The payload class for PXD cluster position error.
float getContent(unsigned short sensorID, unsigned short globalID) const
Get content.
unsigned short getBinsV() const
Get number of bins along sensor v side.
float getDeadNeighbourFactor(unsigned short sensorID, unsigned short globalID) const
Get scaling factor when neighbouring dead rows/column.
unsigned short getBinsU() const
Get number of bins along sensor u side.
float getSensorVEdgeFactor(unsigned short sensorID, unsigned short globalID) const
Get scaling factor at sensor edge in V.
float getSensorUEdgeFactor(unsigned short sensorID, unsigned short globalID) const
Get scaling factor at sensor edge in U.
VxdID getSensorID() const
Get the sensor ID.
Class to remember recently assigned clusters This class will remember the current and the last pixel ...
Class representing a possible cluster during clustering of the PXD It supports merging of different c...
float getSeedCharge() const
get the seed charge of the cluster
Helper struct to collect information about the 1D projection of a Pixel cluster.
double getMinPos() const
Return the position of the minimum cell of the cluster.
void add(unsigned int cell, float position, float charge)
Add Pixel information to the projection.
double getMaxCharge() const
Return the charge in the maximum cell of the cluster.
void finalize()
Finish calculation of center of gravity and set correct cluster size.
unsigned int getMinCell() const
Return the minimum cell part of the cluster.
double getCharge() const
Return the total charge of the cluster.
unsigned int getMaxCell() const
Return the maximum cell part of the cluster.
void setPos(double pos)
Set the position of the cluster.
double getMinCharge() const
Return the charge in the minimum cell of the cluster.
void setError(double error)
Set the error of the cluster.
double getError() const
Return the error of the cluster.
double getMaxPos() const
Return the position of the maximum cell of the cluster.
double getPos() const
Return the projected position of the cluster.
double getCenterCharge() const
Return the center charge of the cluster, that is total charge minus minimum and maximum cell charge.
unsigned int getSize() const
Return the projected size of the cluster.
static PXDClusterPositionEstimator & getInstance()
Main (and only) way to access the PXDClusterPositionEstimator.
float computeEta(const std::set< Pixel > &pixels, int vStart, int vSize, double thetaU, double thetaV) const
Return the normed charge ratio between head and tail pixels (size>=2) or the charge of the seed (size...
int computeShapeIndex(const std::set< Pixel > &pixels, int uStart, int vStart, int vSize, double thetaU, double thetaV) const
Return the shape index of the pixels.
int getClusterkind(const PXDCluster &cluster) const
Return kind of cluster needed to find cluster position correction.
NoiseMap m_noiseMap
Noise map for the currently active sensor.
int m_clusterCacheSize
Size of cluster Cache (0 = default)
std::unique_ptr< DBObjPtr< PXDClusterPositionErrorPar > > m_clusterPositionErrorVPar
DB object for cluster position errors in V.
double m_cutAdjacentSignal
Signal in ADU for Adjacent cut, basically m_elNoise*m_cutAdjacent.
virtual void initialize() override
Initialize the module.
std::string m_positionErrorVName
Name of the DB payload containing cluster position errors in V.
StoreObjPtr< EventLevelTrackingInfo > m_eventLevelTrackingInfo
StoreObject to access the event level tracking information.
std::string m_relDigitMCParticleName
Name of the relation between PXDDigits and MCParticles.
virtual void event() override
do the clustering
void calculatePositionError(const ClusterCandidate &cls, ClusterProjection &primary, const ClusterProjection &secondary, double minPitch, double centerPitch, double maxPitch)
Calculate position and error for a given cluster.
std::vector< const RelationElement * > RelationLookup
Container for a RelationArray Lookup table.
std::string m_relClusterDigitName
Name of the relation between PXDClusters and PXDDigits.
bool m_createPXDClustersForAbortedTrackingEvents
bool to override the EventLevelTrackingInfo abort flag decision
double m_cutCluster
Cluster cut in sigma.
std::string m_storeTrueHitsName
Name of the collection to use for the PXDTrueHits.
PXDClusterizerModule()
Constructor defining the parameters.
void fillRelationMap(const RelationLookup &lookup, std::map< unsigned int, float > &relation, unsigned int index)
Add the relation from a given PXDDigit index to a map.
std::string m_storeMCParticlesName
Name of the collection to use for the MCParticles.
RelationLookup m_trueRelation
Lookup table for PXDDigit->PXDTrueHit relation.
std::string m_positionErrorUName
Name of the DB payload containing cluster position errors in U.
virtual void beginRun() override
do at every run change
std::unique_ptr< DBObjPtr< PXDClusterPositionErrorPar > > m_clusterPositionErrorUPar
DB object for cluster position errors in U.
void assignPositionErrorFromDB(ClusterProjection &primary, PXDClusterPositionErrorPar errorPar, VxdID sensorID, unsigned int uCell, unsigned int vCell, double centerPitch, bool isAtUEdge=false, bool isAtVEdge=false, bool isAdjacentDead=false)
Assign position error for a given cluster from DB.
int m_sizeHeadTail
Size of the cluster at which we switch from Center of Gravity to Analog Head Tail.
double m_elNoise
Noise in ADU.
std::string m_storeDigitsName
Name of the collection to use for the PXDDigits.
void createRelationLookup(const RelationArray &relation, RelationLookup &lookup, size_t digits)
Create lookup maps for Relations We do not use the RelationIndex as we know much more about the relat...
std::string m_storeClustersName
Name of the collection to use for the PXDClusters.
void writeClusters(VxdID sensorID)
Write clusters to collection.
double m_cutSeed
Seed cut in sigma.
std::string m_relDigitTrueHitName
Name of the relation between PXDDigits and PXDTrueHits.
std::string m_relClusterMCParticleName
Name of the relation between PXDClusters and MCParticles.
RelationLookup m_mcRelation
Lookup table for PXDDigit->MCParticle relation.
std::unique_ptr< ClusterCache > m_cache
cache of the last seen clusters to speed up clustering
bool m_errorFromDB
Flag to set cluster position error from DB (default = true)
double m_cutAdjacent
Noise cut in sigma.
std::string m_relClusterTrueHitName
Name of the relation between PXDClusters and PXDTrueHits.
Class to represent one pixel, used in clustering for fast access.
unsigned short getU() const
Return the CellID in u.
unsigned short getV() const
Return the CellID in v.
Specific implementation of SensorInfo for PXD Sensors which provides additional pixel specific inform...
Low-level class to create/modify relations between StoreArrays.
void add(index_type from, index_type to, weight_type weight=1.0)
Add a new element to the relation.
void clear() override
Clear all elements from the relation.
Class to store a single element of a relation.
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.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
Accessor to arrays stored in the data store.
T * appendNew()
Construct a new T object at the end of the array.
int getEntries() const
Get the number of objects in the array.
void clear() override
Delete all entries in this array.
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a reference to the SensorInfo of a given SensorID.
static GeoCache & getInstance()
Return a reference to the singleton instance.
Class to uniquely identify a any structure of the PXD and SVD.
baseType getID() const
Get the unique id.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
double sqrt(double a)
sqrt for double
Namespace to encapsulate code needed for simulation and reconstrucion of the PXD.
unsigned short getBinU(VxdID id, unsigned int uid, unsigned int vid, unsigned short nBinsU)
Function to return a bin number for equal sized binning in U.
bool isClusterAtUEdge(VxdID id, unsigned int umin, unsigned int umax)
Helper function to check if one of the end pixels are at the edge of the sensor.
bool isClusterAtVEdge(VxdID id, unsigned int vmin, unsigned int vmax)
Helper function to check if one of the end pixels are at the edge of the sensor.
bool isClusterAtLadderJoint(VxdID id, unsigned int vmin, unsigned int vmax)
Helper function to check if one of the end pixels are at the ladder joint.
unsigned short getBinV(VxdID id, unsigned int vid, unsigned short nBinsV)
Function to return a bin number for equal sized binning in V.
Abstract base class for different kinds of events.