2 #include <gsl/gsl_sf_trig.h>
3 #include <hkl/hkl-pseudoaxis.h>
5 /*****************************/
6 /* HklPseudoAxisEngineGetSet */
7 /*****************************/
9 HklPseudoAxisEngineGetSet
*hkl_pseudo_axis_engine_get_set_new(
11 HklPseudoAxisEngineGetterFunc get
,
12 HklPseudoAxisEngineSetterFunc set
,
15 HklPseudoAxisEngineGetSet
*self
= NULL
;
20 self
= calloc(1, sizeof(*self
));
22 die("Can not allocate memory for an HklPseudoAxisEngineGetSet");
31 self
->parameters
= calloc(n
, sizeof(HklParameter
));
32 self
->parameters_len
= n
;
34 self
->parameters
[i
] = *va_arg(ap
, HklParameter
*);
38 len
= va_arg(ap
, size_t);
39 self
->axes_names
= calloc(len
, sizeof(char const *));
40 self
->axes_names_len
= len
;
42 self
->axes_names
[i
] = va_arg(ap
, char const *);
49 void hkl_pseudo_axis_engine_get_set_free(HklPseudoAxisEngineGetSet
*self
)
51 if(self
->parameters_len
) {
52 self
->parameters_len
= 0;
53 free(self
->parameters
);
54 self
->parameters
= NULL
;
57 if(self
->axes_names_len
) {
58 self
->axes_names_len
= 0;
59 free(self
->axes_names
);
60 self
->axes_names
= NULL
;
69 HklPseudoAxisEngine
*hkl_pseudoAxisEngine_new(char const *name
,
75 HklPseudoAxisEngine
*self
= NULL
;
77 self
= calloc(1, sizeof(*self
));
79 die("Can not allocate memory for an HklPseudoAxisEngine");
83 // create the pseudoAxes
84 self
->pseudoAxes
= malloc(n
* sizeof(HklPseudoAxis
));
85 self
->pseudoAxes_len
= n
;
88 self
->pseudoAxes
[i
].name
= va_arg(ap
, const char*);
89 self
->pseudoAxes
[i
].engine
= self
;
96 void hkl_pseudoAxisEngine_free(HklPseudoAxisEngine
*self
)
101 hkl_geometry_free(self
->geometry
);
102 /* release the axes memory */
103 if (self
->axes_len
) {
108 /* release the getset added */
109 if (self
->getsets_len
) {
110 for(i
=0; i
<self
->getsets_len
; ++i
)
111 hkl_pseudo_axis_engine_get_set_free(self
->getsets
[i
]);
112 self
->getsets_len
= 0;
114 self
->getsets
= NULL
;
116 /* release the HklPseudoAxe memory */
117 if (self
->pseudoAxes_len
) {
118 free(self
->pseudoAxes
);
119 self
->pseudoAxes
= NULL
;
120 self
->pseudoAxes_len
= 0;
122 /* release the geometries allocated during calculations */
123 if (self
->geometries_alloc
) {
124 for(i
=0; i
<self
->geometries_alloc
; ++i
)
125 hkl_geometry_free(self
->geometries
[i
]);
126 free(self
->geometries
);
127 self
->geometries
= NULL
;
128 self
->geometries_alloc
= self
->geometries_len
= 0;
133 void hkl_pseudoAxisEngine_add_get_set(HklPseudoAxisEngine
*self
,
134 HklPseudoAxisEngineGetSet
*getset
)
136 size_t n
= self
->getsets_len
++;
137 self
->getsets
= realloc(self
->getsets
,
138 self
->getsets_len
*sizeof(HklPseudoAxisEngineGetSet
*));
139 self
->getsets
[n
] = getset
;
143 * @brief this method Add a geometry to the geometries
145 * @param self The current PseudoAxeEngine
146 * @param x A vector of double with the axes values to put in the geometry.
148 * This method try to be clever by allocating memory only if the current
149 * length of the geometries is not large enought. Then it just set the
150 * geometry axes and copy it to the right geometries. We do not gives the
151 * x len as it is equal to the self->axes_len.
153 void hkl_pseudoAxisEngine_add_geometry(HklPseudoAxisEngine
*self
,
157 HklGeometry
*geometry
;
159 // first check if we can get an old geometry.
160 if (self
->geometries_len
== self
->geometries_alloc
) {
161 self
->geometries_alloc
= alloc_nr(self
->geometries_alloc
);
162 self
->geometries
= realloc(self
->geometries
,
163 self
->geometries_alloc
* sizeof(HklGeometry
*));
164 for(i
=self
->geometries_len
; i
<self
->geometries_alloc
; i
++)
165 self
->geometries
[i
] = hkl_geometry_new_copy(self
->geometry
);
168 /* copy the axes configuration into the engine->geometry */
169 for(i
=0; i
<self
->axes_len
; ++i
)
170 self
->axes
[i
]->config
.value
= x
[i
];
172 /* put the axes configuration from engine->geometry -> geometry */
173 geometry
= self
->geometries
[self
->geometries_len
++];
174 hkl_geometry_init_geometry(geometry
, self
->geometry
);
177 void hkl_pseudoAxisEngine_select_get_set(HklPseudoAxisEngine
*self
,
180 self
->getset
= self
->getsets
[idx
];
184 * @brief update the geometry, detector and sample internals.
186 * @param self The current PseudoAxeEngine
187 * @param geometry the geometry to initialize the self->geometry
188 * @param detector idem for the geometry
189 * @param sample idem for the sample
191 * This method also populate the self->axes from the getset->axes_names.
192 * this is to speed the computation of the numerical axes. this method is
193 * usually only use with numerical pseudoAxes.
195 void hkl_pseudoAxeEngine_prepare_internal(HklPseudoAxisEngine
*self
,
196 HklGeometry
*geometry
, HklDetector
*detector
,
203 hkl_geometry_init_geometry(self
->geometry
, geometry
);
205 self
->geometry
= hkl_geometry_new_copy(geometry
);
206 self
->detector
= detector
;
207 self
->sample
= sample
;
209 // fill the axes member from the function
211 free(self
->axes
), self
->axes
= NULL
, self
->axes_len
= 0;
212 self
->axes_len
= self
->getset
->axes_names_len
;
213 self
->axes
= malloc(self
->axes_len
* sizeof(HklAxis
*));
214 for(i
=0; i
<self
->axes_len
; ++i
)
215 self
->axes
[i
] = hkl_geometry_get_axis_by_name(self
->geometry
,
216 self
->getset
->axes_names
[i
]);
218 // reset the geometries len
219 self
->geometries_len
= 0;
222 int hkl_pseudoAxisEngine_setter(HklPseudoAxisEngine
*self
,
223 HklGeometry
*geom
, HklDetector
*det
, HklSample
*sample
)
225 return self
->getset
->set(self
, geom
, det
, sample
);
228 void hkl_pseudoAxisEngine_getter(HklPseudoAxisEngine
*self
,
229 HklGeometry
*geom
, HklDetector
*det
, HklSample
*sample
)
231 self
->getset
->get(self
, geom
, det
, sample
);
234 void hkl_pseudoAxisEngine_fprintf(HklPseudoAxisEngine
*self
, FILE *f
)
239 fprintf(f
, "\nPseudoAxesEngine : \"%s\"", self
->name
);
243 fprintf(f
, " %s", self
->getset
->name
);
245 for(i
=0; i
<self
->getset
->parameters_len
; ++i
)
246 fprintf(f
, " \"%s\" = %g",
247 self
->getset
->parameters
[i
].name
,
248 self
->getset
->parameters
[i
].value
);
251 /* the pseudoAxes part */
253 for(i
=0; i
<self
->pseudoAxes_len
; ++i
)
254 fprintf(f
, " \"%s\" : %f", self
->pseudoAxes
[i
].name
, self
->pseudoAxes
[i
].config
.value
);
257 if (self
->geometry
) {
259 for(i
=0; i
<self
->geometry
->axes_len
; ++i
)
260 fprintf(f
, "%9s", self
->geometry
->axes
[i
]->name
);
264 for(i
=0; i
<self
->geometries_len
; ++i
) {
265 fprintf(f
, "%d :", i
);
266 for(j
=0; j
<self
->geometry
->axes_len
; ++j
) {
267 value
= self
->geometries
[i
]->axes
[j
]->config
.value
;
268 //value = gsl_sf_angle_restrict_symm(value);
269 fprintf(f
, " % 9.6g", value
* HKL_RADTODEG
);
274 fprintf(stdout
, "\n");