StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StThinPlateSpline.cxx
1 
6 /***************************************************************************
7  *
8  * $Id: StThinPlateSpline.cxx,v 1.2 2014/01/28 19:29:47 qiuh Exp $
9  *
10  * Author: Qiu Hao, March 2013
11  ***************************************************************************
12  *
13  * Description:
14  *
15  ***************************************************************************
16  *
17  * $Log: StThinPlateSpline.cxx,v $
18  * Revision 1.2 2014/01/28 19:29:47 qiuh
19  * *** empty log message ***
20  *
21  *
22  **************************************************************************/
23 
24 #include "StThinPlateSpline.h"
25 #include "TMatrixT.h"
26 #include <math.h>
27 
28 StThinPlateSpline::StThinPlateSpline(Int_t nMeasurements)
29 {
30  mX = new TMatrixT<double>(nMeasurements, 1);
31  mY = new TMatrixT<double>(nMeasurements, 1);
32  mW = new TMatrixT<double>(nMeasurements, 1);
33  mA = new TMatrixT<double>(3, 1);
34 }
35 
36 StThinPlateSpline::StThinPlateSpline(Int_t nMeasurements, Double_t *X, Double_t *Y, Double_t *W, Double_t *A)
37 {
38  mX = new TMatrixT<double>(nMeasurements, 1, X);
39  mY = new TMatrixT<double>(nMeasurements, 1, Y);
40  mW = new TMatrixT<double>(nMeasurements, 1, W);
41  mA = new TMatrixT<double>(3, 1, A);
42 }
43 
44 StThinPlateSpline::StThinPlateSpline(Int_t nMeasurements, Float_t *X, Float_t *Y, Float_t *W, Float_t *A)
45 {
46  mX = new TMatrixT<double>(nMeasurements, 1);
47  mY = new TMatrixT<double>(nMeasurements, 1);
48  mW = new TMatrixT<double>(nMeasurements, 1);
49  mA = new TMatrixT<double>(3, 1);
50  for (int j = 0; j < 3; j++)
51  (*mA)[j][0] = A[j];
52  for (int j = 0; j < nMeasurements; j++)
53  (*mX)[j][0] = X[j];
54  for (int j = 0; j < nMeasurements; j++)
55  (*mY)[j][0] = Y[j];
56  for (int j = 0; j < nMeasurements; j++)
57  (*mW)[j][0] = W[j];
58 }
59 
60 StThinPlateSpline::~StThinPlateSpline()
61 {
62  delete mA;
63  delete mX;
64  delete mY;
65  delete mW;
66 }
67 
68 void StThinPlateSpline::fit(Int_t nMeasurements, Double_t *xMeasurement, Double_t *yMeasurement, Double_t *zMeasurement, Double_t lambda)
69 {
70  TMatrixT<double> P(nMeasurements, 3);
71  TMatrixT<double> One(nMeasurements, 1);
72 
73  One += 1;
74  mX->Use(nMeasurements, 1, xMeasurement);
75  mY->Use(nMeasurements, 1, yMeasurement);
76  P.SetSub(0, 0, One);
77  P.SetSub(0, 1, *mX);
78  P.SetSub(0, 2, *mY);
79  // P.Print();
80 
81  TMatrixT<double> K(nMeasurements, nMeasurements);
82  for (int i = 0; i < nMeasurements; i++)
83  for (int j = 0; j < nMeasurements; j++) {
84  double r2 = pow((*mX)[i][0] - (*mX)[j][0], 2) + pow((*mY)[i][0] - (*mY)[j][0], 2);
85  K[i][j] = ur(r2);
86  }
87  // K.Print();
88 
89  TMatrixT<double> I(nMeasurements, nMeasurements);
90  I.UnitMatrix();
91  K += lambda * I;
92 
93  TMatrixT<double> L(nMeasurements + 3, nMeasurements + 3);
94  L.SetSub(0, 0, K);
95  L.SetSub(0, nMeasurements, P);
96  L.SetSub(nMeasurements, 0, P.Transpose(P));
97  // L.Print();
98 
99  TMatrixT<double> V(nMeasurements, 1, zMeasurement);
100  TMatrixT<double> Y(nMeasurements + 3, 1);
101  Y.SetSub(0, 0, V);
102  // Y.Print();
103 
104  TMatrixT<double> WA(Y);
105  L.Invert();
106  // L.Print();
107  WA.Mult(L, Y);
108 
109  mW->ResizeTo(nMeasurements, 1);
110  *mW = WA.GetSub(0, nMeasurements - 1, 0, 0);
111  *mA = WA.GetSub(nMeasurements, nMeasurements + 2, 0, 0);
112 
113  // mA->Print();
114  // mW->Print();
115 }
116 
117 Double_t StThinPlateSpline::ur(Double_t r2) const
118 {
119  if (r2 == 0) return 0;
120  return r2 * log(r2);
121 }
122 
123 Double_t StThinPlateSpline::z(Double_t x, Double_t y) const
124 {
125  double z_ = 0;
126  z_ = (*mA)[0][0] + (*mA)[1][0] * x + (*mA)[2][0] * y;
127  for (int i = 0; i < mW->GetNrows(); i++) {
128  double r2 = pow(x - (*mX)[i][0], 2) + pow(y - (*mY)[i][0], 2);
129  z_ += (*mW)[i][0] * ur(r2);
130  }
131  return z_;
132 }
133 
Double_t z(Double_t x, Double_t y) const
calculate z on the profile at (x,y)
void fit(Int_t nMeasurements, Double_t *xMeasurement, Double_t *yMeasurement, Double_t *zMeasurement, Double_t lambda=0)
fit measurements on a profile with tps to get mX, mY, mW, mA matrix