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 <mdst/dataobjects/EventLevelTrackingInfo.h>
27#include <vxd/dataobjects/VxdID.h>
29#include <unordered_map>
100 RelationArray spacePointsToClusters(spacePoints, svdClusters);
101 for (
unsigned int i = 0; i < uint(svdClusters.
getEntries()); ++i) {
102 const SVDCluster* currentCluster = svdClusters[i];
103 std::vector<const SVDCluster*> currentClusterCombi = { currentCluster };
104 const int spacePointIndex = spacePoints.
getEntries();
105 spacePoints.
appendNew(currentClusterCombi);
106 spacePointsToClusters.
add(spacePointIndex, i);
114 std::vector<float>& inputVector,
118 inputVector.resize(3, 0.0);
122 for (
auto iSD : shaperDigits) {
123 auto samples = iSD.getSamples();
124 std::vector<float> selectedSamples;
125 if (samples.size() == 6) {
128 selectedSamples.assign(maxSamples.begin(), maxSamples.end());
130 selectedSamples.assign(samples.begin(), samples.end());
132 if (selectedSamples.size() < 3)
continue;
134 inputVector[0] += selectedSamples[0];
135 inputVector[1] += selectedSamples[1];
136 inputVector[2] += selectedSamples[2];
138 VxdID thisSensorID = iSD.getSensorID();
139 bool thisSide = iSD.isUStrip();
140 int thisCellID = iSD.getCellID();
141 float thisNoise = noiseCal.
getNoise(thisSensorID, thisSide, thisCellID);
142 noise += thisNoise * thisNoise;
145 inputVector[0] = inputVector[0] / noise;
146 inputVector[1] = inputVector[1] / noise;
147 inputVector[2] = inputVector[2] / noise;
159 std::vector< std::vector<const SVDCluster*> >& foundCombinations,
160 std::vector< std::pair<int, int> >& foundCombinationIndices,
const SVDHitTimeSelection& hitTimeCut,
161 const bool& useSVDGroupInfo,
const int& numberOfSignalGroups,
const bool& formSingleSignalGroup,
163 bool useSVDSpacePointSNRFractionSelector)
166 for (
size_t iU = 0; iU < aSensor.
clustersU.size(); ++iU) {
169 B2DEBUG(29,
"Cluster rejected due to timing cut. Cluster time: " << uCluster->
getClsTime());
172 for (
size_t iV = 0; iV < aSensor.
clustersV.size(); ++iV) {
175 B2DEBUG(29,
"Cluster rejected due to timing cut. Cluster time: " << vCluster->
getClsTime());
180 B2DEBUG(29,
"Cluster combination rejected due to timing cut. Cluster time U (" << uCluster->
getClsTime() <<
181 ") is incompatible with Cluster time V (" << vCluster->
getClsTime() <<
")");
185 if (useSVDGroupInfo) {
186 const std::vector<int>& uTimeGroupId = uCluster->
getTimeGroupId();
187 const std::vector<int>& vTimeGroupId = vCluster->
getTimeGroupId();
189 if (
int(uTimeGroupId.size()) &&
int(vTimeGroupId.size())) {
190 bool isContinue =
true;
191 for (
auto& uitem : uTimeGroupId) {
192 if (uitem < 0 || uitem >= numberOfSignalGroups)
continue;
193 for (
auto& vitem : vTimeGroupId) {
194 if (vitem < 0 || vitem >= numberOfSignalGroups)
continue;
195 if ((uitem == vitem) || formSingleSignalGroup) { isContinue =
false;
break; }
197 if (!isContinue)
break;
201 B2DEBUG(29,
"Cluster combination rejected due to different time-group Id.");
207 if (useSVDSpacePointSNRFractionSelector) {
208 std::vector<float> inputU;
209 std::vector<float> inputV;
214 bool pass = svdSpacePointSelectionFunction->passSNRFractionSelection(inputU, inputV);
216 B2DEBUG(29,
"Cluster combination rejected due to SVDSpacePointSNRFractionSelector");
221 foundCombinations.push_back({uCluster, vCluster});
222 foundCombinationIndices.emplace_back(aSensor.
indicesU[iU], aSensor.
indicesV[iV]);
238 inline void spPDFName(
const VxdID& sensor,
int uSize,
int vSize,
int maxClusterSize, std::string& PDFName,
239 std::string& errorPDFName,
bool useLegacyNaming)
241 if (useLegacyNaming ==
true) {
243 if (uSize > maxClusterSize) uSize = maxClusterSize;
244 if (vSize > maxClusterSize) vSize = maxClusterSize;
246 std::string sensorName;
248 if (sensor.getLayerNumber() == 3) sensorName =
"l3";
249 if (sensor.getLayerNumber() > 3 && sensor.getSensorNumber() == 1) sensorName =
"trap";
250 if (sensor.getLayerNumber() > 3 && sensor.getSensorNumber() > 1) sensorName =
"large";
252 PDFName = sensorName + std::to_string(uSize) + std::to_string(vSize);
253 errorPDFName =
"error" + PDFName;
256 if (uSize > maxClusterSize) uSize = maxClusterSize;
257 if (vSize > maxClusterSize) vSize = maxClusterSize;
259 int layer = sensor.getLayerNumber();
260 int ladder = sensor.getLadderNumber();
261 int sens = sensor.getSensorNumber();
263 PDFName = std::to_string(layer) +
"." + std::to_string(ladder) +
"." + std::to_string(sens) +
"." + std::to_string(
264 uSize) +
"." + std::to_string(vSize);
265 errorPDFName = PDFName +
"_Error";
280 inline void calculatePairingProb(TFile* pdfFile, std::vector<const SVDCluster*>& clusters,
double& prob,
double& error,
281 bool useLegacyNaming)
285 int pdfEntries = pdfFile->GetListOfKeys()->GetSize();
286 if (useLegacyNaming ==
true) {
287 maxSize = floor(
sqrt((pdfEntries - 4) / 6));
289 maxSize = floor(
sqrt((pdfEntries - 4) / 344));
291 std::string chargeProbInput;
292 std::string chargeErrorInput;
294 spPDFName(clusters[0]->getSensorID(), clusters[0]->getSize(), clusters[1]->getSize(), maxSize,
295 chargeProbInput, chargeErrorInput, useLegacyNaming);
296 std::string timeProbInput =
"timeProb";
297 std::string timeErrorInput =
"timeError";
298 std::string sizeProbInput =
"sizeProb";
299 std::string sizeErrorInput =
"sizeError";
302 TH2F* chargePDF =
nullptr;
303 TH2F* chargeError =
nullptr;
304 TH2F* timePDF =
nullptr;
305 TH2F* timeError =
nullptr;
306 TH2F* sizePDF =
nullptr;
307 TH2F* sizeError =
nullptr;
309 pdfFile->GetObject(chargeProbInput.c_str(), chargePDF);
310 pdfFile->GetObject(chargeErrorInput.c_str(), chargeError);
311 pdfFile->GetObject(timeProbInput.c_str(), timePDF);
312 pdfFile->GetObject(timeErrorInput.c_str(), timeError);
313 pdfFile->GetObject(sizeProbInput.c_str(), sizePDF);
314 pdfFile->GetObject(sizeErrorInput.c_str(), sizeError);
316 int xChargeBin = chargePDF->GetXaxis()->FindFixBin(clusters[0]->getCharge());
317 int yChargeBin = chargePDF->GetYaxis()->FindFixBin(clusters[1]->getCharge());
319 int xTimeBin = timePDF->GetXaxis()->FindFixBin(clusters[0]->getClsTime());
320 int yTimeBin = timePDF->GetYaxis()->FindFixBin(clusters[1]->getClsTime());
323 int xSizeBin = sizePDF->GetXaxis()->FindFixBin(clusters[0]->getSize());
324 int ySizeBin = sizePDF->GetYaxis()->FindFixBin(clusters[1]->getSize());
326 double chargeProb = chargePDF->GetBinContent(xChargeBin, yChargeBin);
327 double timeProb = timePDF->GetBinContent(xTimeBin, yTimeBin);
328 double sizeProb = sizePDF->GetBinContent(xSizeBin, ySizeBin);
329 double chargeProbError = chargePDF->GetBinContent(xChargeBin, yChargeBin);
330 double timeProbError = timePDF->GetBinContent(xTimeBin, yTimeBin);
331 double sizeProbError = sizePDF->GetBinContent(xSizeBin, ySizeBin);
334 if (chargeProbError == 0) {
335 B2DEBUG(21,
"svdClusterProbabilityEstimator has not been run, spacePoint QI will return zero!");
338 prob = chargeProb * timeProb * sizeProb * clusters[0]->getQuality() * clusters[1]->getQuality();
339 error = prob *
sqrt(pow(timeProb * sizeProb * clusters[0]->getQuality() * clusters[1]->getQuality() * chargeProbError, 2) +
340 pow(chargeProb * sizeProb * clusters[0]->getQuality() * clusters[1]->getQuality() * timeProbError, 2) +
341 pow(chargeProb * timeProb * clusters[0]->getQuality() * clusters[1]->getQuality() * sizeProbError, 2) +
342 pow(chargeProb * timeProb * sizeProb * clusters[1]->getQuality() * clusters[0]->getQualityError(), 2) +
343 pow(chargeProb * timeProb * sizeProb * clusters[0]->getQuality() * clusters[1]->getQualityError(), 2));
355 bool useLegacyNaming,
unsigned int numMaxSpacePoints, std::string m_eventLevelTrackingInfoName,
const bool& useSVDGroupInfo,
356 const int& numberOfSignalGroups,
const bool& formSingleSignalGroup,
358 bool useSVDSpacePointSNRFractionSelector)
360 std::unordered_map<VxdID::baseType, ClustersOnSensor>
362 std::vector<std::vector<const SVDCluster*> >
364 std::vector<std::pair<int, int> >
365 foundCombinationIndices;
368 for (
unsigned int i = 0; i < uint(svdClusters.
getEntries()); ++i) {
371 activatedSensors[currentCluster->
getSensorID().
getID()].addCluster(currentCluster, i);
374 for (
auto& aSensor : activatedSensors)
376 numberOfSignalGroups, formSingleSignalGroup, noiseCal, svdSpacePointSelectionFunction,
377 useSVDSpacePointSNRFractionSelector);
380 if (foundCombinations.size() > numMaxSpacePoints) {
382 if (m_eventLevelTrackingInfo.
isValid()) {
383 m_eventLevelTrackingInfo->setSVDSpacePointCreatorAbortionFlag();
390 RelationArray spacePointsToClusters(spacePoints, svdClusters);
392 for (
size_t iCombi = 0; iCombi < foundCombinations.size(); ++iCombi) {
393 auto& clusterCombi = foundCombinations[iCombi];
394 const int spacePointIndex = spacePoints.
getEntries();
395 SpacePointType* newSP = spacePoints.
appendNew(clusterCombi);
396 if (useQualityEstimator ==
true) {
400 newSP->setQualityEstimation(probability);
401 newSP->setQualityEstimationError(error);
404 spacePointsToClusters.
add(spacePointIndex, foundCombinationIndices[iCombi].first, 1.);
405 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.
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 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 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.
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