Merge branch 'maint' into next
[hkl.git] / hkl / hkl-parameter.c
blob3b782396c091e523fe9c3a7e6f358a794f1d77c6
1 /* This file is part of the hkl library.
3 * The hkl library is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
8 * The hkl library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with the hkl library. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright (C) 2003-2016 Synchrotron SOLEIL
17 * L'Orme des Merisiers Saint-Aubin
18 * BP 48 91192 GIF-sur-YVETTE CEDEX
20 * Authors: Picca Frédéric-Emmanuel <picca@synchrotron-soleil.fr>
22 #include <stdio.h> // for fprintf, FILE
23 #include <stdlib.h> // for free, malloc, NULL
24 #include <string.h> // for strcmp
25 #include "hkl-interval-private.h" // for HklInterval
26 #include "hkl-macros-private.h" // for HKL_MALLOC
27 #include "hkl-parameter-private.h" // for _HklParameter, etc
28 #include "hkl-unit-private.h" // for hkl_unit_factor, HklUnit, etc
29 #include "hkl.h" // for HklParameter, etc
30 #include "hkl/ccan/darray/darray.h" // for darray_size, darray_item, etc
32 /****************/
33 /* HklParameter */
34 /****************/
36 static int hkl_parameter_init(HklParameter *self, const char *name,
37 const char *description,
38 double min, double value, double max,
39 int fit, int changed,
40 const HklUnit *unit, const HklUnit *punit)
42 if (min <= value
43 && value <= max
44 && strcmp(name, "")
45 && strcmp(description, "")
46 && hkl_unit_compatible(unit, punit)) {
47 self->name = name;
48 self->description = description;
49 self->range.min = min;
50 self->range.max = max;
51 self->_value = value;
52 self->unit = unit;
53 self->punit = punit;
54 self->fit = fit;
55 self->changed = changed;
56 self->ops = &hkl_parameter_operations_defaults;
57 } else
58 return FALSE;
60 return TRUE;
63 /**
64 * hkl_parameter_new: (skip)
65 * @name:
66 * @min:
67 * @value:
68 * @max:
69 * @fit:
70 * @changed:
71 * @unit:
72 * @punit:
74 * create a new #HklParameter
76 * Returns:
77 **/
78 HklParameter *hkl_parameter_new(const char *name, const char *description,
79 double min, double value, double max,
80 int fit, int changed,
81 const HklUnit *unit, const HklUnit *punit)
83 HklParameter *self;
85 self = HKL_MALLOC(HklParameter);
87 if (!hkl_parameter_init(self,
88 name, description,
89 min, value, max,
90 fit, changed,
91 unit, punit)) {
92 free(self);
93 self = NULL;
96 return self;
99 /**
100 * hkl_parameter_new_copy: (skip)
101 * @self:
103 * copy an #HklParameter
105 * Returns:
107 HklParameter *hkl_parameter_new_copy(const HklParameter *self)
109 return self->ops->copy(self);
113 * hkl_parameter_free: (skip)
114 * @self:
116 * delete an #HklParameter
118 void hkl_parameter_free(HklParameter *self)
120 self->ops->free(self);
124 * hkl_parameter_init_copy: (skip)
125 * @self: the this ptr
126 * @src: the parameter to copy from
127 * @error: return location for a GError, or NULL
129 * Returns: TRUE on success, FALSE if an error occurred
131 int hkl_parameter_init_copy(HklParameter *self, const HklParameter *src,
132 GError **error)
134 return self->ops->init_copy(self, src, error);
138 * hkl_parameter_name_get:
139 * @self: the this ptr
141 * Returns: the name of the #HklParameter
143 const char *hkl_parameter_name_get(const HklParameter *self)
145 return self->name;
149 * hkl_parameter_default_unit_get:
150 * @self: the this ptr
152 * Returns: the default unit of the #HklParameter
154 const char *hkl_parameter_default_unit_get(const HklParameter *self)
156 return self->unit->name;
160 * hkl_parameter_user_unit_get:
161 * @self: the this ptr
163 * Returns: the user unit of the #HklParameter
165 const char *hkl_parameter_user_unit_get(const HklParameter *self)
167 return self->punit->name;
171 * hkl_parameter_value_get:
172 * @self: the this ptr
173 * @unit_type: the unit type (default or user) of the returned value
175 * Returns: the value of the #HklParameter
177 inline double hkl_parameter_value_get(const HklParameter *self,
178 HklUnitEnum unit_type)
180 switch(unit_type){
181 case HKL_UNIT_DEFAULT:
182 return self->_value;
183 break;
184 case HKL_UNIT_USER:
185 return self->_value * hkl_unit_factor(self->unit, self->punit);
186 break;
187 default:
188 return NAN;
193 * hkl_parameter_value_get_closest:
194 * @self: the this ptr
195 * @ref: the reference #HklParameter
199 * Returns: the closest value of the ref #HklParameter from the
200 * current self #HklParameter
202 inline double hkl_parameter_value_get_closest(const HklParameter *self,
203 const HklParameter *ref)
205 return self->ops->get_value_closest(self, ref);
209 * hkl_parameter_value_set:
210 * @self: this ptr
211 * @value: the value to set
212 * @unit_type: the unit type (default or user) of the returned value
213 * @error: return location for a GError, or NULL
215 * set the value of an #HklParameter
217 * Returns: TRUE on success, FALSE if an error occurred
219 inline int hkl_parameter_value_set(HklParameter *self, double value,
220 HklUnitEnum unit_type, GError **error)
222 return self->ops->set_value(self, value, unit_type, error);
226 * hkl_parameter_value_set_smallest_in_range: (skip)
227 * @self: the this ptr
229 inline void hkl_parameter_value_set_smallest_in_range(HklParameter *self)
231 self->ops->set_value_smallest_in_range(self);
235 * hkl_parameter_min_max_get:
236 * @self: the this ptr
237 * @min: (out caller-allocates): the returned minimum value
238 * @max: (out caller-allocates): the returned maximum value
239 * @unit_type: the unit type (default or user) of the returned values
241 * get the min and max value of the #HklParameter
244 void hkl_parameter_min_max_get(const HklParameter *self, double *min, double *max,
245 HklUnitEnum unit_type)
247 double factor;
249 switch (unit_type){
250 case HKL_UNIT_DEFAULT:
251 *min = self->range.min;
252 *max = self->range.max;
253 break;
254 case HKL_UNIT_USER:
255 factor = hkl_unit_factor(self->unit, self->punit);
256 *min = factor * self->range.min;
257 *max = factor * self->range.max;
258 break;
263 * hkl_parameter_min_max_set:
264 * @self: the this ptr
265 * @min: the minimum value to set
266 * @max: the maximum value to set
267 * @unit_type: the unit type (default or user) of the min, max
268 * @error: return location for a GError, or NULL
270 * set the #HklParameter range.
271 * @todo test and set the GError
273 * Returns: TRUE on success, FALSE if an error occurred
275 int hkl_parameter_min_max_set(HklParameter *self, double min, double max,
276 HklUnitEnum unit_type, GError **error)
278 double factor;
280 hkl_error (error == NULL || *error == NULL);
282 if (min > max){
283 g_set_error(error,
284 HKL_PARAMETER_ERROR,
285 HKL_PARAMETER_ERROR_MIN_MAX_SET,
286 "can not set this range min > max\n");
288 return FALSE;
291 switch (unit_type){
292 case HKL_UNIT_DEFAULT:
293 self->range.min = min;
294 self->range.max = max;
295 break;
296 case HKL_UNIT_USER:
297 factor = hkl_unit_factor(self->unit, self->punit);
298 self->range.min = min / factor;
299 self->range.max = max / factor;
300 break;
303 return TRUE;
307 * hkl_parameter_fit_get:
308 * @self: the this ptr
310 * Retuen value: the #HklParameter fit value, True is the parameter can be fitted, not otherwise
311 * @todo test
313 int hkl_parameter_fit_get(const HklParameter *self)
315 return self->fit;
319 * hkl_parameter_fit_set:
320 * @self: the this ptr
321 * @fit: the fit value to set
323 * set the #HklParameter fit value, True is the parameter can be fitted, not otherwise
324 * @todo test
326 void hkl_parameter_fit_set(HklParameter *self, int fit)
328 self->fit = fit;
332 * hkl_parameter_randomize: (skip)
333 * @self:
335 * randomize the #HklParameter value into the min,max range
337 void hkl_parameter_randomize(HklParameter *self)
339 self->ops->randomize(self);
343 * hkl_parameter_is_valid: (skip)
344 * @self:
346 * check if the value of the #HklParameter is in the min,max range
348 * Returns:
350 int hkl_parameter_is_valid(const HklParameter *self)
352 return self->ops->is_valid(self);
356 * hkl_parameter_is_valid_range: (skip)
357 * @self:
359 * check if the value of the #HklParameter is in the min,max range
360 * strictly (min < value < max).
362 * Returns:
364 int hkl_parameter_is_valid_range(const HklParameter *self)
366 return self->ops->is_valid_range(self);
370 * hkl_parameter_fprintf: (skip)
371 * @f:
372 * @self:
374 * print into the #FILE f an #HklParameter
376 void hkl_parameter_fprintf(FILE *f, HklParameter *self)
378 double factor = hkl_unit_factor(self->unit, self->punit);
379 if (self->punit)
380 fprintf(f, "\"%s\" : %.7f %s [%.7f : %.7f] (%d)",
381 self->name,
382 self->_value * factor,
383 self->punit->repr,
384 self->range.min * factor,
385 self->range.max * factor,
386 self->fit);
387 else
388 fprintf(f, "\"%s\" : %.7f [%.7f : %.7f] (%d)",
389 self->name,
390 self->_value * factor,
391 self->range.min * factor,
392 self->range.max * factor,
393 self->fit);
397 * hkl_parameter_axis_v_get:
398 * @self: the this ptr
400 * Returns: (allow-none):
402 const HklVector *hkl_parameter_axis_v_get(const HklParameter *self)
404 return self->ops->axis_v_get(self);
408 * hkl_parameter_quaternion_get:
409 * @self: the this ptr
411 * Returns: (allow-none):
413 const HklQuaternion *hkl_parameter_quaternion_get(const HklParameter *self)
415 return self->ops->quaternion_get(self);
419 * hkl_parameter_description_get:
420 * @self: the this ptr
422 * Returns: the #HklParameter description
424 const char *hkl_parameter_description_get(const HklParameter *self)
426 return self->description;