QXRD  0.11.16
qxrdfitterringellipse.cpp
Go to the documentation of this file.
2 #include "qxrdcenterfinder.h"
3 
4 #include "levmar.h"
5 
6 # ifdef LINSOLVERS_RETAIN_MEMORY
7 # ifdef _MSC_VER
8 # pragma message("LINSOLVERS_RETAIN_MEMORY is not safe in a multithreaded environment and should be turned off!")
9 # else
10 # warning LINSOLVERS_RETAIN_MEMORY is not safe in a multithreaded environment and should be turned off!
11 # endif /* _MSC_VER */
12 # endif /* LINSOLVERS_RETAIN_MEMORY */
13 
14 QxrdFitterRingEllipse::QxrdFitterRingEllipse(QxrdCenterFinder *cf, int ringIndex, double x0, double y0) :
15  QxrdFitter(cf),
16  m_RingIndex(ringIndex),
17  m_X0(x0),
18  m_Y0(y0),
19  m_FittedX(0),
20  m_FittedY(0),
21  m_FittedA(0),
22  m_FittedB(0),
23  m_FittedRot(0)
24 {
25 }
26 
28  QxrdFitter(NULL),
29  m_RingIndex(0),
30  m_X0(0),
31  m_Y0(0),
32  m_FittedX(0),
33  m_FittedY(0),
34  m_FittedA(0),
35  m_FittedB(0),
36  m_FittedRot(0)
37 {
38 }
39 
40 void QxrdFitterRingEllipse::staticEvaluate(double *p, double *hx, int m, int n, void *adata)
41 {
43 
44  if (rf) {
45  rf->evaluate(p,hx,m,n);
46  }
47 }
48 
49 void QxrdFitterRingEllipse::evaluate(double *parm, double *xv, int /*np*/, int nx)
50 {
51  if (m_CenterFinder) {
52  double cx = parm[0];
53  double cy = parm[1];
54  double a = parm[2];
55  double b = parm[3];
56  double az = parm[4];
57 
58  double cosaz = cos(az);
59  double sinaz = sin(az);
60 
61  for (int i=0; i<nx; i++) {
63 
64  double ptaz = atan2(pt.y() - cy, pt.x() - cx) - az;
65 
66  double x = cx + a*cos(ptaz);
67  double y = cy + b*sin(ptaz);
68 
69  double xp = x*cosaz - y*sinaz;
70  double yp = x*sinaz + y*cosaz;
71 
72  double dx = xp - pt.x();
73  double dy = yp - pt.y();
74 
75  xv[i] = sqrt(dx*dx + dy*dy);
76  }
77  }
78 }
79 
81 {
82  int niter = -1;
83 
84  if (m_CenterFinder) {
86  double rsum = 0;
87 
88  for (int i=0; i<npts; i++) {
90 
91  double dx = pt.x() - m_X0;
92  double dy = pt.y() - m_Y0;
93 
94  rsum += sqrt(dx*dx + dy*dy);
95  }
96 
97  double parms[5];
98  double info[LM_INFO_SZ];
99 
100  parms[0] = m_X0;
101  parms[1] = m_Y0;
102  parms[2] = rsum/npts;
103  parms[3] = rsum/npts;
104  parms[4] = 0;
105 
106  niter = dlevmar_dif(QxrdFitterRingEllipse::staticEvaluate,
107  parms, NULL, 5, npts,
108  m_CenterFinder->get_PeakFitIterations(),
109  NULL, info, NULL, NULL, this);
110 
111  if (niter > 0) {
113  m_FittedX = parms[0];
114  m_FittedY = parms[1];
115  m_FittedA = parms[2];
116  m_FittedB = parms[3];
117  m_FittedRot = parms[4];
118  } else {
119  m_Reason = NoResult;
120  }
121  }
122 
123  return niter;
124 }
double y() const
FitResult m_Reason
Definition: qxrdfitter.h:32
int countPowderRingPoints() const
static void staticEvaluate(double *parm, double *xv, int np, int nx, void *adata)
QxrdCenterFinder * m_CenterFinder
Definition: qxrdfitter.h:31
QxrdPowderPoint powderRingPoint(int i) const
double x() const
void evaluate(double *parm, double *xv, int np, int nx)