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 <mdst/dataobjects/EventLevelTrackingInfo.h>
25#include <vxd/dataobjects/VxdID.h>
27#include <unordered_map>
81 for (
unsigned int i = 0; i < uint(svdClusters.
getEntries()); ++i) {
82 const SVDCluster* currentCluster = svdClusters[i];
83 std::vector<const SVDCluster*> currentClusterCombi = { currentCluster };
84 SpacePointType* newSP = spacePoints.
appendNew(currentClusterCombi);
85 newSP->addRelationTo(currentCluster);
93 std::vector<float>& inputVector,
97 inputVector.resize(3, 0.0);
101 for (
auto iSD : shaperDigits) {
102 auto samples = iSD.getSamples();
103 std::vector<float> selectedSamples;
104 if (samples.size() == 6) {
107 selectedSamples.assign(maxSamples.begin(), maxSamples.end());
109 selectedSamples.assign(samples.begin(), samples.end());
111 if (selectedSamples.size() < 3)
continue;
113 inputVector[0] += selectedSamples[0];
114 inputVector[1] += selectedSamples[1];
115 inputVector[2] += selectedSamples[2];
117 VxdID thisSensorID = iSD.getSensorID();
118 bool thisSide = iSD.isUStrip();
119 int thisCellID = iSD.getCellID();
120 float thisNoise = noiseCal.
getNoise(thisSensorID, thisSide, thisCellID);
121 noise += thisNoise * thisNoise;
124 inputVector[0] = inputVector[0] / noise;
125 inputVector[1] = inputVector[1] / noise;
126 inputVector[2] = inputVector[2] / noise;
138 std::vector< std::vector<const SVDCluster*> >& foundCombinations,
const SVDHitTimeSelection& hitTimeCut,
139 const bool& useSVDGroupInfo,
const int& numberOfSignalGroups,
const bool& formSingleSignalGroup,
141 bool useSVDSpacePointSNRFractionSelector)
146 B2DEBUG(29,
"Cluster rejected due to timing cut. Cluster time: " << uCluster->
getClsTime());
151 B2DEBUG(29,
"Cluster rejected due to timing cut. Cluster time: " << vCluster->
getClsTime());
156 B2DEBUG(29,
"Cluster combination rejected due to timing cut. Cluster time U (" << uCluster->
getClsTime() <<
157 ") is incompatible with Cluster time V (" << vCluster->
getClsTime() <<
")");
161 if (useSVDGroupInfo) {
162 const std::vector<int>& uTimeGroupId = uCluster->
getTimeGroupId();
163 const std::vector<int>& vTimeGroupId = vCluster->
getTimeGroupId();
165 if (
int(uTimeGroupId.size()) &&
int(vTimeGroupId.size())) {
166 bool isContinue =
true;
167 for (
auto& uitem : uTimeGroupId) {
168 if (uitem < 0 || uitem >= numberOfSignalGroups)
continue;
169 for (
auto& vitem : vTimeGroupId) {
170 if (vitem < 0 || vitem >= numberOfSignalGroups)
continue;
171 if ((uitem == vitem) || formSingleSignalGroup) { isContinue =
false;
break; }
173 if (!isContinue)
break;
177 B2DEBUG(29,
"Cluster combination rejected due to different time-group Id.");
183 if (useSVDSpacePointSNRFractionSelector) {
184 std::vector<float> inputU;
185 std::vector<float> inputV;
190 bool pass = svdSpacePointSelectionFunction->passSNRFractionSelection(inputU, inputV);
192 B2DEBUG(29,
"Cluster combination rejected due to SVDSpacePointSNRFractionSelector");
197 foundCombinations.push_back({uCluster, vCluster});
213 inline void spPDFName(
const VxdID& sensor,
int uSize,
int vSize,
int maxClusterSize, std::string& PDFName,
214 std::string& errorPDFName,
bool useLegacyNaming)
216 if (useLegacyNaming ==
true) {
218 if (uSize > maxClusterSize) uSize = maxClusterSize;
219 if (vSize > maxClusterSize) vSize = maxClusterSize;
221 std::string sensorName;
223 if (sensor.getLayerNumber() == 3) sensorName =
"l3";
224 if (sensor.getLayerNumber() > 3 && sensor.getSensorNumber() == 1) sensorName =
"trap";
225 if (sensor.getLayerNumber() > 3 && sensor.getSensorNumber() > 1) sensorName =
"large";
227 PDFName = sensorName + std::to_string(uSize) + std::to_string(vSize);
228 errorPDFName =
"error" + PDFName;
231 if (uSize > maxClusterSize) uSize = maxClusterSize;
232 if (vSize > maxClusterSize) vSize = maxClusterSize;
234 int layer = sensor.getLayerNumber();
235 int ladder = sensor.getLadderNumber();
236 int sens = sensor.getSensorNumber();
238 PDFName = std::to_string(layer) +
"." + std::to_string(ladder) +
"." + std::to_string(sens) +
"." + std::to_string(
239 uSize) +
"." + std::to_string(vSize);
240 errorPDFName = PDFName +
"_Error";
255 inline void calculatePairingProb(TFile* pdfFile, std::vector<const SVDCluster*>& clusters,
double& prob,
double& error,
256 bool useLegacyNaming)
260 int pdfEntries = pdfFile->GetListOfKeys()->GetSize();
261 if (useLegacyNaming ==
true) {
262 maxSize = floor(
sqrt((pdfEntries - 4) / 6));
264 maxSize = floor(
sqrt((pdfEntries - 4) / 344));
266 std::string chargeProbInput;
267 std::string chargeErrorInput;
269 spPDFName(clusters[0]->getSensorID(), clusters[0]->getSize(), clusters[1]->getSize(), maxSize,
270 chargeProbInput, chargeErrorInput, useLegacyNaming);
271 std::string timeProbInput =
"timeProb";
272 std::string timeErrorInput =
"timeError";
273 std::string sizeProbInput =
"sizeProb";
274 std::string sizeErrorInput =
"sizeError";
277 TH2F* chargePDF =
nullptr;
278 TH2F* chargeError =
nullptr;
279 TH2F* timePDF =
nullptr;
280 TH2F* timeError =
nullptr;
281 TH2F* sizePDF =
nullptr;
282 TH2F* sizeError =
nullptr;
284 pdfFile->GetObject(chargeProbInput.c_str(), chargePDF);
285 pdfFile->GetObject(chargeErrorInput.c_str(), chargeError);
286 pdfFile->GetObject(timeProbInput.c_str(), timePDF);
287 pdfFile->GetObject(timeErrorInput.c_str(), timeError);
288 pdfFile->GetObject(sizeProbInput.c_str(), sizePDF);
289 pdfFile->GetObject(sizeErrorInput.c_str(), sizeError);
291 int xChargeBin = chargePDF->GetXaxis()->FindFixBin(clusters[0]->getCharge());
292 int yChargeBin = chargePDF->GetYaxis()->FindFixBin(clusters[1]->getCharge());
294 int xTimeBin = timePDF->GetXaxis()->FindFixBin(clusters[0]->getClsTime());
295 int yTimeBin = timePDF->GetYaxis()->FindFixBin(clusters[1]->getClsTime());
298 int xSizeBin = sizePDF->GetXaxis()->FindFixBin(clusters[0]->getSize());
299 int ySizeBin = sizePDF->GetYaxis()->FindFixBin(clusters[1]->getSize());
301 double chargeProb = chargePDF->GetBinContent(xChargeBin, yChargeBin);
302 double timeProb = timePDF->GetBinContent(xTimeBin, yTimeBin);
303 double sizeProb = sizePDF->GetBinContent(xSizeBin, ySizeBin);
304 double chargeProbError = chargePDF->GetBinContent(xChargeBin, yChargeBin);
305 double timeProbError = timePDF->GetBinContent(xTimeBin, yTimeBin);
306 double sizeProbError = sizePDF->GetBinContent(xSizeBin, ySizeBin);
309 if (chargeProbError == 0) {
310 B2DEBUG(21,
"svdClusterProbabilityEstimator has not been run, spacePoint QI will return zero!");
313 prob = chargeProb * timeProb * sizeProb * clusters[0]->getQuality() * clusters[1]->getQuality();
314 error = prob *
sqrt(pow(timeProb * sizeProb * clusters[0]->getQuality() * clusters[1]->getQuality() * chargeProbError, 2) +
315 pow(chargeProb * sizeProb * clusters[0]->getQuality() * clusters[1]->getQuality() * timeProbError, 2) +
316 pow(chargeProb * timeProb * clusters[0]->getQuality() * clusters[1]->getQuality() * sizeProbError, 2) +
317 pow(chargeProb * timeProb * sizeProb * clusters[1]->getQuality() * clusters[0]->getQualityError(), 2) +
318 pow(chargeProb * timeProb * sizeProb * clusters[0]->getQuality() * clusters[1]->getQualityError(), 2));
330 bool useLegacyNaming,
unsigned int numMaxSpacePoints, std::string m_eventLevelTrackingInfoName,
const bool& useSVDGroupInfo,
331 const int& numberOfSignalGroups,
const bool& formSingleSignalGroup,
333 bool useSVDSpacePointSNRFractionSelector)
335 std::unordered_map<VxdID::baseType, ClustersOnSensor>
337 std::vector<std::vector<const SVDCluster*> >
341 for (
unsigned int i = 0; i < uint(svdClusters.
getEntries()); ++i) {
344 activatedSensors[currentCluster->
getSensorID().
getID()].addCluster(currentCluster);
348 for (
auto& aSensor : activatedSensors)
350 formSingleSignalGroup,
351 noiseCal, svdSpacePointSelectionFunction, useSVDSpacePointSNRFractionSelector);
354 if (foundCombinations.size() > numMaxSpacePoints) {
356 if (m_eventLevelTrackingInfo.
isValid()) {
357 m_eventLevelTrackingInfo->setSVDSpacePointCreatorAbortionFlag();
362 for (
auto& clusterCombi : foundCombinations) {
363 SpacePointType* newSP = spacePoints.
appendNew(clusterCombi);
364 if (useQualityEstimator ==
true) {
368 newSP->setQualityEstimation(probability);
369 newSP->setQualityEstimationError(error);
371 for (
auto* cluster : clusterCombi) {
372 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.
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