10#include <klm/modules/KLMClusterAna/KLMClusterAnaModule.h>
13#include <framework/dataobjects/EventMetaData.h>
14#include <framework/datastore/StoreObjPtr.h>
18#include <TMatrixDSymEigen.h>
34static double expectation(std::vector<double> vec)
38 return accumulate(vec.begin(), vec.end(), 0.0) / vec.size();
41static std::vector<double> addition(std::vector<double> vec1, std::vector<double> vec2)
43 std::vector<double> output(vec1.size());
44 if (vec1.size() != vec2.size()) {
45 B2ERROR(
"Vector lengths don't match so error. (addition)");
46 for (
unsigned int i = 0; i < (
unsigned int) vec1.size(); ++i) {
52 for (
unsigned int i = 0; i < (
unsigned int) vec1.size(); ++i) {
53 output[i] = vec1[i] + vec2[i];
60static std::vector<double> product(std::vector<double> vec1, std::vector<double> vec2)
62 std::vector<double> output(vec1.size());
63 if (vec1.size() != vec2.size()) {
64 B2ERROR(
"Vector lengths don't match so error. (product)");
65 for (
unsigned int i = 0; i < (
unsigned int) vec1.size(); ++i) {
71 for (
unsigned int i = 0; i < (
unsigned int) vec1.size(); ++i) {
72 output[i] = vec1[i] * vec2[i];
78static std::vector<double> covariance_matrix3x3(std::vector<double> xcoord, std::vector<double> ycoord, std::vector<double> zcoord)
81 if (xcoord.size() != ycoord.size() || (ycoord.size() != zcoord.size())) {
82 B2ERROR(
"Vector lengths don't match so error. (Covariance Matrix)");
83 double array[] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
84 std::vector <double>output(std::begin(
array), std::end(
array));
88 int length = xcoord.size();
89 double xmean = expectation(xcoord);
double ymean = expectation(ycoord);
double zmean = expectation(zcoord);
91 std::vector<double> xmeanV(length, -1 * xmean);
92 std::vector<double> ymeanV(length, -1 * ymean);
93 std::vector<double> zmeanV(length, -1 * zmean);
95 std::vector<double> deltax = addition(xcoord, xmeanV);
96 std::vector<double> deltay = addition(ycoord, ymeanV);
97 std::vector<double> deltaz = addition(zcoord, zmeanV);
99 double xxterm = expectation(product(deltax, deltax));
100 double xyterm = expectation(product(deltax, deltay));
101 double xzterm = expectation(product(deltax, deltaz));
102 double yyterm = expectation(product(deltay, deltay));
103 double yzterm = expectation(product(deltay, deltaz));
104 double zzterm = expectation(product(deltaz, deltaz));
106 double array[] = {xxterm, xyterm, xzterm, xyterm, yyterm, yzterm, xzterm, yzterm, zzterm};
107 std::vector <double>output(std::begin(
array), std::end(
array));
113static TMatrixT<double> eigenvectors3x3(std::vector<double> matrix)
116 TMatrixT<double> output(4, 3);
117 if (matrix.size() != 9) {
118 B2ERROR(
"Error! For eigenvalue3x3 calc, invalid matrix size");
119 for (
int i = 0; i < 3; i++) {
120 for (
int j = 0; j < 3; j++) {
128 TMatrixDSym covar(3);
129 for (
int i = 0; i < 9; i++) {
130 covar[i % 3][i / 3] = matrix[i];
132 const TMatrixDSymEigen eigen(covar);
133 const TVectorT<double> eigenList = eigen.GetEigenValues();
134 const TMatrixT<double> eigenvecs = eigen.GetEigenVectors();
136 for (
int i = 0; i < 3; i++) {
137 for (
int j = 0; j < 3; j++) {
138 output[i][j] = eigenvecs[i][j];
140 output[3][i] = eigenList[i];
148static TMatrixT<double> spatialVariances(std::vector<double> xcoord, std::vector<double> ycoord, std::vector<double> zcoord)
155 if (xcoord.size() != ycoord.size() || (ycoord.size() != zcoord.size())) {
156 B2FATAL(
"Vector lengths don't match so error.");
158 std::vector<double> covar = covariance_matrix3x3(xcoord, ycoord, zcoord);
160 TMatrixT<double> output = eigenvectors3x3(covar);
169 setDescription(
"Module for extracting KLM cluster shape information via PCA.");
196 ROOT::Math::XYZVector hitPosition;
200 int nHits = hit2ds.
size();
202 std::vector<double> xHits(nHits);
203 std::vector<double> yHits(nHits);
204 std::vector<double> zHits(nHits);
206 std::vector<KLMHit2d*> klmHit2ds;
208 for (
int i = 0; i < nHits; i++) {
209 klmHit2ds.push_back(hit2ds[i]);
210 hitPosition = hit2ds[i]->getPosition();
211 xHits[i] = (double) hitPosition.X();
212 yHits[i] = (double) hitPosition.Y();
213 zHits[i] = (double) hitPosition.Z();
222 TMatrixT<double> output = spatialVariances(xHits, yHits, zHits);
229 klmcluster.addRelationTo(clusterShape);
231 for (
const KLMHit2d* hit2d : klmHit2ds) {
236 klmcluster.setShapeStdDev1(0);
237 klmcluster.setShapeStdDev2(0);
238 klmcluster.setShapeStdDev3(0);
void initialize() override
Initializer.
void event() override
This method is called for each event.
KLMClusterAnaModule()
Constructor.
StoreArray< KLMClusterShape > m_KLMClusterShape
Output per cluster.
void beginRun() override
Called when entering a new run.
StoreArray< KLMHit2d > m_klmHit2ds
Two-dimensional hits.
StoreArray< KLMCluster > m_KLMClusters
KLM clusters.
~KLMClusterAnaModule()
Destructor.
Variable for KLM cluster shape analysis.
void setEigen(TMatrixT< double > eigenList)
Set eigenvectors and eigenvalues.
void setNHits(int nHits)
Set number of hits.
double getVariance1() const
Get principal axis eigenvector.
double getVariance3() const
Get tertiary axis eigenvector.
double getVariance2() const
Get secondary axis eigenvector.
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Class for type safe access to objects that are referred to in relations.
size_t size() const
Get number of relations.
void addRelationTo(const RelationsInterface< BASE > *object, float weight=1.0, const std::string &namedRelation="") const
Add a relation from this object to another object (with caching).
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
double sqrt(double a)
sqrt for double
Abstract base class for different kinds of events.