9#include <framework/logging/Logger.h>
10#include <svd/reconstruction/SimpleClusterCandidate.h>
11#include <vxd/geometry/GeoCache.h>
12#include <svd/geometry/SensorInfo.h>
13#include <framework/core/Environment.h>
15#include <framework/datastore/StoreArray.h>
16#include <svd/dataobjects/SVDRecoDigit.h>
31 double cutCluster,
int timeAlgorithm)
34 , m_sizeHeadTail(sizeHeadTail)
36 , m_cutAdjacent(cutAdjacent)
37 , m_cutCluster(cutCluster)
38 , m_timeAlgorithm(timeAlgorithm)
43 , m_6SampleTimeError(0)
50 , m_storeShaperDigitsName(
"SVDShaperDigits")
51 , m_storeRecoDigitsName(
"SVDRecoDigits")
55 double cutCluster,
int timeAlgorithm,
const std::string& storeShaperDigitsName,
const std::string& storeRecoDigitsName)
58 , m_sizeHeadTail(sizeHeadTail)
60 , m_cutAdjacent(cutAdjacent)
61 , m_cutCluster(cutCluster)
62 , m_timeAlgorithm(timeAlgorithm)
67 , m_6SampleTimeError(0)
74 , m_storeShaperDigitsName(storeShaperDigitsName)
75 , m_storeRecoDigitsName(storeRecoDigitsName)
118 double pitch =
m_isUside ? info.getUPitch() : info.getVPitch();
122 int minStripCellID =
m_strips.at(0).cellID;
123 double minStripCharge =
m_strips.at(0).charge;
127 double weightSum = 0;
130 double stripPos =
m_isUside ? info.getUCellPosition(aStrip.cellID) : info.getVCellPosition(aStrip.cellID);
135 float tmp_sigmaSquared = aStrip.timeError * aStrip.timeError;
136 weightSum += tmp_sigmaSquared;
141 noise += aStrip.noise * aStrip.noise;
144 if ((
m_charge == 0) || (noise == 0)) {
159 if (clusterSize == 1) {
177 double centreCharge = (
m_charge - minStripCharge - maxStripCharge) / (clusterSize - 2);
178 if (centreCharge == 0) {
183 minStripCharge = (minStripCharge < centreCharge) ? minStripCharge : centreCharge;
184 maxStripCharge = (maxStripCharge < centreCharge) ? maxStripCharge : centreCharge;
185 double minPos =
m_isUside ? info.getUCellPosition(minStripCellID) : info.getVCellPosition(minStripCellID);
186 double maxPos =
m_isUside ? info.getUCellPosition(maxStripCellID) : info.getVCellPosition(maxStripCellID);
187 m_position = 0.5 * (minPos + maxPos + (maxStripCharge - minStripCharge) / centreCharge * pitch);
191 double landauHead = minStripCharge / centreCharge;
192 double landauTail = maxStripCharge / centreCharge;
194 0.5 * landauHead * landauHead +
195 0.5 * landauTail * landauTail);
217 B2WARNING(
"Something is wrong in the cluster creation, this cluster will not be created!");
238 B2FATAL(
"unrecognized timeAlgorithm, please check the input parameter and select a value among {0 (6-sample CoG), 1 (3-sample CoG), 2 (3-sample ELS)} to select the algorithm that you want to reconstruct the cluster time");
253 B2FATAL(
"unrecognized timeAlgorithm, please check the input parameter and select a value among {0 (6-sample CoG), 1 (3-sample CoG), 2 (3-sample ELS)} to select the algorithm that you want to reconstruct the cluster time");
263 auto begin = clustered3s.begin();
264 const auto end = clustered3s.end();
267 constexpr auto stepSize = 16000. / 509;
268 auto retval = 0., norm = 0.;
269 for (
auto step = 0.; begin != end; ++begin, step += stepSize) {
270 norm +=
static_cast<double>(*begin);
271 retval +=
static_cast<double>(*begin) * step;
273 float rawtime = retval / norm;
283 const auto begin = clustered3s.begin();
286 constexpr auto stepSize = 16000. / 509;
287 constexpr auto tau = 55;
288 auto num = 2 * stepSize * std::exp(-4 * stepSize / tau) + std::exp(-2 * stepSize / tau) * stepSize / 2 * (*begin - std::exp(
289 -2 * stepSize / tau) * (*(begin + 2))) / (*begin + std::exp(-stepSize / tau) * (*(begin + 1)) / 2);
290 auto denom = 1 - std::exp(-4 * stepSize / tau) - (1 + std::exp(-2 * stepSize / tau) / 2) * (*begin - std::exp(
291 -2 * stepSize / tau) * (*(begin + 2))) / (*begin + std::exp(-stepSize / tau) * (*(begin + 1)) / 2);
292 float rawtime = - num / denom;
316 B2ERROR(
" you are asking fo the cluster samples for a cluster candidate with no strips, it make no sense to ask for the cluster time!");
332 if (!shaperdigit) B2ERROR(
"No shaperdigit for strip!?");
334 for (
int iSample = 0; iSample < static_cast<int>(APVsamples.size()); ++iSample)
335 returnSamples.at(iSample) += APVsamples.at(iSample);
338 return returnSamples;
348 if (clsSamples.size() < 3) B2ERROR(
"APV25 samples less than 3!?");
349 std::vector<float> Sum2bin(clsSamples.size() - 1, 0);
350 for (
int iBin = 0; iBin < static_cast<int>(clsSamples.size()) - 1; ++iBin)
351 Sum2bin.at(iBin) = clsSamples.at(iBin) + clsSamples.at(iBin + 1);
352 auto itSum = std::max_element(std::begin(Sum2bin), std::end(Sum2bin));
353 int ctrFrame = std::distance(std::begin(Sum2bin), itSum);
354 if (ctrFrame == 0) ctrFrame = 1;
355 std::vector<float> clustered3s = {clsSamples.at(ctrFrame - 1), clsSamples.at(ctrFrame), clsSamples.at(ctrFrame + 1)};
357 return std::make_pair(ctrFrame - 1, clustered3s);
bool isMC() const
Do we have generated, not real data?
static Environment & Instance()
Static method to get a reference to the Environment instance.
The SVD ShaperDigit class.
std::array< APVFloatSampleType, c_nAPVSamples > APVFloatSamples
array of APVFloatSampleType objects
APVFloatSamples getSamples() const
Get array of samples.
Specific implementation of SensorInfo for SVD Sensors which provides additional sensor specific infor...
const ROOT::Math::XYZVector & getLorentzShift(double uCoord, double vCoord) const
Calculate Lorentz shift along a given coordinate in a magnetic field at a given position.
std::string m_storeRecoDigitsName
Name of the collection to use for the SVDRecoDigits.
float m_position
Position of the cluster.
float m_6SampleTimeError
Error on Time of the cluster computed with the 6-sample CoG (not implemented yet)
float getTime() const
return the time of the cluster depending on the m_timeAlgorithm
float get3SampleELSRawTime() const
return the raw time of the cluster for the 3-sample ELS
bool m_stopCreationCluster
cluster is not good if something goes wrong
std::string m_storeShaperDigitsName
Name of the collection to use for the SVDShaperDigits.
double m_cutCluster
SNR above which the cluster is ok.
std::vector< stripInCluster > m_strips
first frame selected with the max-sum algorithm
float get6SampleCoGTime() const
return the time of the cluster for the 6-sample CoG
Belle2::SVDShaperDigit::APVFloatSamples getClsSamples() const
returns the APVFloatSamples obtained summing sample-by-sample all the strips on the cluster
float m_SNR
SNR of the cluster.
bool add(VxdID vxdID, bool isUside, struct stripInCluster &aStrip)
Add a Strip to the current cluster.
float m_charge
Charge of the cluster.
void finalizeCluster()
compute the position, time and their error of the cluster
float m_6SampleTime
Time of the cluster computed with the 6-sample CoG.
bool isGoodCluster()
return true if the cluster candidate can be promoted to cluster
float get3SampleCoGTimeError() const
return the time of the cluster for the 3-sample CoG
bool m_isUside
side of the cluster
float m_positionError
Error on Position of the cluster.
VxdID m_vxdID
VxdID of the cluster.
float get3SampleCoGRawTime() const
return the raw time of the cluster for the 3-sample CoG
float m_seedSNR
SNR of the seed strip.
float get6SampleCoGTimeError() const
return the time of the cluster for the 6-sample CoG
std::pair< int, std::vector< float > > getMaxSum3Samples() const
returns the float vector of clustered 3-samples selected by the MaxSum method with First Frame of the...
int m_sizeHeadTail
number of strips after which we switch from COG to HeadTail estimation of the position
int m_timeAlgorithm
selects the algorithm to compute the cluster tim 0 = 6-sample CoG (default) 1 = 3-sample CoG 2 = 3-sa...
double m_cutSeed
SNR above which the strip can be considered as seed.
float get3SampleELSTimeError() const
return the time of the cluster for the 3-sample ELS
SimpleClusterCandidate(VxdID vxdID, bool isUside, int sizeHeadTail, double cutSeed, double cutAdjacent, double cutSNR, int timeAlgorithm)
Constructor to create an empty Cluster.
float m_seedCharge
Seed Charge of the cluster.
float getTimeError() const
return the error on the time of the cluster depending on the m_timeAlgorithm, implemented only for th...
int m_seedIndex
SVDRecoDigit index of the seed strip of the cluster.
double m_cutAdjacent
SNR above which the strip can be considered for clustering.
Accessor to arrays stored in the data store.
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.
static GeoCache & getInstance()
Return a reference to the singleton instance.
Base class to provide Sensor Information for PXD and SVD.
Class to uniquely identify a any structure of the PXD and SVD.
baseType getLayerNumber() const
Get the layer id.
double sqrt(double a)
sqrt for double
Abstract base class for different kinds of events.
structure containing the relevant informations of eachstrip of the cluster