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