14#include <svd/calibration/SVDHitTimeSelection.h>
15#include <svd/calibration/SVDNoiseCalibrations.h>
16#include <svd/dataobjects/SVDCluster.h>
17#include <svd/dataobjects/SVDShaperDigit.h>
18#include <svd/dbobjects/SVDSpacePointSNRFractionSelector.h>
19#include <svd/reconstruction/SVDMaxSumAlgorithm.h>
21#include <framework/datastore/RelationArray.h>
22#include <framework/datastore/StoreArray.h>
23#include <framework/datastore/StoreObjPtr.h>
24#include <framework/database/DBObjPtr.h>
25#include <framework/utilities/MathHelpers.h>
26#include <mdst/dataobjects/EventLevelTrackingInfo.h>
28#include <vxd/dataobjects/VxdID.h>
30#include <unordered_map>
101 RelationArray spacePointsToClusters(spacePoints, svdClusters);
102 for (
unsigned int i = 0; i < uint(svdClusters.
getEntries()); ++i) {
103 const SVDCluster* currentCluster = svdClusters[i];
104 std::vector<const SVDCluster*> currentClusterCombi = { currentCluster };
105 const int spacePointIndex = spacePoints.
getEntries();
106 spacePoints.
appendNew(currentClusterCombi);
107 spacePointsToClusters.
add(spacePointIndex, i);
115 std::vector<float>& inputVector,
119 inputVector.resize(3, 0.0);
123 for (
auto iSD : shaperDigits) {
124 auto samples = iSD.getSamples();
125 std::vector<float> selectedSamples;
126 if (samples.size() == 6) {
129 selectedSamples.assign(maxSamples.begin(), maxSamples.end());
131 selectedSamples.assign(samples.begin(), samples.end());
133 if (selectedSamples.size() < 3)
continue;
135 inputVector[0] += selectedSamples[0];
136 inputVector[1] += selectedSamples[1];
137 inputVector[2] += selectedSamples[2];
139 VxdID thisSensorID = iSD.getSensorID();
140 bool thisSide = iSD.isUStrip();
141 int thisCellID = iSD.getCellID();
142 float thisNoise = noiseCal.
getNoise(thisSensorID, thisSide, thisCellID);
143 noise += thisNoise * thisNoise;
146 inputVector[0] = inputVector[0] / noise;
147 inputVector[1] = inputVector[1] / noise;
148 inputVector[2] = inputVector[2] / noise;
160 std::vector< std::vector<const SVDCluster*> >& foundCombinations,
161 std::vector< std::pair<int, int> >& foundCombinationIndices,
const SVDHitTimeSelection& hitTimeCut,
162 const bool& useSVDGroupInfo,
const int& numberOfSignalGroups,
const bool& formSingleSignalGroup,
164 bool useSVDSpacePointSNRFractionSelector)
167 for (
size_t iU = 0; iU < aSensor.
clustersU.size(); ++iU) {
170 B2DEBUG(29,
"Cluster rejected due to timing cut. Cluster time: " << uCluster->
getClsTime());
173 for (
size_t iV = 0; iV < aSensor.
clustersV.size(); ++iV) {
176 B2DEBUG(29,
"Cluster rejected due to timing cut. Cluster time: " << vCluster->
getClsTime());
181 B2DEBUG(29,
"Cluster combination rejected due to timing cut. Cluster time U (" << uCluster->
getClsTime() <<
182 ") is incompatible with Cluster time V (" << vCluster->
getClsTime() <<
")");
186 if (useSVDGroupInfo) {
187 const std::vector<int>& uTimeGroupId = uCluster->
getTimeGroupId();
188 const std::vector<int>& vTimeGroupId = vCluster->
getTimeGroupId();
190 if (
int(uTimeGroupId.size()) &&
int(vTimeGroupId.size())) {
191 bool isContinue =
true;
192 for (
const auto& uitem : uTimeGroupId) {
193 if (uitem < 0 || uitem >= numberOfSignalGroups)
continue;
194 for (
const auto& vitem : vTimeGroupId) {
195 if (vitem < 0 || vitem >= numberOfSignalGroups)
continue;
196 if ((uitem == vitem) || formSingleSignalGroup) { isContinue =
false;
break; }
198 if (!isContinue)
break;
202 B2DEBUG(29,
"Cluster combination rejected due to different time-group Id.");
208 if (useSVDSpacePointSNRFractionSelector) {
209 std::vector<float> inputU;
210 std::vector<float> inputV;
215 bool pass = svdSpacePointSelectionFunction->passSNRFractionSelection(inputU, inputV);
217 B2DEBUG(29,
"Cluster combination rejected due to SVDSpacePointSNRFractionSelector");
222 foundCombinations.push_back({uCluster, vCluster});
223 foundCombinationIndices.emplace_back(aSensor.
indicesU[iU], aSensor.
indicesV[iV]);
239 inline void spPDFName(
const VxdID& sensor,
int uSize,
int vSize,
int maxClusterSize, std::string& PDFName,
240 std::string& errorPDFName,
bool useLegacyNaming)
242 if (useLegacyNaming ==
true) {
244 if (uSize > maxClusterSize) uSize = maxClusterSize;
245 if (vSize > maxClusterSize) vSize = maxClusterSize;
247 std::string sensorName;
249 if (sensor.getLayerNumber() == 3) sensorName =
"l3";
250 if (sensor.getLayerNumber() > 3 && sensor.getSensorNumber() == 1) sensorName =
"trap";
251 if (sensor.getLayerNumber() > 3 && sensor.getSensorNumber() > 1) sensorName =
"large";
253 PDFName = sensorName + std::to_string(uSize) + std::to_string(vSize);
254 errorPDFName =
"error" + PDFName;
257 if (uSize > maxClusterSize) uSize = maxClusterSize;
258 if (vSize > maxClusterSize) vSize = maxClusterSize;
260 int layer = sensor.getLayerNumber();
261 int ladder = sensor.getLadderNumber();
262 int sens = sensor.getSensorNumber();
264 PDFName = std::to_string(layer) +
"." + std::to_string(ladder) +
"." + std::to_string(sens) +
"." + std::to_string(
265 uSize) +
"." + std::to_string(vSize);
266 errorPDFName = PDFName +
"_Error";
281 inline void calculatePairingProb(TFile* pdfFile,
const std::vector<const SVDCluster*>& clusters,
double& prob,
double& error,
282 bool useLegacyNaming)
286 int pdfEntries = pdfFile->GetListOfKeys()->GetSize();
287 if (useLegacyNaming ==
true) {
288 maxSize = floor(
sqrt((pdfEntries - 4) / 6));
290 maxSize = floor(
sqrt((pdfEntries - 4) / 344));
292 std::string chargeProbInput;
293 std::string chargeErrorInput;
295 spPDFName(clusters[0]->getSensorID(), clusters[0]->getSize(), clusters[1]->getSize(), maxSize,
296 chargeProbInput, chargeErrorInput, useLegacyNaming);
297 std::string timeProbInput =
"timeProb";
298 std::string timeErrorInput =
"timeError";
299 std::string sizeProbInput =
"sizeProb";
300 std::string sizeErrorInput =
"sizeError";
303 TH2F* chargePDF =
nullptr;
304 TH2F* chargeError =
nullptr;
305 TH2F* timePDF =
nullptr;
306 TH2F* timeError =
nullptr;
307 TH2F* sizePDF =
nullptr;
308 TH2F* sizeError =
nullptr;
310 pdfFile->GetObject(chargeProbInput.c_str(), chargePDF);
311 pdfFile->GetObject(chargeErrorInput.c_str(), chargeError);
312 pdfFile->GetObject(timeProbInput.c_str(), timePDF);
313 pdfFile->GetObject(timeErrorInput.c_str(), timeError);
314 pdfFile->GetObject(sizeProbInput.c_str(), sizePDF);
315 pdfFile->GetObject(sizeErrorInput.c_str(), sizeError);
317 int xChargeBin = chargePDF->GetXaxis()->FindFixBin(clusters[0]->getCharge());
318 int yChargeBin = chargePDF->GetYaxis()->FindFixBin(clusters[1]->getCharge());
320 int xTimeBin = timePDF->GetXaxis()->FindFixBin(clusters[0]->getClsTime());
321 int yTimeBin = timePDF->GetYaxis()->FindFixBin(clusters[1]->getClsTime());
324 int xSizeBin = sizePDF->GetXaxis()->FindFixBin(clusters[0]->getSize());
325 int ySizeBin = sizePDF->GetYaxis()->FindFixBin(clusters[1]->getSize());
327 double chargeProb = chargePDF->GetBinContent(xChargeBin, yChargeBin);
328 double timeProb = timePDF->GetBinContent(xTimeBin, yTimeBin);
329 double sizeProb = sizePDF->GetBinContent(xSizeBin, ySizeBin);
330 double chargeProbError = chargePDF->GetBinContent(xChargeBin, yChargeBin);
331 double timeProbError = timePDF->GetBinContent(xTimeBin, yTimeBin);
332 double sizeProbError = sizePDF->GetBinContent(xSizeBin, ySizeBin);
335 if (chargeProbError == 0) {
336 B2DEBUG(21,
"svdClusterProbabilityEstimator has not been run, spacePoint QI will return zero!");
339 prob = chargeProb * timeProb * sizeProb * clusters[0]->getQuality() * clusters[1]->getQuality();
340 error = prob *
sqrt(
square(timeProb * sizeProb * clusters[0]->getQuality() * clusters[1]->getQuality() * chargeProbError) +
341 square(chargeProb * sizeProb * clusters[0]->getQuality() * clusters[1]->getQuality() * timeProbError) +
342 square(chargeProb * timeProb * clusters[0]->getQuality() * clusters[1]->getQuality() * sizeProbError) +
343 square(chargeProb * timeProb * sizeProb * clusters[1]->getQuality() * clusters[0]->getQualityError()) +
344 square(chargeProb * timeProb * sizeProb * clusters[0]->getQuality() * clusters[1]->getQualityError()));
356 bool useLegacyNaming,
unsigned int numMaxSpacePoints, std::string m_eventLevelTrackingInfoName,
const bool& useSVDGroupInfo,
357 const int& numberOfSignalGroups,
const bool& formSingleSignalGroup,
359 bool useSVDSpacePointSNRFractionSelector)
361 std::unordered_map<VxdID::baseType, ClustersOnSensor>
363 std::vector<std::vector<const SVDCluster*> >
365 std::vector<std::pair<int, int> >
366 foundCombinationIndices;
369 for (
unsigned int i = 0; i < uint(svdClusters.
getEntries()); ++i) {
372 activatedSensors[currentCluster->
getSensorID().
getID()].addCluster(currentCluster, i);
376 for (
const auto& aSensor : activatedSensors)
378 numberOfSignalGroups, formSingleSignalGroup, noiseCal, svdSpacePointSelectionFunction,
379 useSVDSpacePointSNRFractionSelector);
382 if (foundCombinations.size() > numMaxSpacePoints) {
384 if (m_eventLevelTrackingInfo.
isValid()) {
385 m_eventLevelTrackingInfo->setSVDSpacePointCreatorAbortionFlag();
392 RelationArray spacePointsToClusters(spacePoints, svdClusters);
394 for (
size_t iCombi = 0; iCombi < foundCombinations.size(); ++iCombi) {
395 auto& clusterCombi = foundCombinations[iCombi];
396 const int spacePointIndex = spacePoints.
getEntries();
397 SpacePointType* newSP = spacePoints.
appendNew(clusterCombi);
398 if (useQualityEstimator ==
true) {
402 newSP->setQualityEstimation(probability);
403 newSP->setQualityEstimationError(error);
406 spacePointsToClusters.
add(spacePointIndex, foundCombinationIndices[iCombi].first, 1.);
407 spacePointsToClusters.
add(spacePointIndex, foundCombinationIndices[iCombi].second, -1.);
Class for accessing objects in the database.
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.
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 findPossibleCombinations(const Belle2::ClustersOnSensor &aSensor, std::vector< std::vector< const SVDCluster * > > &foundCombinations, std::vector< std::pair< int, int > > &foundCombinationIndices, 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 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 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.
void calculatePairingProb(TFile *pdfFile, const 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 ...
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.
std::vector< int > indicesV
stores the StoreArray indices of the clusters in clustersV, in the same order
std::vector< int > indicesU
stores the StoreArray indices of the clusters in clustersU, in the same order
void addCluster(const SVDCluster *entry, int index)
member function to automatically add the cluster to its corresponding entry