mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
fitGaussian.hpp
Go to the documentation of this file.
1 /** \file fitGaussian.hpp
2  * \author Jared R. Males
3  * \brief Tools for fitting Gaussians to data.
4  * \ingroup fitting_files
5  *
6  */
7 
8 //***********************************************************************//
9 // Copyright 2015, 2016, 2017 Jared R. Males (jaredmales@gmail.com)
10 //
11 // This file is part of mxlib.
12 //
13 // mxlib is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
17 //
18 // mxlib is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU General Public License for more details.
22 //
23 // You should have received a copy of the GNU General Public License
24 // along with mxlib. If not, see <http://www.gnu.org/licenses/>.
25 //***********************************************************************//
26 
27 #ifndef fitGaussian_hpp
28 #define fitGaussian_hpp
29 
30 #include "array2FitGaussian1D.hpp"
31 #include "array2FitGaussian2D.hpp"
32 
33 #include "../../mxError.hpp"
34 #include "levmarInterface.hpp"
35 #include "../func/gaussian.hpp"
36 #include "../constants.hpp"
37 
38 #include "../../improc/eigenImage.hpp"
39 
40 namespace mx
41 {
42 namespace math
43 {
44 namespace fit
45 {
46 
47 /** \defgroup gaussian_peak_fit Gaussians
48  * \brief Fitting Gaussians to data.
49  *
50  * The Gaussian function is fit to data.
51  *
52  * \ingroup peak_fit
53  */
54 
55 
56 //forward
57 template<typename _realT>
58 struct gaussian1D_fitter;
59 
60 ///\ref levmarInterface fitter structure for the symmetric Gaussian.
61 /** \ingroup gaussian_peak_fit
62  *
63  */
64 template<typename _realT>
66 {
67  typedef _realT realT;
68 
69  static const int nparams = 4;
70 
71  static void func(realT *p, realT *hx, int m, int n, void *adata)
72  {
74 
75  realT G0 = arr->G0(p);
76  realT G = arr->G(p);
77  realT x0 = arr->x0(p);
78  realT sigma = arr->sigma(p);
79 
80  if(arr->m_mask)
81  {
82  if(arr->m_coords)
83  {
84  for(int i=0; i<arr->m_nx; ++i)
85  {
86  if(arr->m_mask[i] == 0) continue;
87  hx[i] = func::gaussian<realT>(arr->m_coords[i], G0, G, x0, sigma) - arr->m_data[i];
88  }
89  }
90  else
91  {
92  for(int i=0; i<arr->m_nx; ++i)
93  {
94  if(arr->m_mask[i] == 0) continue;
95  hx[i] = func::gaussian<realT>(i, G0, G, x0, sigma) - arr->m_data[i];
96  }
97  }
98  }
99  else
100  {
101  if(arr->m_coords)
102  {
103  for(int i=0; i<arr->m_nx; ++i)
104  {
105  hx[i] = func::gaussian<realT>(arr->m_coords[i], G0, G, x0, sigma) - arr->m_data[i];
106  }
107  }
108  else
109  {
110  for(int i=0; i<arr->m_nx; ++i)
111  {
112  hx[i] = func::gaussian<realT>(i, G0, G, x0, sigma) - arr->m_data[i];
113  }
114  }
115  }
116  }
117 
118 };
119 
120 extern template struct gaussian1D_fitter<float>;
121 extern template struct gaussian1D_fitter<double>;
122 
123 
124 ///Class to manage fitting a 1D Gaussian to data via the \ref levmarInterface
125 /** Fits the following function to the data:
126  * \f$ G(x) = G_0 + G\exp[-(0.5/\sigma^2)((x-x_0)^2)]\f$
127  *
128  * Can use a vector of x-coordinates, or use the array index as the position corresponding to each y-value.
129  * A mask can be provided, where any 0 entries cause that position to be ignored.
130  *
131  * Any of the parameters can be fixed, and not included in the fit.
132  *
133  * \code
134  *
135  * \endcode
136  *
137  *
138  * \tparam fitterT a type meeting the above requirements.
139  *
140  * \ingroup gaussian_peak_fit
141  *
142  */
143 //template<typename fitterT>
144 template<typename _realT>
146 {
147 
148 public:
149 
150  typedef _realT realT;
152 
153 
154 protected:
155 
157 
158  void initialize()
159  {
160  this->allocate_params(arr.nparams());
161  this->adata = &arr;
162  }
163 
164 public:
165 
166  fitGaussian1D()
167  {
168  this->initialize();
169  }
170 
171  ~fitGaussian1D()
172  {
173  }
174 
175  /// Set whether each parameter is fixed.
176  /** Sets the parameter indices appropriately.
177  */
178  void setFixed( bool G0, ///< [in] if true, then G0 will be not be part of the fit
179  bool G, ///< [in] if true, then G will be not be part of the fit
180  bool x0, ///< [in] if true, then x0 will be not be part of the fit
181  bool sigma ///< [in] if true, then sigma will be not be part of the fit
182  )
183  {
184  arr.setFixed(G0, G, x0, sigma);
185  this->allocate_params(arr.nparams());
186  }
187 
188  ///Set the initial guess for a symmetric Gaussian.
189  /** Also works for the general case, setting the same width in both directions.
190  */
191  void setGuess( realT G0, ///< [in] the constant background level
192  realT G, ///< [in] the peak scaling
193  realT x0, ///< [in] the center x-coordinate
194  realT sigma ///< [in] the width parameter
195  )
196  {
197  arr.G0(this->p,G0);
198  arr.G(this->p,G);
199  arr.x0(this->p,x0);
200  arr.sigma(this->p,sigma);
201  }
202 
203  ///Set the data aray.
204  void setArray( realT *data,
205  int nx
206  )
207  {
208  arr.m_data = data;
209  arr.m_nx = nx;
210 
211  this->n = nx;
212  }
213 
214  ///Set the data aray.
215  void setArray( realT *data,
216  realT *coords,
217  int nx
218  )
219  {
220  arr.m_data = data;
221  arr.m_coords = coords;
222  arr.m_nx = nx;
223 
224  this->n = nx;
225  }
226 
227  ///Do the fit.
228  int fit()
229  {
230  fitterT fitter;
231 
233  }
234 
235  ///Get the current value of G0, the constant.
236  /**
237  * \returns the current value of G0, which is p[0].
238  */
239  realT G0()
240  {
241  return arr.G0( this->p );
242  }
243 
244  ///Get the peak scaling.
245  realT G()
246  {
247  return arr.G( this->p );
248  }
249 
250  ///Get the center x-coordinate
251  realT x0()
252  {
253  return arr.x0( this->p );
254  }
255 
256  ///Return sigma
257  /**
258  */
259  realT sigma()
260  {
261  return arr.sigma( this->p );
262  }
263 
264 };
265 
266 extern template class fitGaussian1D<float>;
267 extern template class fitGaussian1D<double>;
268 
269 
270 ///Alias for the fitGaussian1D type fitting the gaussian.
271 /** \ingroup gaussian_peak_fit
272  */
273 //template<typename realT>
274 //using fitGaussian1D = mx::math::fit::fitGaussian1D<mx::math::fit::gaussian1D_fitter<realT>>;
275 
276 
277 
278 
279 
280 
281 
282 
283 
284 
285 
286 
287 //forward
288 template<typename _realT>
289 struct gaussian2D_sym_fitter;
290 
291 //forward
292 template<typename _realT>
293 struct gaussian2D_gen_fitter;
294 
295 template<typename _realT>
296 struct gaussian2D_gen_fitter_bgfixed;
297 
298 ///Class to manage fitting a 2D Gaussian to data via the \ref levmarInterface
299 /** Can fit either the symmetric Gaussian, or the rotated asymmetric Gaussian. Individual parameters can be fixed,
300  * except in the asymmetric case \f$\sigma_x, \sigma_y, \theta\f$ must currently be fixed together.
301  *
302  * In addition to the requirements on fitterT specified by \ref levmarInterface
303  * this class also requires the following in fitterT
304  * \code
305  * static const int nparams = 7; //where the number 7 is replaced by the number of parameters that fitterT expects to fit.
306  *
307  * void paramNormalizer( array2FitGaussian2D * arr,
308  * realT *,
309  * int); //A function which converts from input parameters to fitting parameters. May do nothing.
310  *
311  * \endcode
312  *
313  *
314  * \tparam fitterT a type meeting the above requirements.
315  *
316  * \ingroup gaussian_peak_fit
317  *
318  * \test Scenario: Verify direction and accuracy of various image shifts \ref tests_improc_imageTransforms_imageShift "[test doc]"
319  *
320  */
321 template<typename fitterT>
323 {
324 
325 public:
326 
327  typedef typename fitterT::realT realT;
328 
329  array2FitGaussian2D<realT> arr; ///< Data array to pass to the levmar library. Contains the actual data plus the parameters if fixed.
330 
331  void initialize()
332  {
333  if(fitterT::maxNparams == 5)
334  {
335  arr.setSymmetric();
336  }
337  else
338  {
339  arr.setGeneral();
340  }
341  this->allocate_params(arr.nparams());
342  this->adata = &arr;
343  }
344 
345  fitGaussian2D()
346  {
347  initialize();
348  }
349 
350  ~fitGaussian2D()
351  {
352  }
353 
354  /// Set whether each parameter is fixed.
355  /** Sets the parameter indices appropriately.
356  */
357  void setFixed( bool G0, ///< [in] if true, then G0 will be not be part of the fit
358  bool G, ///< [in] if true, then G will be not be part of the fit
359  bool x0, ///< [in] if true, then x0 will be not be part of the fit
360  bool y0, ///< [in] if true, then y0 will be not be part of the fit
361  bool sigma_x, ///< [in] if true, then sigma_x will be not be part of the fit
362  bool sigma_y, ///< [in] if true, then sigma_y will be not be part of the fit
363  bool theta ///< [in] if true, then theta will be not be part of the fit
364  )
365  {
366  arr.setFixed(G0, G, x0, y0, sigma_x, sigma_y, theta);
367  this->allocate_params(arr.nparams());
368  }
369 
370  /// Set whether each parameter is fixed.
371  /** Sets the parameter indices appropriately.
372  */
373  void setFixed( bool G0, ///< [in] if true, then G0 will be not be part of the fit
374  bool G, ///< [in] if true, then G will be not be part of the fit
375  bool x0, ///< [in] if true, then x0 will be not be part of the fit
376  bool y0, ///< [in] if true, then y0 will be not be part of the fit
377  bool sigma ///< [in] if true, then sigma will be not be part of the fit
378  )
379  {
380  arr.setFixed(G0, G, x0, y0, sigma, sigma, sigma);
381  this->allocate_params(arr.nparams());
382  }
383 
384  ///Set the initial guess for a symmetric Gaussian.
385  /** Also works for the general case, setting the same width in both directions.
386  */
387  void setGuess( realT G0, ///< [in] the constant background level
388  realT G, ///< [in] the peak scaling
389  realT x0, ///< [in] the center x-coordinate
390  realT y0, ///< [in] the center y-coordinate
391  realT sigma ///< [in] the width parameter
392  )
393  {
394  arr.G0(this->p,G0);
395  arr.G(this->p,G);
396  arr.x0(this->p,x0);
397  arr.y0(this->p,y0);
398  arr.sigma(this->p,sigma);
399 
400 
401  }
402 
403  ///Set the initial guess for the general Gaussian.
404  void setGuess( realT G0, ///< [in] the constant background level
405  realT G, ///< [in] the peak scaling
406  realT x0, ///< [in] the center x-coordinate
407  realT y0, ///< [in] the center y-coordinate
408  realT sigma_x, ///< [in] the width parameter in the rotated x-direction (the long axis)
409  realT sigma_y, ///< [in] the width parameter in the rotated y-direction
410  realT theta ///< [in] the angle of the long axis (always sigma_x)
411  )
412  {
413 
414  arr.G0(this->p,G0);
415  arr.G(this->p,G);
416  arr.x0(this->p,x0);
417  arr.y0(this->p,y0);
418  arr.sigma_x(this->p,sigma_x);
419  arr.sigma_y(this->p,sigma_y);
420  arr.theta(this->p,theta);
421  }
422 
423  ///Set the data aray.
424  void setArray( realT *data, ///< [in] The 2D array of data to fit.
425  int nx, ///< [in] the x size of the data
426  int ny ///< [in] the y size of the data
427  )
428  {
429  arr.data = data;
430  arr.nx = nx;
431  arr.ny = ny;
432  arr.mask = nullptr;
433  this->n = nx*ny;
434 
435  }
436 
437  ///Set the data aray, with a mask.
438  void setArray( realT *data, ///< [in] The 2D array of data to fit.
439  int nx, ///< [in] the x size of the data
440  int ny, ///< [in] the y size of the data
441  realT *mask ///< [in] Array of same size as data. Any 0 pixels in this array will be excluded from the fit.
442  )
443  {
444  arr.data = data;
445  arr.nx = nx;
446  arr.ny = ny;
447  arr.mask = mask;
448 
449  this->n = 0;
450  int idx_mat;
451  for(int j=0;j<nx; ++j)
452  {
453  for(int i=0;i<ny; ++i)
454  {
455  idx_mat = i+j*nx;
456 
457  this->n += arr.mask[idx_mat];
458  }
459  }
460 
461  }
462 
463  ///Do the fit.
464  int fit()
465  {
466  fitterT fitter;
467  fitter.paramNormalizer(&arr, this->p, 1);
468 
470 
471  fitter.paramNormalizer(&arr, this->p, -1);
472  fitter.paramNormalizer(&arr, this->init_p, -1); //The normalized version is stored, so fix it before possible output.
473 
474  return 0;
475  }
476 
477  ///Get the current value of G0, the constant.
478  /**
479  * \returns the current value of G0.
480  */
481  realT G0()
482  {
483  return arr.G0(this->p);
484  }
485 
486  ///Get the peak scaling.
487  realT G()
488  {
489  return arr.G(this->p);
490  }
491 
492  ///Get the center x-coordinate
493  realT x0()
494  {
495  return arr.x0(this->p);
496  }
497 
498  ///Get the center y-coordinate
499  realT y0()
500  {
501  return arr.y0(this->p);
502  }
503 
504  ///Return the width parameter
505  /** As described for the symmetric Gaussian.
506  *
507  * For the general Gaussian, this returns \f$ \sigma = \sqrt{ \sigma_x^2 + \sigma_y^2} \f$.
508  */
509  realT sigma()
510  {
511  return arr.sigma(this->p);
512  }
513 
514  ///Return the full-width at half maximum
515  /** This is a simple scaling of the sigma() result
516  */
517  realT fwhm()
518  {
519  return func::sigma2fwhm(arr.sigma(this->p));
520  }
521 
522  ///Return the width parameter on the long axis.
523  realT sigma_x()
524  {
525  return arr.sigma_x(this->p);
526  }
527 
528  ///Return the width parameter on the short axis.
529  realT sigma_y()
530  {
531  return arr.sigma_y(this->p);
532  }
533 
534  ///Return the orientation of the long axis.
535  realT theta()
536  {
537  return arr.theta(this->p);
538  }
539 
540 };
541 
542 
543 
544 ///\ref levmarInterface fitter structure for the symmetric Gaussian.
545 /** \ingroup gaussian_peak_fit
546  *
547  * \test Scenario: Verify direction and accuracy of various image shifts \ref tests_improc_imageTransforms_imageShift "[test doc]"
548  */
549 template<typename _realT>
551 {
552  typedef _realT realT;
553 
554  static const int maxNparams = 5;
555 
556  static void func(realT *p, realT *hx, int m, int n, void *adata)
557  {
558  array2Fit<realT> * arr = (array2Fit<realT> *) adata;
559 
560  size_t idx_mat, idx_dat;
561 
562  idx_dat = 0;
563 
564  for(int j=0;j<arr->ny; j++)
565  {
566  for(int i=0;i<arr->nx;i++)
567  {
568  idx_mat = i+j*arr->nx;
569 
570  hx[idx_dat] = func::gaussian2D<realT>(i,j,p[0],p[1], p[2], p[3], p[4]) - arr->data[idx_mat];
571 
572  idx_dat++;
573  }
574  }
575 
576  }
577 
578  ///Does nothing in this case.
580  realT * p,
581  int dir
582  )
583  {
584  return;
585  }
586 };
587 
588 ///\ref levmarInterface fitter structure for the general elliptical Gaussian.
589 /** \ingroup gaussian_peak_fit
590  *
591  */
592 template<typename _realT>
594 {
595  typedef _realT realT;
596 
597  static const int maxNparams = 7;
598 
599  static void func(realT *p, realT *hx, int m, int n, void *adata)
600  {
602 
603  size_t idx_mat, idx_dat;
604 
605  realT G0 = arr->G0(p); //0
606  realT G = arr->G(p); //1
607  realT x0 = arr->x0(p); //2
608  realT y0 = arr->y0(p); //3
609  realT a = arr->a(p); //4
610  realT b = arr->b(p); //5
611  realT c = arr->c(p); //6
612 
613  //Check for positive-definiteness of {{a b}{b c}}
614  if( a*c - b*b <= 0 || a <= 0 || c <= 0 || a+c <= 2*fabs(b))
615  {
616  idx_dat = 0;
617  //If it's not positive-definite, then we just fill in with the value of the image itself.
618  if(arr->mask == nullptr)
619  {
620  for(int j=0;j<arr->ny; ++j)
621  {
622  for(int i=0;i<arr->ny; ++i)
623  {
624  idx_mat = i+j*arr->nx;
625  hx[idx_dat] = arr->data[idx_mat];
626  ++idx_dat;
627  }
628  }
629  }
630  else
631  {
632  for(int j=0;j<arr->ny; ++j)
633  {
634  for(int i=0;i<arr->ny; ++i)
635  {
636  idx_mat = i+j*arr->nx;
637  if(arr->mask[idx_mat]==0) continue;
638  hx[idx_dat] = arr->data[idx_mat];
639  ++idx_dat;
640  }
641  }
642  }
643  return;
644  }
645 
646 
647  //If positive-definite, now actually calculate
648  idx_dat = 0;
649 
650  if(arr->mask == nullptr)
651  {
652  for(int j=0;j<arr->ny; ++j)
653  {
654  for(int i=0;i<arr->nx; ++i)
655  {
656  idx_mat = i+j*arr->nx;
657 
658  hx[idx_dat] = func::gaussian2D<realT>(i,j, G0, G, x0, y0, a, b, c) - arr->data[idx_mat];
659 
660  ++idx_dat;
661  }
662  }
663  }
664  else
665  {
666  for(int j=0;j<arr->ny; ++j)
667  {
668  for(int i=0;i<arr->nx; ++i)
669  {
670  idx_mat = i+j*arr->nx;
671 
672  if(arr->mask[idx_mat] == 0)
673  {
674  continue;
675  }
676  else
677  {
678  hx[idx_dat] = func::gaussian2D<realT>(i,j, G0, G, x0, y0, a, b, c) - arr->data[idx_mat];
679 
680  ++idx_dat;
681  }
682  }
683  }
684  }
685 
686 
687  }
688 
689  void paramNormalizer( array2FitGaussian2D<realT> * arr,
690  realT * p,
691  int dir
692  )
693  {
694  //Prepare for fit
695  if(dir == 1)
696  {
697  realT na, nb, nc;
698  realT sx = arr->sigma_x(p);
699  realT sy = arr->sigma_y(p);
700  realT th = arr->theta(p);
701 
702  func::gaussian2D_rot2gen(na,nb,nc, sx, sy, th);
703  arr->a(p, na);
704  arr->b(p, nb);
705  arr->c(p, nc);
706  return;
707  }
708 
709  //Convert after fit
710  if(dir == -1)
711  {
712  realT sx, sy, th;
713  realT na = arr->a(p);
714  realT nb = arr->b(p);
715  realT nc = arr->c(p);
716  func::gaussian2D_gen2rot(sx, sy, th, na, nb, nc);
717 
718  arr->sigma_x(p, sx);
719  arr->sigma_y(p, sy);
720  arr->theta(p, th);
721  return;
722  }
723  }
724 };
725 
730 
731 ///Alias for the fitGaussian2D type fitting the symmetric gaussian.
732 /** \ingroup gaussian_peak_fit
733  */
734 template<typename realT>
736 
737 ///Alias for the fitGaussian2D type fitting the general elliptical gaussian.
738 /** \ingroup gaussian_peak_fit
739  */
740 template<typename realT>
742 
743 
744 ///Form an estimate of the parameters of an elliptical Gaussian from a 2D image.
745 /** Note that this assumes that there is no constant value (i.e. it is zero-ed).
746  *
747  * \ingroup gaussian_peak_fit
748  */
749 template<typename realT>
750 int guessGauss2D_ang( realT & Ag, ///< [out] estimate of the peak
751  realT & xg, ///< [out] estimate of the x-coordinate of the peak
752  realT & yg, ///< [out] estimate of the y-coordinate of the peak
753  realT & xFWHM, ///< [out] estimate of the x-FWHM
754  realT & yFWHM, ///< [out] estimate of the y-FWHM
755  realT & angG, ///< [out] estimate of the angle of the ellipse
756  mx::improc::eigenImage<realT> & im, ///< [in] the image with an elliptical gaussian
757  realT maxWidth, ///< [in] the width of the box to search for the maximum
758  realT widthWidth, ///< [in] the radius of the circle to search for the widths
759  realT nAngs, ///< [in] the number of angles at which to search for the widths
760  realT xg0, ///< [in] an initial guess at the x-coordinate of the peak
761  realT yg0 ///< [in] an initial guess at the y-coordinate of the peak
762  )
763 {
764  xg = xg0;
765  yg = yg0;
766  Ag = im( (int) xg, (int) yg);
767  for(int i =0; i< 2*maxWidth+1; ++i)
768  {
769  for(int j=0; j< 2*maxWidth+1; ++j)
770  {
771  if( im( (int)(xg0 - maxWidth + i), (int) (yg0 - maxWidth + j)) > Ag )
772  {
773  Ag = im( (int) (xg0 - maxWidth + i), (int) (yg0 - maxWidth + j));
774  xg = xg0 - maxWidth + i;
775  yg = yg0 - maxWidth + j;
776  }
777  }
778  }
779 
780  realT dAng = math::two_pi<realT>()/nAngs;
781  //std::vector<realT> dist(nAngs);
782 
783  realT c, s;
784 
785  realT maxD = 0;
786  int maxDidx = 0;
787  realT minD = widthWidth;
788  int minDidx = 0;
789 
790  for(int i=0; i < nAngs; ++i)
791  {
792  c = cos(i*dAng);
793  s = sin(i*dAng);
794 
795  for(int j=0; j < widthWidth; ++j)
796  {
797  if( im( (int)(xg + j*c), (int)(yg + j*s)) <= 0.5*Ag )
798  {
799  //dist[i] = j;
800 
801  if(j > maxD)
802  {
803  maxD = j;
804  maxDidx = i;
805  }
806 
807  if(j < minD)
808  {
809  minD = j;
810  minDidx = i;
811  }
812  break;
813  }
814  }
815  }
816 
817  //Take minang and move it by 90 degrees
818  realT minang = fmod(minDidx * dAng - 0.5*math::pi<realT>(), math::pi<realT>());
819  if(minang < 0) minang = fmod(minang + math::two_pi<realT>(), math::pi<realT>());
820 
821  realT maxang = fmod(maxDidx * dAng, math::pi<realT>());
822 
823  //Now average
824  angG = 0.5*(minang + maxang);
825 
826  xFWHM = 2*maxD;
827  yFWHM = 2*minD;
828 
829  return 0; ///\returns 0 if successful
830 }
831 
832 extern template
833 int guessGauss2D_ang<float>( float & Ag,
834  float & xg,
835  float & yg,
836  float & xFWHM,
837  float & yFWHM,
838  float & angG,
840  float maxWidth,
841  float widthWidth,
842  float nAngs,
843  float xg0,
844  float yg0
845  );
846 
847 extern template
848 int guessGauss2D_ang<double>( double & Ag,
849  double & xg,
850  double & yg,
851  double & xFWHM,
852  double & yFWHM,
853  double & angG,
855  double maxWidth,
856  double widthWidth,
857  double nAngs,
858  double xg0,
859  double yg0
860  );
861 
862 } //namespace fit
863 } //namespace math
864 
865 } //namespace mx
866 
867 #endif //fitGaussian_hpp
868 
Wrapper for a native array to pass to levmarInterface, with 1D Gaussian details.
Wrapper for a native array to pass to levmarInterface, with 2D Gaussian details.
Class to manage fitting a 1D Gaussian to data via the levmarInterface.
realT G()
Get the peak scaling.
realT sigma()
Return sigma.
void setArray(realT *data, realT *coords, int nx)
Set the data aray.
realT G0()
Get the current value of G0, the constant.
void setGuess(realT G0, realT G, realT x0, realT sigma)
Set the initial guess for a symmetric Gaussian.
void setFixed(bool G0, bool G, bool x0, bool sigma)
Set whether each parameter is fixed.
realT x0()
Get the center x-coordinate.
void setArray(realT *data, int nx)
Set the data aray.
Class to manage fitting a 2D Gaussian to data via the levmarInterface.
realT x0()
Get the center x-coordinate.
void setGuess(realT G0, realT G, realT x0, realT y0, realT sigma)
Set the initial guess for a symmetric Gaussian.
void setFixed(bool G0, bool G, bool x0, bool y0, bool sigma_x, bool sigma_y, bool theta)
Set whether each parameter is fixed.
realT theta()
Return the orientation of the long axis.
realT y0()
Get the center y-coordinate.
array2FitGaussian2D< realT > arr
Data array to pass to the levmar library. Contains the actual data plus the parameters if fixed.
realT sigma()
Return the width parameter.
void setArray(realT *data, int nx, int ny)
Set the data aray.
realT G0()
Get the current value of G0, the constant.
void setGuess(realT G0, realT G, realT x0, realT y0, realT sigma_x, realT sigma_y, realT theta)
Set the initial guess for the general Gaussian.
realT fwhm()
Return the full-width at half maximum.
realT sigma_y()
Return the width parameter on the short axis.
void setFixed(bool G0, bool G, bool x0, bool y0, bool sigma)
Set whether each parameter is fixed.
realT G()
Get the peak scaling.
realT sigma_x()
Return the width parameter on the long axis.
void setArray(realT *data, int nx, int ny, realT *mask)
Set the data aray, with a mask.
A templatized interface to the levmar package.
constexpr units::realT G()
Newton's Gravitational Constant.
Definition: constants.hpp:51
constexpr units::realT c()
The speed of light.
Definition: constants.hpp:60
constexpr units::realT sigma()
Stefan-Boltzmann Constant.
Definition: constants.hpp:82
Eigen::Array< scalarT, -1, -1 > eigenImage
Definition of the eigenImage type, which is an alias for Eigen::Array.
Definition: eigenImage.hpp:44
int guessGauss2D_ang(realT &Ag, realT &xg, realT &yg, realT &xFWHM, realT &yFWHM, realT &angG, mx::improc::eigenImage< realT > &im, realT maxWidth, realT widthWidth, realT nAngs, realT xg0, realT yg0)
Form an estimate of the parameters of an elliptical Gaussian from a 2D image.
floatT sigma2fwhm(floatT sig)
Convert from Gaussian width parameter to FWHM.
Definition: gaussian.hpp:80
void gaussian2D_gen2rot(realT &sigma_x, realT &sigma_y, realT &theta, const realT a, const realT b, const realT c)
Convert from (a,b,c) to ( , , ) for the elliptical Gaussian.
Definition: gaussian.hpp:245
void gaussian2D_rot2gen(realT &a, realT &b, realT &c, const realT sigma_x, const realT sigma_y, const realT theta)
Convert from ( , , ) to (a,b,c) for the elliptical Gaussian.
Definition: gaussian.hpp:328
A c++ interface to the templatized levmar minimization routines..
The mxlib c++ namespace.
Definition: mxError.hpp:107
Wrapper for a native array to pass to levmarInterface, with !D Gaussian details.
size_t m_nx
X dimension of the array.
realT * m_mask
Pointer to the (optional) mask array. Any 0 pixels are excluded from the fit.
realT * m_coords
Pointer to the array of x values (optional)
realT * m_data
///< Pointer to the array of y values
void setFixed(bool G0, bool G, bool x0, bool sigma)
Set whether each parameter is fixed.
Wrapper for a native array to pass to levmarInterface, with 2D Gaussian details.
size_t ny
Y dimension of the array.
void setFixed(bool G0, bool G, bool x0, bool y0, bool sigma_x, bool sigma_y, bool theta)
Set whether each parameter is fixed.
size_t nx
X dimension of the array.
realT * data
Pointer to the array.
realT * mask
Pointer to the (optional) mask array. Any 0 pixels are excluded from the fit.
Wrapper for a native array to pass to levmarInterface.
size_t ny
X dimension of the array.
size_t nx
Pointer to the array.
levmarInterface fitter structure for the symmetric Gaussian.
Definition: fitGaussian.hpp:66
levmarInterface fitter structure for the general elliptical Gaussian.
Alias for the fitGaussian1D type fitting the gaussian.
void paramNormalizer(array2FitGaussian2D< realT > *arr, realT *p, int dir)
Does nothing in this case.