EIC Software
Reference for
EIC
simulation and reconstruction software on GitHub
Home page
Related Pages
Modules
Namespaces
Classes
Files
External Links
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Groups
Pages
ThreeDeePolySpace.cxx
Go to the documentation of this file.
Or view
the newest version in sPHENIX GitHub for file ThreeDeePolySpace.cxx
1
/* -------------------------------------------------------------------------- */
2
/* ThreeDeePolySpace.cc */
3
/* */
4
/* Collection of fitting routines with orthogonal polynomials. */
5
/* */
6
/* A.Kisselev, PNPI, St.Petersburg, Russia. */
7
/* e-mail: kisselev@hermes.desy.de */
8
/* -------------------------------------------------------------------------- */
9
10
#include <cstdio>
11
#include <cstdlib>
12
#include <cstring>
13
#include <cmath>
14
#include <cassert>
15
16
#include <
ayk.h
>
17
#include <
ThreeDeePolySpace.h
>
18
19
/* ========================================================================== */
20
21
ThreeDeePolySpace::ThreeDeePolySpace
(
int
max_power[3],
int
_point_num,
unsigned
char
_parity[3])
22
{
23
int
odd, even;
24
25
// Check later, whether this is really needed;
26
memset(
this
, 0x00,
sizeof
(
ThreeDeePolySpace
));
27
28
// Start off "1"; the actual calculation is below;
29
dim
= 1;
30
31
// Figure out overall dimension;
32
for
(
int
ik=0; ik<3; ik++)
33
{
34
_max_power
[ik] = max_power[ik];
35
36
parity
[ik] = _parity ? _parity[ik] :
_BOTH_
;
37
38
// Figure out actual number of degrees of freedom;
39
degrees_of_freedom
[ik] = 0;
40
odd = even = max_power[ik]/2;
41
if
(max_power[ik]%2) even++;
42
if
(
parity
[ik] &
_ODD_
)
degrees_of_freedom
[ik] += odd;
43
if
(
parity
[ik] &
_EVEN_
)
degrees_of_freedom
[ik] += even;
44
45
dim
*=
degrees_of_freedom
[ik];
46
}
/*for*/
47
48
// Allocate memory for basis and derivatives;
49
basis
=
new
ThreeDeePolynomial
* [
dim
];
50
for
(
int
ik=0; ik<
dim
; ik++)
51
basis
[ik] =
new
ThreeDeePolynomial
(
this
);
52
53
dbasis
=
new
ThreeDeePolynomial
** [
dim
];
54
for
(
int
ii=0; ii<
dim
; ii++)
55
{
56
dbasis
[ii] =
new
ThreeDeePolynomial
* [3];
57
58
for
(
int
ik=0; ik<3; ik++)
59
dbasis
[ii][ik] =
new
ThreeDeePolynomial
(
this
);
60
}
/*for*/
61
62
// Working space;
63
buffer
=
new
ThreeDeePolynomial
(
this
);
64
65
// Allocate 3D points;
66
point_num
= _point_num;
67
points
=
new
ThreeDeePolyPoint
[
point_num
];
68
69
// A reasonable default for weight, please;
70
for
(
int
ik=0; ik<
point_num
; ik++)
71
points
[ik].weight = 1.;
72
}
/* ThreeDeePolySpace::ThreeDeePolySpace */
73
74
/* ========================================================================== */
75
/* Does not take into account possibility that some of the directions may */
76
/* have too few points; fix later; */
77
78
int
ThreeDeePolySpace::getNDF
()
79
{
80
return
point_num
-
dim
;
81
}
/* ThreeDeePolySpace::getNDF */
82
83
/* ========================================================================== */
84
85
//
86
// -> do not bother to create operators; just convert functions to methods;
87
// since at least few of these are logically related to ThreeDeePolySpace rather
88
// than ThreeDeePolynomial class, put them all into ThreeDeePolySpace;
89
//
90
91
double
ThreeDeePolySpace::polyProduct
(
ThreeDeePolynomial
*p1,
ThreeDeePolynomial
*p2)
92
{
93
double
ret = 0.0;
94
95
for
(
int
pt=0; pt<
point_num
; pt++)
96
{
97
ThreeDeePolyPoint
*
point
=
points
+ pt;
98
99
assert(0);
100
//@@@ ret += point->weight*p1->value(point->xx)*p2->value(point->xx);
101
}
/*for*/
102
103
return
ret;
104
}
/* ThreeDeePolySpace::polyProduct */
105
106
/* -------------------------------------------------------------------------- */
107
108
double
ThreeDeePolySpace::polyProjection
(
ThreeDeePolynomial
*
poly
)
109
{
110
double
ret = 0.0;
111
112
if
(poly->
off
)
return
0.0;
113
114
for
(
int
pt=0; pt<
point_num
; pt++)
115
{
116
ThreeDeePolyPoint
*
point
=
points
+ pt;
117
118
assert(0);
119
//@@@ ret += point->weight*poly->value(point->xx)*point->f;
120
}
/*for*/
121
122
return
ret;
123
}
/* ThreeDeePolySpace::polyProjection */
124
125
/* -------------------------------------------------------------------------- */
126
127
void
ThreeDeePolySpace::polyCopy
(
ThreeDeePolynomial
*dest,
ThreeDeePolynomial
*source)
128
{
129
int
ix, iy, iz;
130
131
for
(ix=0; ix<
_max_power
[
_X_
]; ix++)
132
{
133
if
(!
PARITY_CHECK
(
this
,
_X_
, ix))
continue
;
134
135
for
(iy=0; iy<_max_power[
_Y_
]; iy++)
136
{
137
if
(!
PARITY_CHECK
(
this
,
_Y_
, iy))
continue
;
138
139
for
(iz=0; iz<_max_power[
_Z_
]; iz++)
140
{
141
if
(!
PARITY_CHECK
(
this
,
_Z_
, iz))
continue
;
142
143
dest->
cff
[ix][iy][iz] = source->
cff
[ix][iy][iz];
144
}
/*for*/
145
}
/*for*/
146
}
/*for*/
147
}
/* ThreeDeePolySpace::polyCopy */
148
149
/* -------------------------------------------------------------------------- */
150
151
void
ThreeDeePolySpace::buildOrthogonalPolynomials
()
152
{
153
// Do I actually need this "off_counter"?;
154
int
id
= 0, off_counter = 0;
155
156
// Start with 1, x, x^2, ...;
157
for
(
int
ix=0; ix<
_max_power
[
_X_
]; ix++)
158
for
(
int
iy=0; iy<_max_power[
_Y_
]; iy++)
159
for
(
int
iz=0; iz<_max_power[
_Z_
]; iz++)
160
{
161
if
(!
PARITY_CHECK
(
this
,
_X_
, ix) ||
162
!
PARITY_CHECK
(
this
,
_Y_
, iy) ||
163
!
PARITY_CHECK
(
this
,
_Z_
, iz))
164
continue
;
165
166
{
167
ThreeDeePolynomial
*
poly
=
basis
[
id
++];
168
169
for
(
int
qx=0; qx<_max_power[
_X_
]; qx++)
170
for
(
int
qy=0; qy<_max_power[
_Y_
]; qy++)
171
for
(
int
qz=0; qz<_max_power[
_Z_
]; qz++)
172
poly->
cff
[qx][qy][qz] = 0.;
173
174
poly->
cff
[ix][iy][iz] = 1.;
175
}
176
}
/*for..for*/
177
178
for
(
int
ii=0; ii<
dim
; ii++)
179
{
180
for
(
int
ik=0; ik<ii; ik++)
181
{
182
double
projection =
polyProduct
(
basis
[ii],
basis
[ik]);
183
184
polyCopy
(
buffer
,
basis
[ik]);
185
buffer
->multiply(-projection);
186
basis
[ii]->
increment
(
buffer
);
187
}
/*for*/
188
189
if
(
basis
[ii]->normalize()) off_counter++;
190
}
/*for*/
191
}
/* ThreeDeePolySpace::buildOrthogonalPolynomials */
192
193
/* ========================================================================== */
194
195
int
ThreeDeePolySpace::buildBasisGradients
()
196
{
197
for
(
int
ii=0; ii<
dim
; ii++)
198
if
(
basis
[ii]->calculateGradient(
dbasis
[ii]))
199
return
-1;
200
201
return
0;
202
}
/* ThreeDeePolySpace::buildBasisGradients */
203
204
/* ========================================================================== */
205
206
//
207
// -> yes, at least here I should use ThreeDeePolySpace-based routine (not to
208
// blindly reuse fit->space pointer);
209
//
210
211
void
ThreeDeePolySpace::calculateFittingPolynomial
(
ThreeDeePolynomial
*fit)
212
{
213
for
(
int
ii=0; ii<
dim
; ii++)
214
fit->
linear
[ii] =
polyProjection
(
basis
[ii]);
215
216
fit->
convertLinearToCff
();
217
}
/* ThreeDeePolySpace::calculateFittingPolynomial */
218
219
/* ========================================================================== */
220
221
//
222
// -> yes, as any point-coupled routine this one should be ThreeDeePolySpace-related;
223
//
224
225
double
ThreeDeePolySpace::getPolyFitChiSquare
(
ThreeDeePolynomial
*fit)
226
{
227
double
ret = 0.0;
228
229
for
(
int
pt=0; pt<
point_num
; pt++)
230
{
231
ThreeDeePolyPoint
*
point
=
points
+ pt;
232
233
assert(0);
234
//@@@ ret += point->weight*SQR(fit->value(point->xx) - point->f);
235
}
/*for*/
236
237
return
ret;
238
}
/* ThreeDeePolySpace::getPolyFitChiSquare */
239
240
/* ========================================================================== */
241
/* This calculation assumes that chi^2 is correct; in this case errors on */
242
/* 'linear' coefficients are all equal '1.' and below calculation is Ok; */
243
244
double
ThreeDeePolySpace::getNaivePolyFitError
(
double
xx[3])
245
{
246
double
err
= 0.0;
247
248
for
(
int
ii=0; ii<
dim
; ii++)
249
err +=
SQR
(
basis
[ii]->
value
(xx));
250
251
return
sqrt(err);
252
}
/* ThreeDeePolySpace::getNaivePolyFitError */
253
254
/* ========================================================================== */
255
/* This calculation takes chi^2 into account and renormalizes naive error */
256
/* estimate by sqrt(chi^2/ndf); this way error estimate will not depend on the*/
257
/* weight scaling factor; so for instance if errors in all points are more or */
258
/* less the same, they can be safely set to 1. and this function will provide */
259
/* best guess error estimate; */
260
261
//
262
// -> not sure this has ever been checked;
263
//
264
265
double
ThreeDeePolySpace::getRealisticPolyFitError
(
ThreeDeePolynomial
*fit,
double
xx[3])
266
{
267
int
ndf =
getNDF
();
268
double
err
= 0.0, chi2 =
getPolyFitChiSquare
(fit);
269
270
for
(
int
ii=0; ii<
dim
; ii++)
271
err +=
SQR
(
basis
[ii]->
value
(xx));
272
273
return
sqrt(err*chi2/ndf);
274
}
/* ThreeDeePolySpace::getRealisticPolyFitError */
275
276
/* ========================================================================== */
EicRoot
blob
master
eic
ayk
ThreeDeePolySpace.cxx
Built by
Jin Huang
. updated:
Mon Jan 22 2024 12:43:33
using
1.8.2 with
EIC GitHub integration