9 #include <framework/logging/Logger.h>
10 #include <svd/reconstruction/SVDClusterPosition.h>
11 #include <svd/reconstruction/SVDCoG3Time.h>
12 #include <svd/reconstruction/SVDELS3Time.h>
13 #include <svd/reconstruction/SVDELS3Charge.h>
14 #include <svd/reconstruction/SVDMaxSampleCharge.h>
15 #include <svd/reconstruction/SVDSumSamplesCharge.h>
16 #include <svd/reconstruction/SVDMaxSumAlgorithm.h>
17 #include <vxd/geometry/GeoCache.h>
18 #include <svd/geometry/SensorInfo.h>
21 #include <Eigen/Dense>
34 void SVDClusterPosition::applyCoGPosition(
const Belle2::SVD::RawCluster& rawCluster,
double& position,
double& positionError)
46 for (
auto aStrip : strips) {
48 double stripPos = rawCluster.
isUSide() ? info.getUCellPosition(aStrip.cellID) : info.getVCellPosition(aStrip.cellID);
51 double stripCharge = aStrip.charge;
53 position += stripPos * stripCharge;
54 charge += stripCharge;
61 double pitch = rawCluster.
isUSide() ? info.getUPitch() : info.getVPitch();
62 double sumStripCharge = getSumOfStripCharges(rawCluster);
64 positionError = m_CoGOnlyErr.getPositionError(rawCluster.
getSensorID(), rawCluster.
isUSide(), 0,
65 sumStripCharge / getClusterNoise(rawCluster), rawCluster.
getSize(), pitch);
71 void SVDClusterPosition::applyAHTPosition(
const Belle2::SVD::RawCluster& rawCluster,
double& position,
double& positionError)
79 double pitch = rawCluster.
isUSide() ? info.getUPitch() : info.getVPitch();
85 int headStripCellID = strips.at(strips.size() - 1).cellID;
86 double headStripCharge = strips.at(strips.size() - 1).charge;
88 int tailStripCellID = strips.at(0).cellID;
89 double tailStripCharge = strips.at(0).charge;
93 double centreCharge = (getSumOfStripCharges(rawCluster) - tailStripCharge - headStripCharge) / (strips.size() - 2);
95 tailStripCharge = (tailStripCharge < centreCharge) ? tailStripCharge : centreCharge;
96 headStripCharge = (headStripCharge < centreCharge) ? headStripCharge : centreCharge;
97 double tailPos = rawCluster.
isUSide() ? info.getUCellPosition(tailStripCellID) : info.getVCellPosition(tailStripCellID);
98 double headPos = rawCluster.
isUSide() ? info.getUCellPosition(headStripCellID) : info.getVCellPosition(headStripCellID);
99 position = 0.5 * (tailPos + headPos + (headStripCharge - tailStripCharge) / centreCharge * pitch);
102 double cutAdjacent = m_ClusterCal.getMinAdjSNR(rawCluster.
getSensorID(), rawCluster.
isUSide());
103 double sn = centreCharge / cutAdjacent / getClusterNoise(rawCluster);
106 double landauHead = tailStripCharge / centreCharge;
107 double landauTail = headStripCharge / centreCharge;
108 positionError = 0.5 * pitch *
sqrt(1.0 / sn / sn +
109 0.5 * landauHead * landauHead +
110 0.5 * landauTail * landauTail);
117 double sumStripCharge = 0;
123 for (
auto aStrip : strips) {
125 double stripCharge = aStrip.charge;
126 sumStripCharge += stripCharge;
128 return sumStripCharge;
134 double clusterNoise = 0;
140 for (
auto aStrip : strips) {
142 float averageNoiseInElectrons = m_NoiseCal.getNoiseInElectrons(rawCluster.
getSensorID(), rawCluster.
isUSide(), aStrip.cellID);
143 clusterNoise += averageNoiseInElectrons * averageNoiseInElectrons;
145 return sqrt(clusterNoise);
151 double averageNoise = 0;
157 for (
auto aStrip : strips) {
159 float averageNoiseInElectrons = m_NoiseCal.getNoiseInElectrons(rawCluster.
getSensorID(), rawCluster.
isUSide(), aStrip.cellID);
160 averageNoise += averageNoiseInElectrons;
162 return averageNoise / strips.size();
172 for (
int i = 0; i < (int)strips.size(); i++) {
180 if (m_stripTimeAlgo.compare(
"dontdo") != 0) {
183 double timeError = 0;
186 if (m_stripTimeAlgo ==
"ELS3") {
190 }
else if (m_stripTimeAlgo ==
"CoG3") {
200 if (m_stripChargeAlgo.compare(
"dontdo") != 0) {
205 if (m_stripChargeAlgo ==
"ELS3") {
211 cc.computeClusterCharge(tmp, charge, SNR, seedCharge);
213 double maxSample_charge = 0;
217 if ((abs(charge - maxSample_charge) / maxSample_charge > 0.3) || charge < 0)
222 }
else if (m_stripChargeAlgo ==
"SumSamples") {
224 cc.computeClusterCharge(tmp, charge, SNR, seedCharge);
229 cc.computeClusterCharge(tmp, charge, SNR, seedCharge);
234 B2ERROR(
"this should not happen...");
245 double unfoldingCoefficient = m_ClusterCal.getUnfoldingCoeff(rawCluster.
getSensorID(), rawCluster.
isUSide());
246 unsigned int Size = strips.size();
247 double threshold = 0;
248 Eigen::VectorXd Charges(Size);
249 Eigen::MatrixXd Couplings(Size, Size);
251 for (
unsigned int i = 0; i < Size; ++i) {
252 for (
unsigned int j = 0; j < Size; ++j) {
253 if (i == j) {Couplings(i, j) = 1 - 2 * unfoldingCoefficient;}
254 else if (j == i + 1) {Couplings(i, j) = unfoldingCoefficient;}
255 else if (j == i - 1) {Couplings(i, j) = unfoldingCoefficient;}
256 else {Couplings(i, j) = 0;}
264 Charges(i) = strip.
charge;
269 Charges = Couplings.inverse() * Charges;
270 for (
unsigned i = 0; i < Size; i++) {
271 if (Charges(i) < threshold) {Charges(i) = 0;}
Class representing a raw cluster candidate during clustering of the SVD.
void setStripCharge(int index, double charge)
set the strip charge
VxdID getSensorID() const
const std::vector< StripInRawCluster > getStripsInRawCluster() const
void setStripTime(int index, double time)
set the strip time
Derived Class representing the SVD cluster time computed with the CoG3 algorithm.
void computeClusterTime(Belle2::SVD::RawCluster &rawCluster, double &time, double &timeError, int &firstFrame) override
computes the cluster time, timeError and FirstFrame with the CoG3 algorithm
Derived Class representing the SVD cluster charge computed with the ELS3 algorithm.
Derived Class representing the SVD cluster time computed with the ELS3 algorithm.
void computeClusterTime(Belle2::SVD::RawCluster &rawCluster, double &time, double &timeError, int &firstFrame) override
computes the cluster time, timeError and FirstFrame with the ELS3 algorithm
Derived Class representing the SVD cluster charge computed summing the max sample of each strip.
void computeClusterCharge(Belle2::SVD::RawCluster &rawCluster, double &charge, double &SNR, double &seedCharge) override
compute the cluster charge, charge error and SNR with MaxSample
Derived Class representing the SVD cluster charge computed summing the samples of each strip.
Class to faciliate easy access to sensor information of the VXD like coordinate transformations or pi...
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a referecne to the SensorInfo of a given SensorID.
Base class to provide Sensor Information for PXD and SVD.
double sqrt(double a)
sqrt for double
Abstract base class for different kinds of events.
structure containing the relevant informations of each strip of the raw cluster
double charge
strip charge