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.");
194 ROOT::Math::XYZVector hitPosition;
198 int nHits = hit2ds.
size();
200 std::vector<double> xHits(nHits);
201 std::vector<double> yHits(nHits);
202 std::vector<double> zHits(nHits);
204 std::vector<KLMHit2d*> klmHit2ds;
206 for (
int i = 0; i < nHits; i++) {
207 klmHit2ds.push_back(hit2ds[i]);
208 hitPosition = hit2ds[i]->getPosition();
209 xHits[i] = (double) hitPosition.X();
210 yHits[i] = (double) hitPosition.Y();
211 zHits[i] = (double) hitPosition.Z();
220 TMatrixT<double> output = spatialVariances(xHits, yHits, zHits);
227 klmcluster.addRelationTo(clusterShape);
229 for (
const KLMHit2d* hit2d : klmHit2ds) {
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.
void setDescription(const std::string &description)
Sets the description of the module.
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.
Abstract base class for different kinds of events.