10 #include <klm/modules/KLMClusterAna/KLMClusterAnaModule.h>
13 #include <framework/dataobjects/EventMetaData.h>
14 #include <framework/datastore/StoreObjPtr.h>
18 #include <TMatrixDSymEigen.h>
35 static double expectation(std::vector<double> vec)
39 return accumulate(vec.begin(), vec.end(), 0.0) / vec.size();
42 static std::vector<double> addition(std::vector<double> vec1, std::vector<double> vec2)
44 std::vector<double> output(vec1.size());
45 if (vec1.size() != vec2.size()) {
46 B2ERROR(
"Vector lengths don't match so error. (addition)");
47 for (
unsigned int i = 0; i < (
unsigned int) vec1.size(); ++i) {
53 for (
unsigned int i = 0; i < (
unsigned int) vec1.size(); ++i) {
54 output[i] = vec1[i] + vec2[i];
61 static std::vector<double> product(std::vector<double> vec1, std::vector<double> vec2)
63 std::vector<double> output(vec1.size());
64 if (vec1.size() != vec2.size()) {
65 B2ERROR(
"Vector lengths don't match so error. (product)");
66 for (
unsigned int i = 0; i < (
unsigned int) vec1.size(); ++i) {
72 for (
unsigned int i = 0; i < (
unsigned int) vec1.size(); ++i) {
73 output[i] = vec1[i] * vec2[i];
79 static std::vector<double> covariance_matrix3x3(std::vector<double> xcoord, std::vector<double> ycoord, std::vector<double> zcoord)
82 if (xcoord.size() != ycoord.size() || (ycoord.size() != zcoord.size())) {
83 B2ERROR(
"Vector lengths don't match so error. (Covariance Matrix)");
84 double array[] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
85 std::vector <double>output(std::begin(array), std::end(array));
89 int length = xcoord.size();
90 double xmean = expectation(xcoord);
double ymean = expectation(ycoord);
double zmean = expectation(zcoord);
92 std::vector<double> xmeanV(length, -1 * xmean);
93 std::vector<double> ymeanV(length, -1 * ymean);
94 std::vector<double> zmeanV(length, -1 * zmean);
96 std::vector<double> deltax = addition(xcoord, xmeanV);
97 std::vector<double> deltay = addition(ycoord, ymeanV);
98 std::vector<double> deltaz = addition(zcoord, zmeanV);
100 double xxterm = expectation(product(deltax, deltax));
101 double xyterm = expectation(product(deltax, deltay));
102 double xzterm = expectation(product(deltax, deltaz));
103 double yyterm = expectation(product(deltay, deltay));
104 double yzterm = expectation(product(deltay, deltaz));
105 double zzterm = expectation(product(deltaz, deltaz));
107 double array[] = {xxterm, xyterm, xzterm, xyterm, yyterm, yzterm, xzterm, yzterm, zzterm};
108 std::vector <double>output(std::begin(array), std::end(array));
114 static TMatrixT<double> eigenvectors3x3(std::vector<double> matrix)
117 TMatrixT<double> output(4, 3);
118 if (matrix.size() != 9) {
119 B2ERROR(
"Error! For eigenvalue3x3 calc, invalid matrix size");
120 for (
int i = 0; i < 3; i++) {
121 for (
int j = 0; j < 3; j++) {
129 TMatrixDSym covar(3);
130 for (
int i = 0; i < 9; i++) {
131 covar[i % 3][i / 3] = matrix[i];
133 const TMatrixDSymEigen eigen(covar);
134 const TVectorT<double> eigenList = eigen.GetEigenValues();
135 const TMatrixT<double> eigenvecs = eigen.GetEigenVectors();
137 for (
int i = 0; i < 3; i++) {
138 for (
int j = 0; j < 3; j++) {
139 output[i][j] = eigenvecs[i][j];
141 output[3][i] = eigenList[i];
149 static TMatrixT<double> spatialVariances(std::vector<double> xcoord, std::vector<double> ycoord, std::vector<double> zcoord)
156 if (xcoord.size() != ycoord.size() || (ycoord.size() != zcoord.size())) {
157 B2FATAL(
"Vector lengths don't match so error.");
159 std::vector<double> covar = covariance_matrix3x3(xcoord, ycoord, zcoord);
161 TMatrixT<double> output = eigenvectors3x3(covar);
170 setDescription(
"Module for extracting KLM cluster shape information via PCA.");
195 ROOT::Math::XYZVector hitPosition;
199 int nHits = hit2ds.
size();
201 std::vector<double> xHits(nHits);
202 std::vector<double> yHits(nHits);
203 std::vector<double> zHits(nHits);
205 std::vector<KLMHit2d*> klmHit2ds;
206 std::vector<KLMHit2d*>::iterator it;
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 (it = klmHit2ds.begin(); it != klmHit2ds.end(); ++it) {
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).
REG_MODULE(arichBtest)
Register the Module.
Abstract base class for different kinds of events.