1
// -*- mode: C++; tab-width: 2; -*-
4
// --------------------------------------------------------------------------
5
// OpenMS Mass Spectrometry Framework
6
// --------------------------------------------------------------------------
7
// Copyright (C) 2003-2011 -- Oliver Kohlbacher, Knut Reinert
9
// This library is free software; you can redistribute it and/or
10
// modify it under the terms of the GNU Lesser General Public
11
// License as published by the Free Software Foundation; either
12
// version 2.1 of the License, or (at your option) any later version.
14
// This library is distributed in the hope that it will be useful,
15
// but WITHOUT ANY WARRANTY; without even the implied warranty of
16
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
// Lesser General Public License for more details.
19
// You should have received a copy of the GNU Lesser General Public
20
// License along with this library; if not, write to the Free Software
21
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1
// --------------------------------------------------------------------------
2
// OpenMS -- Open-Source Mass Spectrometry
3
// --------------------------------------------------------------------------
4
// Copyright The OpenMS Team -- Eberhard Karls University Tuebingen,
5
// ETH Zurich, and Freie Universitaet Berlin 2002-2013.
7
// This software is released under a three-clause BSD license:
8
// * Redistributions of source code must retain the above copyright
9
// notice, this list of conditions and the following disclaimer.
10
// * Redistributions in binary form must reproduce the above copyright
11
// notice, this list of conditions and the following disclaimer in the
12
// documentation and/or other materials provided with the distribution.
13
// * Neither the name of any author or any participating institution
14
// may be used to endorse or promote products derived from this software
15
// without specific prior written permission.
16
// For a full list of authors, refer to the file AUTHORS.
17
// --------------------------------------------------------------------------
18
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
// ARE DISCLAIMED. IN NO EVENT SHALL ANY OF THE AUTHORS OR THE CONTRIBUTING
22
// INSTITUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
30
// --------------------------------------------------------------------------
24
31
// $Maintainer: Andreas Bertsch $
43
GaussFitter::GaussFitter()
47
init_param_.sigma = 0.5;
50
GaussFitter::~GaussFitter()
54
void GaussFitter::setInitialParameters(const GaussFitResult& param)
56
init_param_.A = param.A;
57
init_param_.x0 = param.x0;
58
init_param_.sigma = param.sigma;
61
const String& GaussFitter::getGnuplotFormula() const
63
return gnuplot_formula_;
66
int GaussFitter::gaussFitterf_(const gsl_vector* x, void* params, gsl_vector* f)
68
vector<DPosition<2> >* data = static_cast<vector<DPosition<2> >*>(params);
70
double A = gsl_vector_get (x, 0);
71
double x0 = gsl_vector_get (x, 1);
72
double sig = gsl_vector_get (x, 2);
75
for (vector<DPosition<2> >::iterator it = data->begin(); it != data->end(); ++it)
77
gsl_vector_set(f, i++, A * exp(-1.0 * pow(it->getX() - x0, 2) / (2 * pow(sig, 2))) - it->getY());
83
int GaussFitter::gaussFitterdf_(const gsl_vector* x, void* params, gsl_matrix* J)
85
vector<DPosition<2> >* data = static_cast<vector<DPosition<2> >*>(params);
87
double A = gsl_vector_get (x, 0);
88
double x0 = gsl_vector_get (x, 1);
89
double sig = gsl_vector_get (x, 2);
92
for (vector<DPosition<2> >::iterator it = data->begin(); it != data->end(); ++it)
94
gsl_matrix_set (J, i, 0, exp(-1.0 * pow(it->getX() - x0, 2) / (2 * pow(sig, 2))));
95
gsl_matrix_set (J, i, 1, (A * exp(-1.0 * pow(it->getX() - x0, 2) / (2 * pow(sig, 2))) * (-1 * (-2 * it->getX() + 2.0 * x0) / (2 * pow(sig, 2)))));
96
gsl_matrix_set (J, i++, 2, (A * exp(-1.0 * pow(it->getX() - x0, 2) / (2 * pow(sig, 2))) * (pow(it->getX() - x0, 2) / (4 * pow(sig, 3)))));
101
int GaussFitter::gaussFitterfdf_(const gsl_vector* x, void* params, gsl_vector* f, gsl_matrix* J)
103
gaussFitterf_(x, params, f);
104
gaussFitterdf_(x, params, J);
108
#ifdef GAUSS_FITTER_VERBOSE
109
void GaussFitter::printState_(size_t iter, gsl_multifit_fdfsolver * s)
111
printf ("iter: %3u x = % 15.8f % 15.8f % 15.8f "
114
gsl_vector_get(s->x, 0),
115
gsl_vector_get(s->x, 1),
116
gsl_vector_get(s->x, 2),
117
/*gsl_blas_dnrm2(s->f)*/0);
121
GaussFitter::GaussFitResult GaussFitter::fit(vector<DPosition<2> >& input)
123
const gsl_multifit_fdfsolver_type *T = NULL;
124
gsl_multifit_fdfsolver *s = NULL;
131
//gsl_matrix *covar = gsl_matrix_alloc (p, p);
132
gsl_multifit_function_fdf f;
133
double x_init[3] = { init_param_.A, init_param_.x0, init_param_.sigma };
134
gsl_vector_view x = gsl_vector_view_array (x_init, p);
135
const gsl_rng_type * type = NULL;
140
type = gsl_rng_default;
141
r = gsl_rng_alloc (type);
143
f.f = &gaussFitterf_;
144
f.df = &gaussFitterdf_;
145
f.fdf = &gaussFitterfdf_;
150
T = gsl_multifit_fdfsolver_lmsder;
151
s = gsl_multifit_fdfsolver_alloc (T, input.size(), p);
152
gsl_multifit_fdfsolver_set (s, &f, &x.vector);
154
#ifdef GAUSS_FITTER_VERBOSE
155
printState_(iter, s);
161
status = gsl_multifit_fdfsolver_iterate (s);
163
#ifdef GAUSS_FITTER_VERBOSE
164
printf ("status = %s\n", gsl_strerror (status));
165
printState_(iter, s);
167
cerr << "f(x)=" << gsl_vector_get(s->x, 0) << " * exp(-(x - " << gsl_vector_get(s->x, 1) << ") ** 2 / 2 / (" << gsl_vector_get(s->x, 2) << ") ** 2)";
175
status = gsl_multifit_test_delta (s->dx, s->x,
178
while (status == GSL_CONTINUE && iter < 500);
180
if (status!=GSL_SUCCESS)
183
gsl_multifit_fdfsolver_free(s);
185
throw Exception::UnableToFit(__FILE__,__LINE__,__PRETTY_FUNCTION__,"UnableToFit-GaussFitter","Could not fit the gaussian to the data");
188
// write the result in a GaussFitResult struct
189
GaussFitResult result;
190
result.A = gsl_vector_get(s->x, 0);
191
result.x0 = gsl_vector_get(s->x, 1);
192
result.sigma = gsl_vector_get(s->x, 2);
194
// build a formula with the fitted parameters for gnuplot
195
stringstream formula;
196
formula << "f(x)=" << result.A << " * exp(-(x - " << result.x0 << ") ** 2 / 2 / (" << result.sigma << ") ** 2)";
197
gnuplot_formula_ = formula.str();
198
#ifdef GAUSS_FITTER_VERBOSE
199
cout << gnuplot_formula_ << endl;
203
gsl_multifit_fdfsolver_free (s);
50
GaussFitter::GaussFitter()
54
init_param_.sigma = 0.5;
57
GaussFitter::~GaussFitter()
61
void GaussFitter::setInitialParameters(const GaussFitResult & param)
63
init_param_.A = param.A;
64
init_param_.x0 = param.x0;
65
init_param_.sigma = param.sigma;
68
const String & GaussFitter::getGnuplotFormula() const
70
return gnuplot_formula_;
73
int GaussFitter::gaussFitterf_(const gsl_vector * x, void * params, gsl_vector * f)
75
vector<DPosition<2> > * data = static_cast<vector<DPosition<2> > *>(params);
77
double A = gsl_vector_get(x, 0);
78
double x0 = gsl_vector_get(x, 1);
79
double sig = gsl_vector_get(x, 2);
82
for (vector<DPosition<2> >::iterator it = data->begin(); it != data->end(); ++it)
84
gsl_vector_set(f, i++, A * exp(-1.0 * pow(it->getX() - x0, 2) / (2 * pow(sig, 2))) - it->getY());
90
int GaussFitter::gaussFitterdf_(const gsl_vector * x, void * params, gsl_matrix * J)
92
vector<DPosition<2> > * data = static_cast<vector<DPosition<2> > *>(params);
94
double A = gsl_vector_get(x, 0);
95
double x0 = gsl_vector_get(x, 1);
96
double sig = gsl_vector_get(x, 2);
99
for (vector<DPosition<2> >::iterator it = data->begin(); it != data->end(); ++it)
101
gsl_matrix_set(J, i, 0, exp(-1.0 * pow(it->getX() - x0, 2) / (2 * pow(sig, 2))));
102
gsl_matrix_set(J, i, 1, (A * exp(-1.0 * pow(it->getX() - x0, 2) / (2 * pow(sig, 2))) * (-1 * (-2 * it->getX() + 2.0 * x0) / (2 * pow(sig, 2)))));
103
gsl_matrix_set(J, i++, 2, (A * exp(-1.0 * pow(it->getX() - x0, 2) / (2 * pow(sig, 2))) * (pow(it->getX() - x0, 2) / (4 * pow(sig, 3)))));
108
int GaussFitter::gaussFitterfdf_(const gsl_vector * x, void * params, gsl_vector * f, gsl_matrix * J)
110
gaussFitterf_(x, params, f);
111
gaussFitterdf_(x, params, J);
115
#ifdef GAUSS_FITTER_VERBOSE
116
void GaussFitter::printState_(size_t iter, gsl_multifit_fdfsolver * s)
118
printf("iter: %3u x = % 15.8f % 15.8f % 15.8f "
121
gsl_vector_get(s->x, 0),
122
gsl_vector_get(s->x, 1),
123
gsl_vector_get(s->x, 2),
124
/*gsl_blas_dnrm2(s->f)*/ 0);
129
GaussFitter::GaussFitResult GaussFitter::fit(vector<DPosition<2> > & input)
131
const gsl_multifit_fdfsolver_type * T = NULL;
132
gsl_multifit_fdfsolver * s = NULL;
139
//gsl_matrix *covar = gsl_matrix_alloc (p, p);
140
gsl_multifit_function_fdf f;
141
double x_init[3] = { init_param_.A, init_param_.x0, init_param_.sigma };
142
gsl_vector_view x = gsl_vector_view_array(x_init, p);
143
const gsl_rng_type * type = NULL;
148
type = gsl_rng_default;
149
r = gsl_rng_alloc(type);
151
f.f = &gaussFitterf_;
152
f.df = &gaussFitterdf_;
153
f.fdf = &gaussFitterfdf_;
158
T = gsl_multifit_fdfsolver_lmsder;
159
s = gsl_multifit_fdfsolver_alloc(T, input.size(), p);
160
gsl_multifit_fdfsolver_set(s, &f, &x.vector);
162
#ifdef GAUSS_FITTER_VERBOSE
163
printState_(iter, s);
169
status = gsl_multifit_fdfsolver_iterate(s);
171
#ifdef GAUSS_FITTER_VERBOSE
172
printf("status = %s\n", gsl_strerror(status));
173
printState_(iter, s);
175
cerr << "f(x)=" << gsl_vector_get(s->x, 0) << " * exp(-(x - " << gsl_vector_get(s->x, 1) << ") ** 2 / 2 / (" << gsl_vector_get(s->x, 2) << ") ** 2)";
183
status = gsl_multifit_test_delta(s->dx, s->x,
186
while (status == GSL_CONTINUE && iter < 500);
188
if (status != GSL_SUCCESS)
191
gsl_multifit_fdfsolver_free(s);
193
throw Exception::UnableToFit(__FILE__, __LINE__, __PRETTY_FUNCTION__, "UnableToFit-GaussFitter", "Could not fit the gaussian to the data");
196
// write the result in a GaussFitResult struct
197
GaussFitResult result;
198
result.A = gsl_vector_get(s->x, 0);
199
result.x0 = gsl_vector_get(s->x, 1);
200
result.sigma = gsl_vector_get(s->x, 2);
202
// build a formula with the fitted parameters for gnuplot
203
stringstream formula;
204
formula << "f(x)=" << result.A << " * exp(-(x - " << result.x0 << ") ** 2 / 2 / (" << result.sigma << ") ** 2)";
205
gnuplot_formula_ = formula.str();
206
#ifdef GAUSS_FITTER_VERBOSE
207
cout << gnuplot_formula_ << endl;
211
gsl_multifit_fdfsolver_free(s);
209
217
} // namespace OpenMS