Line data Source code
1 : /** \file array2FitGaussian1D.hpp
2 : * \author Jared R. Males
3 : * \brief Wrapper for a native array to pass to \ref mx::math::fit::levmarInterface, with 1D Gaussian details.
4 : * \ingroup fitting_files
5 : *
6 : */
7 :
8 : //***********************************************************************//
9 : // Copyright 2022 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 math_fit_array2FitGaussian1D_hpp
28 : #define math_fit_array2FitGaussian1D_hpp
29 :
30 : #include "../../mxlib.hpp"
31 :
32 : namespace mx
33 : {
34 : namespace math
35 : {
36 : namespace fit
37 : {
38 :
39 : /// Wrapper for a native array to pass to \ref levmarInterface, with !D Gaussian details.
40 : /** Supports fixing G0, G, x0, and sigma independently.
41 : * \ingroup gaussian_peak_fit
42 : */
43 : template <typename realT>
44 : struct array2FitGaussian1D
45 : {
46 : realT *m_data{ nullptr }; ///< ///< Pointer to the array of y values
47 : realT *m_coords{ nullptr }; ///< Pointer to the array of x values (optional)
48 : size_t m_nx{ 0 }; ///< X dimension of the array
49 :
50 : realT *m_mask{ nullptr }; ///< Pointer to the (optional) mask array. Any 0 pixels are excluded from the fit.
51 :
52 : realT m_G0{ 0 };
53 : realT m_G{ 0 };
54 : realT m_x0{ 0 };
55 : realT m_sigma{ 0 };
56 :
57 : int m_G0_idx{ 0 };
58 : int m_G_idx{ 1 };
59 : int m_x0_idx{ 2 };
60 : int m_sigma_idx{ 3 };
61 :
62 : int m_nparams{ 4 };
63 : int m_maxNparams{ 4 };
64 :
65 : /// Set whether each parameter is fixed.
66 : /** Sets the parameter indices appropriately.
67 : */
68 : void setFixed( bool G0, bool G, bool x0, bool sigma );
69 :
70 : realT G0( realT *p );
71 :
72 : void G0( realT *p, realT nG0 );
73 :
74 : realT G( realT *p );
75 :
76 : void G( realT *p, realT nG );
77 :
78 : realT x0( realT *p );
79 :
80 : void x0( realT *p, realT nx0 );
81 :
82 : realT sigma( realT *p );
83 :
84 : void sigma( realT *p, realT nsigma_x );
85 :
86 : int nparams();
87 : };
88 :
89 : template <typename realT>
90 0 : void array2FitGaussian1D<realT>::setFixed( bool G0, bool G, bool x0, bool sigma )
91 : {
92 0 : int idx = 0;
93 :
94 0 : if( G0 )
95 0 : m_G0_idx = -1;
96 : else
97 0 : m_G0_idx = idx++;
98 :
99 0 : if( G )
100 0 : m_G_idx = -1;
101 : else
102 0 : m_G_idx = idx++;
103 :
104 0 : if( x0 )
105 0 : m_x0_idx = -1;
106 : else
107 0 : m_x0_idx = idx++;
108 :
109 0 : if( sigma )
110 0 : m_sigma_idx = -1;
111 : else
112 0 : m_sigma_idx = idx++;
113 :
114 0 : m_nparams = idx;
115 0 : }
116 :
117 : template <typename realT>
118 0 : realT array2FitGaussian1D<realT>::G0( realT *p )
119 : {
120 0 : if( m_G0_idx < 0 )
121 : {
122 0 : return m_G0;
123 : }
124 : else
125 : {
126 0 : return p[m_G0_idx];
127 : }
128 : }
129 :
130 : template <typename realT>
131 0 : void array2FitGaussian1D<realT>::G0( realT *p, realT nG0 )
132 : {
133 0 : if( m_G0_idx < 0 )
134 : {
135 0 : m_G0 = nG0;
136 : }
137 : else
138 : {
139 0 : p[m_G0_idx] = nG0;
140 : }
141 0 : }
142 :
143 : template <typename realT>
144 0 : realT array2FitGaussian1D<realT>::G( realT *p )
145 : {
146 0 : if( m_G_idx < 0 )
147 : {
148 0 : return m_G;
149 : }
150 : else
151 : {
152 0 : return p[m_G_idx];
153 : }
154 : }
155 :
156 : template <typename realT>
157 0 : void array2FitGaussian1D<realT>::G( realT *p, realT nG )
158 : {
159 0 : if( m_G_idx < 0 )
160 : {
161 0 : m_G = nG;
162 : }
163 : else
164 : {
165 0 : p[m_G_idx] = nG;
166 : }
167 0 : }
168 :
169 : template <typename realT>
170 0 : realT array2FitGaussian1D<realT>::x0( realT *p )
171 : {
172 0 : if( m_x0_idx < 0 )
173 : {
174 0 : return m_x0;
175 : }
176 : else
177 : {
178 0 : return p[m_x0_idx];
179 : }
180 : }
181 :
182 : template <typename realT>
183 0 : void array2FitGaussian1D<realT>::x0( realT *p, realT nx0 )
184 : {
185 0 : if( m_x0_idx < 0 )
186 : {
187 0 : m_x0 = nx0;
188 : }
189 : else
190 : {
191 0 : p[m_x0_idx] = nx0;
192 : }
193 0 : }
194 :
195 : template <typename realT>
196 0 : realT array2FitGaussian1D<realT>::sigma( realT *p )
197 : {
198 0 : if( m_sigma_idx < 0 )
199 : {
200 0 : return m_sigma;
201 : }
202 : else
203 : {
204 0 : return p[m_sigma_idx];
205 : }
206 : }
207 :
208 : template <typename realT>
209 0 : void array2FitGaussian1D<realT>::sigma( realT *p, realT nsigma )
210 : {
211 0 : if( m_sigma_idx < 0 )
212 : {
213 0 : m_sigma = nsigma;
214 : }
215 : else
216 : {
217 0 : p[m_sigma_idx] = nsigma;
218 : }
219 0 : }
220 :
221 : template <typename realT>
222 0 : int array2FitGaussian1D<realT>::nparams()
223 : {
224 0 : return m_nparams;
225 : }
226 :
227 : } // namespace fit
228 : } // namespace math
229 :
230 : } // namespace mx
231 :
232 : #endif // math_fit_array2FitGaussian1D_hpp
|