13#include <svd/calibration/SVDHitTimeSelection.h>
14#include <svd/calibration/SVDNoiseCalibrations.h>
15#include <svd/dataobjects/SVDCluster.h>
16#include <svd/dataobjects/SVDShaperDigit.h>
17#include <svd/dbobjects/SVDSpacePointSNRFractionSelector.h>
18#include <svd/reconstruction/SVDMaxSumAlgorithm.h>
20#include <framework/datastore/StoreArray.h>
21#include <framework/datastore/StoreObjPtr.h>
22#include <framework/database/DBObjPtr.h>
23#include <framework/utilities/MathHelpers.h>
24#include <mdst/dataobjects/EventLevelTrackingInfo.h>
26#include <vxd/dataobjects/VxdID.h>
28#include <unordered_map>
82 for (
unsigned int i = 0; i < uint(svdClusters.
getEntries()); ++i) {
83 const SVDCluster* currentCluster = svdClusters[i];
84 std::vector<const SVDCluster*> currentClusterCombi = { currentCluster };
85 SpacePointType* newSP = spacePoints.
appendNew(currentClusterCombi);
86 newSP->addRelationTo(currentCluster);
94 std::vector<float>& inputVector,
98 inputVector.resize(3, 0.0);
102 for (
auto iSD : shaperDigits) {
103 auto samples = iSD.getSamples();
104 std::vector<float> selectedSamples;
105 if (samples.size() == 6) {
108 selectedSamples.assign(maxSamples.begin(), maxSamples.end());
110 selectedSamples.assign(samples.begin(), samples.end());
112 if (selectedSamples.size() < 3)
continue;
114 inputVector[0] += selectedSamples[0];
115 inputVector[1] += selectedSamples[1];
116 inputVector[2] += selectedSamples[2];
118 VxdID thisSensorID = iSD.getSensorID();
119 bool thisSide = iSD.isUStrip();
120 int thisCellID = iSD.getCellID();
121 float thisNoise = noiseCal.
getNoise(thisSensorID, thisSide, thisCellID);
122 noise += thisNoise * thisNoise;
125 inputVector[0] = inputVector[0] / noise;
126 inputVector[1] = inputVector[1] / noise;
127 inputVector[2] = inputVector[2] / noise;
139 std::vector< std::vector<const SVDCluster*> >& foundCombinations,
const SVDHitTimeSelection& hitTimeCut,
140 const bool& useSVDGroupInfo,
const int& numberOfSignalGroups,
const bool& formSingleSignalGroup,
142 bool useSVDSpacePointSNRFractionSelector)
147 B2DEBUG(29,
"Cluster rejected due to timing cut. Cluster time: " << uCluster->
getClsTime());
152 B2DEBUG(29,
"Cluster rejected due to timing cut. Cluster time: " << vCluster->
getClsTime());
157 B2DEBUG(29,
"Cluster combination rejected due to timing cut. Cluster time U (" << uCluster->
getClsTime() <<
158 ") is incompatible with Cluster time V (" << vCluster->
getClsTime() <<
")");
162 if (useSVDGroupInfo) {
163 const std::vector<int>& uTimeGroupId = uCluster->
getTimeGroupId();
164 const std::vector<int>& vTimeGroupId = vCluster->
getTimeGroupId();
166 if (
int(uTimeGroupId.size()) &&
int(vTimeGroupId.size())) {
167 bool isContinue =
true;
168 for (
auto& uitem : uTimeGroupId) {
169 if (uitem < 0 || uitem >= numberOfSignalGroups)
continue;
170 for (
auto& vitem : vTimeGroupId) {
171 if (vitem < 0 || vitem >= numberOfSignalGroups)
continue;
172 if ((uitem == vitem) || formSingleSignalGroup) { isContinue =
false;
break; }
174 if (!isContinue)
break;
178 B2DEBUG(29,
"Cluster combination rejected due to different time-group Id.");
184 if (useSVDSpacePointSNRFractionSelector) {
185 std::vector<float> inputU;
186 std::vector<float> inputV;
191 bool pass = svdSpacePointSelectionFunction->passSNRFractionSelection(inputU, inputV);
193 B2DEBUG(29,
"Cluster combination rejected due to SVDSpacePointSNRFractionSelector");
198 foundCombinations.push_back({uCluster, vCluster});
214 inline void spPDFName(
const VxdID& sensor,
int uSize,
int vSize,
int maxClusterSize, std::string& PDFName,
215 std::string& errorPDFName,
bool useLegacyNaming)
217 if (useLegacyNaming ==
true) {
219 if (uSize > maxClusterSize) uSize = maxClusterSize;
220 if (vSize > maxClusterSize) vSize = maxClusterSize;
222 std::string sensorName;
224 if (sensor.getLayerNumber() == 3) sensorName =
"l3";
225 if (sensor.getLayerNumber() > 3 && sensor.getSensorNumber() == 1) sensorName =
"trap";
226 if (sensor.getLayerNumber() > 3 && sensor.getSensorNumber() > 1) sensorName =
"large";
228 PDFName = sensorName + std::to_string(uSize) + std::to_string(vSize);
229 errorPDFName =
"error" + PDFName;
232 if (uSize > maxClusterSize) uSize = maxClusterSize;
233 if (vSize > maxClusterSize) vSize = maxClusterSize;
235 int layer = sensor.getLayerNumber();
236 int ladder = sensor.getLadderNumber();
237 int sens = sensor.getSensorNumber();
239 PDFName = std::to_string(layer) +
"." + std::to_string(ladder) +
"." + std::to_string(sens) +
"." + std::to_string(
240 uSize) +
"." + std::to_string(vSize);
241 errorPDFName = PDFName +
"_Error";
256 inline void calculatePairingProb(TFile* pdfFile, std::vector<const SVDCluster*>& clusters,
double& prob,
double& error,
257 bool useLegacyNaming)
261 int pdfEntries = pdfFile->GetListOfKeys()->GetSize();
262 if (useLegacyNaming ==
true) {
263 maxSize = floor(
sqrt((pdfEntries - 4) / 6));
265 maxSize = floor(
sqrt((pdfEntries - 4) / 344));
267 std::string chargeProbInput;
268 std::string chargeErrorInput;
270 spPDFName(clusters[0]->getSensorID(), clusters[0]->getSize(), clusters[1]->getSize(), maxSize,
271 chargeProbInput, chargeErrorInput, useLegacyNaming);
272 std::string timeProbInput =
"timeProb";
273 std::string timeErrorInput =
"timeError";
274 std::string sizeProbInput =
"sizeProb";
275 std::string sizeErrorInput =
"sizeError";
278 TH2F* chargePDF =
nullptr;
279 TH2F* chargeError =
nullptr;
280 TH2F* timePDF =
nullptr;
281 TH2F* timeError =
nullptr;
282 TH2F* sizePDF =
nullptr;
283 TH2F* sizeError =
nullptr;
285 pdfFile->GetObject(chargeProbInput.c_str(), chargePDF);
286 pdfFile->GetObject(chargeErrorInput.c_str(), chargeError);
287 pdfFile->GetObject(timeProbInput.c_str(), timePDF);
288 pdfFile->GetObject(timeErrorInput.c_str(), timeError);
289 pdfFile->GetObject(sizeProbInput.c_str(), sizePDF);
290 pdfFile->GetObject(sizeErrorInput.c_str(), sizeError);
292 int xChargeBin = chargePDF->GetXaxis()->FindFixBin(clusters[0]->getCharge());
293 int yChargeBin = chargePDF->GetYaxis()->FindFixBin(clusters[1]->getCharge());
295 int xTimeBin = timePDF->GetXaxis()->FindFixBin(clusters[0]->getClsTime());
296 int yTimeBin = timePDF->GetYaxis()->FindFixBin(clusters[1]->getClsTime());
299 int xSizeBin = sizePDF->GetXaxis()->FindFixBin(clusters[0]->getSize());
300 int ySizeBin = sizePDF->GetYaxis()->FindFixBin(clusters[1]->getSize());
302 double chargeProb = chargePDF->GetBinContent(xChargeBin, yChargeBin);
303 double timeProb = timePDF->GetBinContent(xTimeBin, yTimeBin);
304 double sizeProb = sizePDF->GetBinContent(xSizeBin, ySizeBin);
305 double chargeProbError = chargePDF->GetBinContent(xChargeBin, yChargeBin);
306 double timeProbError = timePDF->GetBinContent(xTimeBin, yTimeBin);
307 double sizeProbError = sizePDF->GetBinContent(xSizeBin, ySizeBin);
310 if (chargeProbError == 0) {
311 B2DEBUG(21,
"svdClusterProbabilityEstimator has not been run, spacePoint QI will return zero!");
314 prob = chargeProb * timeProb * sizeProb * clusters[0]->getQuality() * clusters[1]->getQuality();
315 error = prob *
sqrt(
square(timeProb * sizeProb * clusters[0]->getQuality() * clusters[1]->getQuality() * chargeProbError) +
316 square(chargeProb * sizeProb * clusters[0]->getQuality() * clusters[1]->getQuality() * timeProbError) +
317 square(chargeProb * timeProb * clusters[0]->getQuality() * clusters[1]->getQuality() * sizeProbError) +
318 square(chargeProb * timeProb * sizeProb * clusters[1]->getQuality() * clusters[0]->getQualityError()) +
319 square(chargeProb * timeProb * sizeProb * clusters[0]->getQuality() * clusters[1]->getQualityError()));
331 bool useLegacyNaming,
unsigned int numMaxSpacePoints, std::string m_eventLevelTrackingInfoName,
const bool& useSVDGroupInfo,
332 const int& numberOfSignalGroups,
const bool& formSingleSignalGroup,
334 bool useSVDSpacePointSNRFractionSelector)
336 std::unordered_map<VxdID::baseType, ClustersOnSensor>
338 std::vector<std::vector<const SVDCluster*> >
342 for (
unsigned int i = 0; i < uint(svdClusters.
getEntries()); ++i) {
345 activatedSensors[currentCluster->
getSensorID().
getID()].addCluster(currentCluster);
349 for (
auto& aSensor : activatedSensors)
351 formSingleSignalGroup,
352 noiseCal, svdSpacePointSelectionFunction, useSVDSpacePointSNRFractionSelector);
355 if (foundCombinations.size() > numMaxSpacePoints) {
357 if (m_eventLevelTrackingInfo.
isValid()) {
358 m_eventLevelTrackingInfo->setSVDSpacePointCreatorAbortionFlag();
363 for (
auto& clusterCombi : foundCombinations) {
364 SpacePointType* newSP = spacePoints.
appendNew(clusterCombi);
365 if (useQualityEstimator ==
true) {
369 newSP->setQualityEstimation(probability);
370 newSP->setQualityEstimationError(error);
372 for (
auto* cluster : clusterCombi) {
373 newSP->addRelationTo(cluster, cluster->isUCluster() ? 1. : -1.);
Class for accessing objects in the database.
RelationVector< TO > getRelationsTo(const std::string &name="", const std::string &namedRelation="") const
Get the relations that point from this object to another store array.
The SVD Cluster class This class stores all information about reconstructed SVD clusters.
float getClsTime() const
Get average of waveform maximum times of cluster strip signals.
VxdID getSensorID() const
Get the sensor ID.
bool isUCluster() const
Get the direction of strips.
const std::vector< int > & getTimeGroupId() const
Get ID of the time-group.
This class defines the dbobject and the methods to access the calibration of the cluster reconstructi...
bool isClusterInTime(const Belle2::VxdID &sensorID, const bool &isU, const double &svdTime, const double &svdTimeError=0, const double &t0=0, const double &t0Error=0) const
Return whether the cluster is estimated to be in time with the event or off-time.
bool areClusterTimesCompatible(const Belle2::VxdID &sensorID, const double &uTime, const double &vTime=0) const
Return whether the cluster is estimated to be in time with the event or off-time.
This class defines the dbobject and the method to access SVD calibrations from the noise local runs.
float getNoise(const VxdID &sensorID, const bool &isU, const unsigned short &strip) const
This is the method for getting the noise.
The SVD ShaperDigit class.
Class implementing the MaxSum algorithm.
std::vector< float > getSelectedSamples()
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.
Type-safe access to single objects in the data store.
bool isValid() const
Check whether the object was created.
Class to uniquely identify a any structure of the PXD and SVD.
baseType getID() const
Get the unique id.
constexpr T square(const T &x)
Calculate the square of the input.
double sqrt(double a)
sqrt for double
void calculatePairingProb(TFile *pdfFile, std::vector< const SVDCluster * > &clusters, double &prob, double &error, bool useLegacyNaming)
Function to extract probability of correct (pair from signal hit) cluster pairing from preconfigured ...
void provideSVDClusterSingles(const StoreArray< SVDCluster > &svdClusters, StoreArray< SpacePointType > &spacePoints)
simply store one spacePoint for each existing SVDCluster.
void storeInputVectorFromSingleCluster(const SVDCluster *cls, std::vector< float > &inputVector, const SVDNoiseCalibrations &noiseCal)
Store the input values for SVDSpacePoint selection from the given SVDCluster.
void findPossibleCombinations(const Belle2::ClustersOnSensor &aSensor, std::vector< std::vector< const SVDCluster * > > &foundCombinations, const SVDHitTimeSelection &hitTimeCut, const bool &useSVDGroupInfo, const int &numberOfSignalGroups, const bool &formSingleSignalGroup, const SVDNoiseCalibrations &noiseCal, const DBObjPtr< SVDSpacePointSNRFractionSelector > &svdSpacePointSelectionFunction, bool useSVDSpacePointSNRFractionSelector)
stores all possible 2-Cluster-combinations.
void provideSVDClusterCombinations(const StoreArray< SVDCluster > &svdClusters, StoreArray< SpacePointType > &spacePoints, SVDHitTimeSelection &hitTimeCut, bool useQualityEstimator, TFile *pdfFile, bool useLegacyNaming, unsigned int numMaxSpacePoints, std::string m_eventLevelTrackingInfoName, const bool &useSVDGroupInfo, const int &numberOfSignalGroups, const bool &formSingleSignalGroup, const SVDNoiseCalibrations &noiseCal, const DBObjPtr< SVDSpacePointSNRFractionSelector > &svdSpacePointSelectionFunction, bool useSVDSpacePointSNRFractionSelector)
finds all possible combinations of U and V Clusters for SVDClusters.
void spPDFName(const VxdID &sensor, int uSize, int vSize, int maxClusterSize, std::string &PDFName, std::string &errorPDFName, bool useLegacyNaming)
Function to set name of PDF for spacePoint quality estimation.
Abstract base class for different kinds of events.
small struct for storing all clusters of the same sensor in one container.
std::vector< const SVDCluster * > clustersU
stores all SVDclusters of U type.
std::vector< const SVDCluster * > clustersV
stores all SVDclusters of V type.
VxdID vxdID
Id of sensor, TODO can be removed if struct is used in a map.
void addCluster(const SVDCluster *entry)
member function to automatically add the cluster to its corresponding entry