* do not remove dynamic devices when stopping the Diffractometer device.
[diffractometer.git] / src / TangoHKLAdapter.cpp
blobcf7b4929f055da28df23cada227fba6903af3b31
1 #if ( _MSC_VER && _MSC_VER <= 1200 )
2 // Ce pragma ne devrait pas etre dans ce fichier car le warning ne s'affiche
3 // que si l'on compile une version DEBUG de la librairie.
4 // Il faut utiliser l'option de compilation \wd4786 mais elle n'est presente
5 // qu'à partir de VC++7
6 # pragma warning (disable : 4786)
7 #endif
9 #include <iomanip>
11 #include <hkl/hkl-pseudoaxis.h>
13 #include "macros.h"
14 #include "TangoHKLAdapter.h"
15 #include "Diffractometer.h"
16 #include "PseudoAxes.h"
17 #include "AxisAdapter.h"
18 #include "AxisAttrib.h"
19 #include "PseudoAxesAttrib.h"
21 //#define DEBUG
22 #ifndef NDEBUG
23 # define STDOUT(stream) std::cout << stream
24 #else
25 # define STDOUT(stream) {};
26 #endif
28 namespace Diffractometer_ns
30 //+----------------------------------------------------------------------------
32 // method : TangoHKLAdapter::TangoHKLAdapter(string &s)
34 // description : constructor for the adapter between HKl library and Tango
36 // in : - type : Type of diffractometer to instancate
38 //-----------------------------------------------------------------------------
39 TangoHKLAdapter::TangoHKLAdapter(Diffractometer *device, HklGeometryType type) :
40 _device(device),
41 _type(type)
43 size_t i, len;
44 HklAxis *axes_r;
45 HklAxis *axes_w;
46 HklAxis *axes_r_real;
47 HklAxis *axes_w_real;
49 this->ready = false;
50 this->simulated = true;
51 _lambdaAttributeProxy = NULL;
52 _wrong_nb_of_axis_proxies = false;
53 _ux = 0;
54 _uy = 0;
55 _uz = 0;
56 _angles_idx = 0;
58 duration.Start();
60 // Create the hkl part
61 _diffractometer = new HklDiffractometer;
62 _diffractometer->geometry_r = hkl_geometry_factory_new(type, 50 * HKL_DEGTORAD);
63 _diffractometer->geometry_w = hkl_geometry_factory_new(type, 50 * HKL_DEGTORAD);
64 _diffractometer->geometry_r_real = hkl_geometry_factory_new(type, 50 * HKL_DEGTORAD);
65 _diffractometer->geometry_w_real = hkl_geometry_factory_new(type, 50 * HKL_DEGTORAD);
66 _diffractometer->detector.idx = 1;
67 _diffractometer->detector_real.idx = 1;
68 _diffractometer->samples = hkl_sample_list_new();
69 _diffractometer->engines_r = hkl_pseudo_axis_engine_list_factory(type);
70 _diffractometer->engines_w = hkl_pseudo_axis_engine_list_factory(type);
71 _diffractometer->engines_r_real = hkl_pseudo_axis_engine_list_factory(type);
72 _diffractometer->engines_w_real = hkl_pseudo_axis_engine_list_factory(type);
74 // only once as it use only the "hkl" mode for now
75 this->update_mode_names();
76 this->update_mode_parameters_names();
78 // Build Group
79 Tango::GroupReply::enable_exception(true);
80 _proxies = new Tango::Group("Axis");
82 // fill the axisAdapter.
83 len = HKL_LIST_LEN(_diffractometer->geometry_r->axes);
84 axes_r = _diffractometer->geometry_r->axes;
85 axes_w = _diffractometer->geometry_w->axes;
86 axes_r_real = _diffractometer->geometry_r_real->axes;
87 axes_w_real = _diffractometer->geometry_w_real->axes;
88 for(i=0; i<len; ++i)
89 _axes.push_back(AxisAdapter(this, &axes_r[i], &axes_w[i], &axes_r_real[i], &axes_w_real[i]));
91 // hack to connect all axes the first time
92 this->simulated = false;
93 this->connect_all_proxies();
94 this->simulated = true;
96 // fill the pseudoAxesAdapters
98 omni_mutex_lock lock(_lock);
100 len = HKL_LIST_LEN(_diffractometer->engines_r->engines);
101 _pseudo_axes_proxies.resize(len, 1);
102 for(i=0; i<len; ++i){
103 PseudoAxesAdapter *adapter;
105 adapter = new PseudoAxesAdapter(this, i);
106 _pseudoAxesAdapters.push_back(adapter);
107 _pseudo_axes_proxies.data[i] = const_cast<char *>(adapter->_proxy_name.c_str());
111 // create the dynamic attributes
112 this->create_axes_dynamic_attributes();
114 // set the default lambda
115 this->set_lambda(1.54);
118 TangoHKLAdapter::~TangoHKLAdapter(void)
120 unsigned int i;
122 // remove all pseudo axis adapters
123 for(i=0;i<_pseudoAxisAdapters.size();i++)
124 delete _pseudoAxisAdapters[i];
126 // remove all pseudo axes adapters;
127 for(i=0; i<_pseudoAxesAdapters.size(); ++i)
128 delete _pseudoAxesAdapters[i];
130 // remove all axisAdapter
131 _axes.clear();
133 if(_proxies) {
134 _proxies->remove_all();
135 delete _proxies;
136 _proxies = NULL;
139 if (_lambdaAttributeProxy)
140 delete _lambdaAttributeProxy;
142 // remove the hkl part
143 hkl_geometry_free(_diffractometer->geometry_r);
144 hkl_geometry_free(_diffractometer->geometry_w);
145 hkl_geometry_free(_diffractometer->geometry_r_real);
146 hkl_geometry_free(_diffractometer->geometry_w_real);
147 hkl_sample_list_free(_diffractometer->samples);
148 hkl_pseudo_axis_engine_list_free(_diffractometer->engines_r);
149 hkl_pseudo_axis_engine_list_free(_diffractometer->engines_w);
150 hkl_pseudo_axis_engine_list_free(_diffractometer->engines_r_real);
151 hkl_pseudo_axis_engine_list_free(_diffractometer->engines_w_real);
153 if(_diffractometer) {
154 delete _diffractometer;
155 _diffractometer = NULL;
159 void TangoHKLAdapter::connect_all_proxies(void)
161 omni_mutex_lock lock(_lock);
163 // connect the lambda proxy
164 if ((!_lambdaAttributeProxy && !this->simulated)
165 && _device->lambdaAttributeProxy != "") {
168 _lambdaAttributeProxy = new Tango::AttributeProxy(_device->lambdaAttributeProxy);
170 catch(...) {
174 // connect the axes proxies
175 if (!this->ready && !this->simulated) {
176 unsigned int nb;
178 nb = _device->realAxisProxies.size();
179 if (nb != _axes.size()) {
180 _wrong_nb_of_axis_proxies = true;
181 return;
182 } else {
183 unsigned int i, j;
184 bool ready = true;
186 for(i=0; i<nb; ++i) {
187 AxisAdapter & axis = _axes[i];
188 if (!axis.is_ready()){
189 // Find axis in the proxy list
190 for(j=0; j<nb; ++j) {
191 char *line = strdup(_device->realAxisProxies[j].c_str());
192 char *last;
193 char *axis_name = strtok_r(line, ":", &last);
194 char *proxy_name = strtok_r(NULL, ":", &last);
195 if (axis.get_name() == axis_name){
196 Tango::Group *group = axis.connect(proxy_name);
197 if(group)
198 _proxies->add(group);
200 free(line);
202 if (!axis.is_ready())
203 ready = false;
206 this->ready = ready;
211 void TangoHKLAdapter::set_lambda(double lambda)
213 omni_mutex_lock lock(_lock);
215 if ((this->simulated || _device->lambdaAttributeProxy == "")
216 && lambda > 0){
217 _lambda = lambda;
218 _diffractometer->geometry_r->source.wave_length = lambda;
219 _diffractometer->geometry_w->source.wave_length = lambda;
220 _diffractometer->geometry_r_real->source.wave_length = lambda;
221 _diffractometer->geometry_w_real->source.wave_length = lambda;
225 void TangoHKLAdapter::update_lambda(void)
227 if (_lambdaAttributeProxy && !this->simulated){
228 try{
229 _lambdaAttributeProxy->read() >> _lambda;
230 _diffractometer->geometry_r->source.wave_length = _lambda;
231 _diffractometer->geometry_w->source.wave_length = _lambda;
232 _diffractometer->geometry_r_real->source.wave_length = _lambda;
233 _diffractometer->geometry_w_real->source.wave_length = _lambda;
235 catch (Tango::DevFailed &){
237 }else
238 _lambda = _diffractometer->geometry_r->source.wave_length;
242 * this method update the angles attribut from the engines->geometry list
244 void TangoHKLAdapter::update_angles(void)
246 size_t i, j;
247 size_t xdim;
248 size_t ydim;
249 HklPseudoAxisEngine *engine;
250 double *data;
251 HklGeometry **geometries;
253 if(this->simulated)
254 engine = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_w, "hkl");
255 else
256 engine = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_w_real, "hkl");
258 xdim = 4 + HKL_LIST_LEN(_diffractometer->geometry_r->axes);
259 ydim = HKL_LIST_LEN(engine->engines->geometries->geometries);
261 _angles.resize(xdim, ydim);
262 _angles.clear();
264 //fill the array
265 data = _angles.data;
266 geometries = engine->engines->geometries->geometries;
267 for(j=0; j<ydim; ++j){
268 HklGeometry *geom = geometries[j];
270 data[0] = j;
271 data[1] = hkl_parameter_get_value_unit((HklParameter *)(engine->pseudoAxes[0]));
272 data[2] = hkl_parameter_get_value_unit((HklParameter *)(engine->pseudoAxes[1]));
273 data[3] = hkl_parameter_get_value_unit((HklParameter *)(engine->pseudoAxes[2]));
274 for(i=4; i<xdim; ++i)
275 data[i] = hkl_axis_get_value_unit(&geom->axes[i-4]);
276 data += xdim;
281 * this method update the reflections_angles when we change a sample parameter
283 void TangoHKLAdapter::update_reflections_angles(void)
285 HklSample *sample = _diffractometer->samples->current;
286 if (sample) {
287 unsigned int i, j;
288 size_t rdim;
289 double *data;
291 // the reflection Angles
292 rdim = HKL_LIST_LEN(sample->reflections);
293 _reflections_angles.resize(rdim, rdim);
294 _reflections_angles.clear();
296 data = _reflections_angles.data;
297 for(i=0; i<rdim; ++i) {
298 for(j=0; j<rdim; ++j) {
299 double angle = 0.;
300 if (j < i)
301 angle = hkl_sample_get_reflection_theoretical_angle(sample, i, j);
302 else if (j > i)
303 angle = hkl_sample_get_reflection_mesured_angle(sample, i, j);
305 *data = angle * HKL_RADTODEG;
306 data++;
312 void TangoHKLAdapter::update_sample_reflections(void)
314 HklSample *sample = _diffractometer->samples->current;
315 if (sample) {
317 // Allocation of the image
318 unsigned int xdim = 6 + HKL_LIST_LEN(_diffractometer->geometry_r->axes);
319 unsigned int ydim = HKL_LIST_LEN(sample->reflections);
320 _sample_reflections.resize(xdim, ydim);
322 size_t i = 0;
323 double *data = _sample_reflections.data;
324 for(i=0; i<ydim; ++i) {
325 HklSampleReflection *r;
327 r = hkl_sample_get_ith_reflection(sample, i);
328 if (r) {
329 size_t k;
330 HklAxis *axes = r->geometry->axes;
332 data[0] = i;
333 data[1] = r->hkl.data[0];
334 data[2] = r->hkl.data[1];
335 data[3] = r->hkl.data[2];
336 data[4] = 0;
337 data[5] = (double)r->flag;
339 for(k=0; k<HKL_LIST_LEN(r->geometry->axes); ++k)
340 data[6 + k] = hkl_axis_get_value_unit(&axes[k]);
342 data += xdim;
347 void TangoHKLAdapter::update_ub(void)
349 HklSample const *sample = _diffractometer->samples->current;
350 if(sample){
351 size_t dim = 3;
352 _ub.resize(dim, dim);
353 _ub.set_data_from_buffer(&(sample->UB.data[0][0]), dim, dim);
357 void TangoHKLAdapter::update_ux_uy_uz(void)
359 HklSample *sample = _diffractometer->samples->current;
361 if(sample){
362 hkl_matrix_to_euler(&sample->U, &_ux, &_uy, &_uz);
363 _ux *= HKL_RADTODEG;
364 _uy *= HKL_RADTODEG;
365 _uz *= HKL_RADTODEG;
369 void TangoHKLAdapter::update_mode_names(void)
371 HklPseudoAxisEngine *engine;
373 engine = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_r, "hkl");
374 if(engine){
375 size_t i;
376 size_t len;
378 len = HKL_LIST_LEN(engine->modes);
379 _mode_names.resize(len, 1);
380 for(i=0; i<len; ++i)
381 _mode_names.data[i] = const_cast<char *>(engine->modes[i]->name);
385 void TangoHKLAdapter::update_mode_parameters_names(void)
387 HklPseudoAxisEngine *engine;
389 engine = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_r, "hkl");
390 if (engine){
391 size_t i;
392 size_t len;
394 len = HKL_LIST_LEN(engine->mode->parameters);
395 _mode_parameters_names.resize(len, 1);
396 for(i=0; i<len; ++i)
397 _mode_parameters_names.data[i] = const_cast<char *>(engine->mode->parameters[i].name);
402 * this method update all the AxisAdapter from the proxy every 200 ms.
403 * this from_proxy get the real part from the proxy and the "sim" part
404 * from the HklAxis in simulated mode or from the proxy in real mode
405 * else it updates them from the HklAxis.
407 * every 200 ms
408 * simulated:
409 * real <- proxy
410 * sim <- HklAxis
411 * non simulated:
412 * real <- proxy
413 * sim <- proxy
414 * rest of the time
415 * real <- HklAxis
416 * simulated -> HklAxis
418 void TangoHKLAdapter::update_axis_adapters(void)
420 size_t i;
422 // first read from the proxy.
423 duration.Stop();
424 if(duration.GetDurationInMs() >= 200 && _proxies) {
425 for(size_t i=0; i<_axes.size(); ++i)
426 _axes[i].from_proxy(this->simulated);
427 duration.Start();
428 }else
429 for(i=0; i<_axes.size(); ++i)
430 _axes[i].from_HklAxis();
433 void TangoHKLAdapter::update_hkl_from_axis_adapters(void)
435 size_t i;
437 // set the axis
438 for(i=0; i<_axes.size(); ++i)
439 _axes[i].to_HklAxis();
441 // update the pseudo axes
442 if(_diffractometer && _diffractometer->samples){
443 hkl_pseudo_axis_engine_list_getter(_diffractometer->engines_r, _diffractometer->geometry_r,
444 &_diffractometer->detector, _diffractometer->samples->current);
445 hkl_pseudo_axis_engine_list_getter(_diffractometer->engines_w, _diffractometer->geometry_w,
446 &_diffractometer->detector, _diffractometer->samples->current);
447 hkl_pseudo_axis_engine_list_getter(_diffractometer->engines_r_real, _diffractometer->geometry_r_real,
448 &_diffractometer->detector_real, _diffractometer->samples->current);
449 hkl_pseudo_axis_engine_list_getter(_diffractometer->engines_w_real, _diffractometer->geometry_w_real,
450 &_diffractometer->detector_real, _diffractometer->samples->current);
454 void TangoHKLAdapter::update_HKLBuffer_from_hkl(void)
456 HklPseudoAxisEngine *engine_r;
457 HklPseudoAxisEngine *engine_w;
459 if(_diffractometer){
460 engine_r = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_r, "hkl");
461 engine_w = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_w, "hkl");
463 _hklBuffer.h_r = hkl_parameter_get_value_unit((HklParameter *)engine_r->pseudoAxes[0]);
464 _hklBuffer.k_r = hkl_parameter_get_value_unit((HklParameter *)engine_r->pseudoAxes[1]);
465 _hklBuffer.l_r = hkl_parameter_get_value_unit((HklParameter *)engine_r->pseudoAxes[2]);
467 _hklBuffer.h_w = hkl_parameter_get_value_unit((HklParameter *)engine_w->pseudoAxes[0]);
468 _hklBuffer.k_w = hkl_parameter_get_value_unit((HklParameter *)engine_w->pseudoAxes[1]);
469 _hklBuffer.l_w = hkl_parameter_get_value_unit((HklParameter *)engine_w->pseudoAxes[2]);
473 void TangoHKLAdapter::update_pseudo_axis_adapters_from_hkl(void)
475 for(size_t i=0;i<_pseudoAxisAdapters.size();++i)
476 _pseudoAxisAdapters[i]->update();
479 void TangoHKLAdapter::update_proxies_from_axis_adapters(void)
481 _proxies->command_inout(AXIS_COMMAND_STOP_NAME);
482 for(size_t i=0; i<_axes.size(); ++i)
483 _axes[i].to_proxy();
486 void TangoHKLAdapter::update_proxies_from_pseudo_axis_adapters(PseudoAxisAdapter *adapter)
488 adapter->to_proxies();
491 void TangoHKLAdapter::update_pseudo_axes_adapters_from_hkl(void)
493 size_t i, j, len;
494 HklPseudoAxisEngine *engine_r, *engine_w;
496 for(i=0; i<_pseudoAxesAdapters.size(); ++i){
497 PseudoAxesAdapter *adapter;
499 adapter = _pseudoAxesAdapters[i];
500 engine_r = _diffractometer->engines_r->engines[i];
501 engine_w = _diffractometer->engines_w->engines[i];
502 len = HKL_LIST_LEN(engine_r->pseudoAxes);
503 for(j=0; j<len; ++j){
504 adapter->_read.data[j] = hkl_parameter_get_value_unit((HklParameter *)engine_r->pseudoAxes[j]);
505 adapter->_write.data[j] = hkl_parameter_get_value_unit((HklParameter *)engine_w->pseudoAxes[j]);
509 adapter->update_state_and_status_i();
513 void TangoHKLAdapter::update_state_and_status(void)
515 Tango::DevState state;
516 std::string status;
517 std::string extra_status;
519 state = Tango::STANDBY;
520 if (this->simulated)
521 status = "Simulated Mode: Motors will NOT move.";
522 else {
523 status = "REAL Mode : Motors will REALLY move.";
525 if (!this->ready) {
526 state = Tango::FAULT;
527 extra_status += "\nCan not connect to axes proxies";
528 // update the monochromator proxy status.
529 if (!_lambdaAttributeProxy && !this->simulated) {
530 extra_status += "\nCan not connect to the lambdaAttributeProxy";
531 extra_status += "\nCheck also the lambdaAttributeProxy property";
533 } else {
534 try {
535 for(unsigned int i=0; i<_axes.size(); ++i) {
536 AxisAdapter const & axis = _axes[i];
537 std::string const & device_name = axis.get_device_name();
538 Tango::DevState tmpState = axis.get_state();
540 ::compose_state(state, tmpState);
541 if (tmpState != Tango::STANDBY)
542 extra_status += "\n" + device_name + " is in " + Tango::DevStateName[tmpState];
544 } catch(...)
546 state = Tango::FAULT;
547 extra_status += "\nCan not connect to axes proxies";
553 if (_diffractometer){
554 status += "\nSample: ";
555 if(!_diffractometer->samples->current){
556 status += "Not yet Set";
557 state = Tango::FAULT;
558 } else
559 status += _diffractometer->samples->current->name;
560 if (state == Tango::STANDBY)
561 extra_status += "\nready to compute hkl";
562 }else{
563 state = Tango::FAULT;
564 extra_status += "\nhkl core not yet initialized !!!";
566 status += "\nDiffractometer status: ";
567 status += Tango::DevStateName[state];
568 status += extra_status;
570 _state = state;
571 _status = status;
574 void TangoHKLAdapter::update(void)
576 /**********************************************
577 * CRITICAL SECTION
578 **********************************************/
579 omni_mutex_lock lock(_lock);
581 this->update_lambda();
582 this->update_axis_adapters();
583 this->update_hkl_from_axis_adapters();
584 this->update_HKLBuffer_from_hkl();
585 this->update_pseudo_axis_adapters_from_hkl();
586 this->update_pseudo_axes_adapters_from_hkl();
587 this->update_state_and_status();
588 /**********************************************
589 * END OF CRITICAL SECTION
590 **********************************************/
593 /************/
594 /* hkl part */
595 /************/
597 short & TangoHKLAdapter::get_angles_idx(void)
599 omni_mutex_lock lock(_lock);
601 return _angles_idx;
604 void TangoHKLAdapter::set_angles_idx(short idx)
606 omni_mutex_lock lock(_lock);
608 // A REVOIR
609 if(idx < (int)_angles.ydim){
610 size_t i;
611 double *values;
613 _angles_idx = idx;
614 values = &_angles.data[4 + idx * _angles.xdim];
615 for(i=0; i<_axes.size(); ++i)
616 this->write_axis_i(_axes[i], values[i]);
620 void TangoHKLAdapter::load(void)
622 this->load_1();
625 void TangoHKLAdapter::load_1(void)
627 unsigned long nb_properties;
629 // Get the Crystal Attributes properties.
630 Tango::DbData properties;
631 properties.push_back(Tango::DbDatum("Crystal"));
632 _device->get_db_device()->get_attribute_property(properties);
634 // the first one is the number of properties
635 properties[0] >> nb_properties;
637 if (nb_properties > 1) {
638 unsigned long i, j;
639 HklGeometry *geometry;
640 HklDetector detector;
642 geometry = hkl_geometry_new_copy(_diffractometer->geometry_r);
644 hkl_sample_list_clear(_diffractometer->samples);
645 for(i=1; i<=nb_properties; ++i) {
646 // skip the _ver property
647 if(!strcasecmp("_ver", properties[i].name.c_str()))
648 continue;
650 HklSample * sample;
652 // The name of the property name is the name of a crystal.
653 sample = hkl_sample_new(properties[i].name.c_str(), HKL_SAMPLE_MONOCRYSTAL);
655 // Extract the lines store in the property
656 std::vector<std::string> lines;
657 properties[i] >> lines;
659 for(j=0; j<lines.size(); j++) {
660 char *line = strdup(lines[j].c_str());
661 char *last;
662 char *key = strtok_r(line, "=", &last);
664 if (!strcmp(key,"lattice")) {
665 double a = atof(strtok_r(NULL, ";", &last));
666 double b = atof(strtok_r(NULL, ";", &last));
667 double c = atof(strtok_r(NULL, ";", &last));
668 double alpha = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
669 double beta = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
670 double gamma = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
671 int a_flag = atoi(strtok_r(NULL, ";", &last));
672 int b_flag = atoi(strtok_r(NULL, ";", &last));
673 int c_flag = atoi(strtok_r(NULL, ";", &last));
674 int alpha_flag = atoi(strtok_r(NULL, ";", &last));
675 int beta_flag = atoi(strtok_r(NULL, ";", &last));
676 int gamma_flag = atoi(strtok_r(NULL, ";", &last));
677 hkl_sample_set_lattice(sample, a, b, c, alpha, beta, gamma);
678 sample->lattice->a->not_to_fit = !a_flag;
679 sample->lattice->b->not_to_fit = !b_flag;
680 sample->lattice->c->not_to_fit = !c_flag;
681 sample->lattice->alpha->not_to_fit = !alpha_flag;
682 sample->lattice->beta->not_to_fit = !beta_flag;
683 sample->lattice->gamma->not_to_fit = !gamma_flag;
684 } else if (!strcmp(key, "uxuyuz")){
685 double ux = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
686 double uy = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
687 double uz = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
688 hkl_sample_set_U_from_euler(sample, ux, uy, uz);
689 } else if (!strcmp(key,"reflection")) {
690 unsigned int idx = 0;
691 HklSampleReflection *reflection;
693 double wavelength = atof(strtok_r(NULL, ";", &last));
694 double h = atof(strtok_r(NULL, ";", &last));
695 double k = atof(strtok_r(NULL, ";", &last));
696 double l = atof(strtok_r(NULL, ";", &last));
697 int flag = atoi(strtok_r(NULL, ";", &last));
699 // first set the geometry axes
700 while(key = strtok_r(NULL, ";", &last))
701 hkl_axis_set_value_unit(&geometry->axes[idx++], atof(key));
702 geometry->source.wave_length = wavelength;
703 detector = _diffractometer->detector;
705 reflection = hkl_sample_add_reflection(sample, geometry, &detector, h, k, l);
706 reflection->flag = flag;
708 free(line);
709 // End of key research
710 }// End for each parameters
711 hkl_sample_list_append(_diffractometer->samples, sample);
712 }// End for each property
714 hkl_geometry_free(geometry);
716 //_device->refresh_crystal_parameters();
720 void TangoHKLAdapter::save(void)
722 omni_mutex_lock lock(_lock);
724 size_t i, j, k;
725 size_t len;
726 Tango::DbData crystal_prop;
727 Tango::DbData data_put;
729 // Step 1 : clean all properties
730 // FP Le mieux serait sans doute de ne pas effacer les propriétés d'attribut
731 // avant d'avoir crée correctement un data_put.
732 crystal_prop.push_back(Tango::DbDatum("Crystal"));
733 _device->get_db_device()->get_attribute_property(crystal_prop);
734 long number_of_prop = 0;
735 crystal_prop[0] >> number_of_prop ;
736 if( number_of_prop > 0)
737 _device->get_db_device()->delete_attribute_property(crystal_prop);
739 // Step 2 : create the Crystal properties
740 Tango::DbDatum properties("Crystal");
741 // Put number of properties (= nb of samples + 1)
742 len = hkl_sample_list_len(_diffractometer->samples);
743 properties << (long)(len + 1);
744 data_put.push_back(properties);
746 // first property is the format version
747 Tango::DbDatum version("_ver");
748 version << (long)FORMAT_VERSION;
749 data_put.push_back(version);
751 // now each sample
752 for(k=0; k<len; ++k){
753 HklSample *sample;
754 std::vector<std::string> lines;
755 char line[256];
757 // the lattices values
758 sample = hkl_sample_list_get_ith(_diffractometer->samples, k);
759 double a = hkl_parameter_get_value_unit(sample->lattice->a);
760 double b = hkl_parameter_get_value_unit(sample->lattice->b);
761 double c = hkl_parameter_get_value_unit(sample->lattice->c);
762 double alpha = hkl_parameter_get_value_unit(sample->lattice->alpha);
763 double beta = hkl_parameter_get_value_unit(sample->lattice->beta);
764 double gamma = hkl_parameter_get_value_unit(sample->lattice->gamma);
765 // the fit flag
766 int a_flag = !sample->lattice->a->not_to_fit;
767 int b_flag = !sample->lattice->b->not_to_fit;
768 int c_flag = !sample->lattice->c->not_to_fit;
769 int alpha_flag = !sample->lattice->alpha->not_to_fit;
770 int beta_flag = !sample->lattice->beta->not_to_fit;
771 int gamma_flag = !sample->lattice->gamma->not_to_fit;
773 snprintf(line, 255, "lattice=%f;%f;%f;%f;%f;%f;%d;%d;%d;%d;%d;%d",
774 a, b, c, alpha, beta, gamma,
775 a_flag, b_flag, c_flag, alpha_flag, beta_flag, gamma_flag);
776 lines.push_back(line);
778 // the UxUyUz parameters
779 double ux, uy, uz;
780 hkl_matrix_to_euler(&sample->U, &ux, &uy, &uz);
781 ux *= HKL_RADTODEG;
782 uy *= HKL_RADTODEG;
783 uz *= HKL_RADTODEG;
785 snprintf(line, 255, "uxuyuz=%f;%f;%f", ux, uy, uz);
786 lines.push_back(line);
788 // the reflections
789 for(i=0; i<HKL_LIST_LEN(sample->reflections); ++i) {
790 HklSampleReflection *reflection;
792 reflection = hkl_sample_get_ith_reflection(sample, i);
793 double wavelength = reflection->geometry->source.wave_length;
794 double h = reflection->hkl.data[0];
795 double k = reflection->hkl.data[1];
796 double l = reflection->hkl.data[2];
797 int flag = reflection->flag;
799 snprintf(line, 255, "reflection=%f;%f;%f;%f;%d",
800 wavelength, h, k, l, flag);
801 // Extract values of each axes
802 for(j=0; j<HKL_LIST_LEN(reflection->geometry->axes); ++j) {
803 char pos[256];
804 double rad = hkl_axis_get_value_unit(&reflection->geometry->axes[j]);
805 snprintf(pos, 255, ";%f", rad);
806 strncat(line, pos, 255);
808 lines.push_back(line);
811 // Try to create property
812 // Get crystal name
813 Tango::DbDatum property(sample->name);
814 property << lines;
815 data_put.push_back(property);
818 //update database for this property
819 _device->get_db_device()->put_attribute_property(data_put);
822 /***************/
823 /* sample part */
824 /***************/
826 char const *TangoHKLAdapter::get_sample_name(void)
828 omni_mutex_lock lock(_lock);
830 HklSample *sample = _diffractometer->samples->current;
831 if(sample)
832 return sample->name;
833 else
834 return "";
837 void TangoHKLAdapter::set_current_sample(char const * name)
839 omni_mutex_lock lock(_lock);
841 HklSample *last;
843 last = _diffractometer->samples->current;
844 if (HKL_SUCCESS == hkl_sample_list_select_current(_diffractometer->samples, name))
845 if (last != _diffractometer->samples->current){
846 this->update_ub();
847 this->update_ux_uy_uz();
848 this->update_reflections_angles();
849 this->update_sample_reflections();
850 this->update_state_and_status();
854 void TangoHKLAdapter::get_sample_lattices(double *a, double *b, double *c,
855 double *alpha, double *beta, double *gamma,
856 double *a_star, double *b_star, double *c_star,
857 double *alpha_star, double *beta_star, double *gamma_star)
859 omni_mutex_lock lock(_lock);
861 HklSample * sample = _diffractometer->samples->current;
862 if (!sample)
863 return;
865 HklLattice const *lattice = sample->lattice;
866 HklLattice *reciprocal = hkl_lattice_new_copy(lattice);
868 hkl_lattice_reciprocal(lattice, reciprocal);
870 // direct space
871 *a = hkl_parameter_get_value_unit(lattice->a);
872 *b = hkl_parameter_get_value_unit(lattice->b);
873 *c = hkl_parameter_get_value_unit(lattice->c);
874 *alpha = hkl_parameter_get_value_unit(lattice->alpha);
875 *beta = hkl_parameter_get_value_unit(lattice->beta);
876 *gamma = hkl_parameter_get_value_unit(lattice->gamma);
878 // reciprocal space
879 *a_star = hkl_parameter_get_value_unit(reciprocal->a);
880 *b_star = hkl_parameter_get_value_unit(reciprocal->b);
881 *c_star = hkl_parameter_get_value_unit(reciprocal->c);
882 *alpha_star = hkl_parameter_get_value_unit(reciprocal->alpha);
883 *beta_star = hkl_parameter_get_value_unit(reciprocal->beta);
884 *gamma_star = hkl_parameter_get_value_unit(reciprocal->gamma);
886 hkl_lattice_free(reciprocal);
889 void TangoHKLAdapter::set_sample_Ux(double ux)
891 HklSample *sample;
893 sample = _diffractometer->samples->current;
894 if (sample){
895 if (HKL_SUCCESS == hkl_sample_set_U_from_euler(sample,
896 ux * HKL_DEGTORAD,
897 _uy * HKL_DEGTORAD,
898 _uz * HKL_DEGTORAD)){
899 _ux = ux;
900 this->update_ub();
901 }else
902 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this Ux value",
903 "Set a correct value");
907 void TangoHKLAdapter::set_sample_Uy(double uy)
909 HklSample *sample;
911 sample = _diffractometer->samples->current;
912 if (sample){
913 if (HKL_SUCCESS == hkl_sample_set_U_from_euler(sample,
914 _ux * HKL_DEGTORAD,
915 uy * HKL_DEGTORAD,
916 _uz * HKL_DEGTORAD)){
917 _uy = uy;
918 this->update_ub();
919 }else
920 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this Uy value",
921 "Set a correct value");
925 void TangoHKLAdapter::set_sample_Uz(double uz)
927 HklSample *sample;
929 sample = _diffractometer->samples->current;
930 if (sample){
931 if (HKL_SUCCESS == hkl_sample_set_U_from_euler(sample,
932 _ux * HKL_DEGTORAD,
933 _uy * HKL_DEGTORAD,
934 uz * HKL_DEGTORAD)){
935 _uz = uz;
936 this->update_ub();
937 }else
938 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this Uz value",
939 "Set a correct value");
943 void TangoHKLAdapter::add_new_sample(std::string const & name)
945 omni_mutex_lock lock(_lock);
947 HklSample *sample = hkl_sample_new(name.c_str(), HKL_SAMPLE_MONOCRYSTAL);
949 if (!hkl_sample_list_append(_diffractometer->samples, sample)){
950 hkl_sample_free(sample);
951 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not add a sample with this name",
952 "A sample with the same name is already present in the sample list");
956 void TangoHKLAdapter::copy_sample_as(Tango::DevString copy_name)
958 omni_mutex_lock lock(_lock);
960 HklSample *sample;
961 HklSample const *current;
963 current = _diffractometer->samples->current;
964 if(!current)
965 TANGO_EXCEPTION_THROW_WITHOUT_LOG("No current sample set",
966 "Please set a current sample");
968 sample = hkl_sample_list_get_by_name(_diffractometer->samples, copy_name);
969 if (sample)
970 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not add a sample with this name",
971 "A sample with the same name is already present in the sample list");
973 sample = hkl_sample_new_copy(current);
974 if(sample){
975 hkl_sample_set_name(sample, copy_name);
976 hkl_sample_list_append(_diffractometer->samples, sample);
980 void TangoHKLAdapter::del_sample(void)
982 omni_mutex_lock lock(_lock);
984 HklSampleList *samples = _diffractometer->samples;
985 hkl_sample_list_del(samples, samples->current);
987 // add a default sample if no more sample in the list
988 if(hkl_sample_list_len(samples) == 0){
989 HklSample *sample = hkl_sample_new("default", HKL_SAMPLE_MONOCRYSTAL);
990 samples->current = hkl_sample_list_append(samples, sample);
991 }else
992 samples->current = hkl_sample_list_get_ith(samples, 0);
993 this->update_ub();
994 this->update_ux_uy_uz();
995 this->update_reflections_angles();
996 this->update_sample_reflections();
999 void TangoHKLAdapter::set_lattice(const Tango::DevVarDoubleArray *argin)
1001 omni_mutex_lock lock(_lock);
1003 if (argin && argin->length() != 6)
1004 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1005 "Did not receive the exact amount of crystal parameters: A, B, C, alpha, beta, gamma");
1007 HklSample *sample = _diffractometer->samples->current;
1008 if (HKL_FAIL == hkl_sample_set_lattice(sample,
1009 (*argin)[0],(*argin)[1], (*argin)[2],
1010 (*argin)[3] * HKL_DEGTORAD,
1011 (*argin)[4] * HKL_DEGTORAD,
1012 (*argin)[5] * HKL_DEGTORAD))
1014 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this lattice combination.",
1015 "Please set a good combination");
1016 this->update_ub();
1017 this->update_reflections_angles();
1020 void TangoHKLAdapter::add_reflection(void)
1022 omni_mutex_lock lock(_lock);
1024 HklSample *sample = _diffractometer->samples->current;
1026 if(sample){
1027 double h, k, l;
1028 HklPseudoAxisEngine *engine;
1029 HklSampleReflection *ref;
1031 engine = hkl_pseudo_axis_engine_list_get_by_name(
1032 _diffractometer->engines_r, "hkl");
1034 h = hkl_parameter_get_value_unit((HklParameter *)engine->pseudoAxes[0]);
1035 k = hkl_parameter_get_value_unit((HklParameter *)engine->pseudoAxes[1]);
1036 l = hkl_parameter_get_value_unit((HklParameter *)engine->pseudoAxes[2]);
1038 ref = hkl_sample_add_reflection(sample,
1039 _diffractometer->geometry_r,
1040 &_diffractometer->detector,
1041 h, k, l);
1042 if(ref){
1043 this->update_reflections_angles();
1044 this->update_sample_reflections();
1049 void TangoHKLAdapter::del_reflection(Tango::DevShort argin)
1051 omni_mutex_lock lock(_lock);
1053 if (HKL_FAIL == hkl_sample_del_reflection(_diffractometer->samples->current, argin))
1054 TANGO_EXCEPTION_THROW_WITHOUT_LOG("index out of range",
1055 "change the reflection index");
1056 this->update_reflections_angles();
1057 this->update_sample_reflections();
1060 void TangoHKLAdapter::get_sample_reflection(int idx, Tango::DevVarDoubleArray *argout)
1062 omni_mutex_lock lock(_lock);
1064 HklSample *sample = _diffractometer->samples->current;
1065 if (sample){
1066 HklSampleReflection * r = hkl_sample_get_ith_reflection(sample, idx);
1067 if (r) {
1068 size_t i;
1069 size_t len = HKL_LIST_LEN(r->geometry->axes);
1071 // now that we can get the reflection set size of the argout
1072 argout->length(5 + len);
1073 (*argout)[0] = r->hkl.data[0];
1074 (*argout)[1] = r->hkl.data[1];
1075 (*argout)[2] = r->hkl.data[2];
1076 (*argout)[3] = r->flag;
1077 (*argout)[4] = r->flag;
1079 // now get the axes values
1080 HklAxis *axes = r->geometry->axes;
1081 for(i=0; i<len; i++)
1082 (*argout)[i+5] = hkl_axis_get_value_unit(&axes[i]);
1087 void TangoHKLAdapter::set_sample_reflection(const Tango::DevVarDoubleArray *argin)
1089 omni_mutex_lock lock(_lock);
1091 HklSample *sample = _diffractometer->samples->current;
1092 if (sample
1093 && argin->length() == 6) {
1094 HklSampleReflection *r = hkl_sample_get_ith_reflection(sample, (size_t)(*argin)[0]);
1095 if(r){
1096 hkl_sample_reflection_set_hkl(r, (*argin)[1], (*argin)[2], (*argin)[3]);
1097 hkl_sample_reflection_set_flag(r, (int)(*argin)[5]);
1098 this->update_sample_reflections();
1099 this->update_reflections_angles();
1104 void TangoHKLAdapter::set_sample_reflections(Matrix<double> const & img)
1106 omni_mutex_lock lock(_lock);
1108 HklSample *sample = _diffractometer->samples->current;
1109 if (sample
1110 && img.xdim == _sample_reflections.xdim
1111 && img.ydim == _sample_reflections.ydim) {
1113 size_t i = 0;
1114 size_t j = 0;
1115 for(i=0; i<HKL_LIST_LEN(sample->reflections); ++i) {
1116 HklSampleReflection *r;
1118 r = hkl_sample_get_ith_reflection(sample, i);
1119 if (r) {
1120 hkl_sample_reflection_set_hkl(r, img.data[j+1], img.data[j+2], img.data[j+3]);
1121 hkl_sample_reflection_set_flag(r, (int)img.data[j+5]);
1123 j += _sample_reflections.xdim;
1125 this->update_sample_reflections();
1126 this->update_reflections_angles();
1130 double TangoHKLAdapter::affine_sample(std::string name)
1132 omni_mutex_lock lock(_lock);
1134 HklSample *sample;
1135 double res = 0.;
1137 sample = hkl_sample_list_get_by_name(_diffractometer->samples, name.c_str());
1138 if(sample){
1139 HklSample *tmp;
1141 // check if the affine sample is already in the HklSampleList
1142 std::string name = sample->name;
1143 name += "(affine)";
1144 tmp = hkl_sample_list_get_by_name(_diffractometer->samples, name.c_str());
1145 hkl_sample_list_del(_diffractometer->samples, tmp);
1147 tmp = hkl_sample_new_copy(sample);
1148 hkl_sample_set_name(tmp, name.c_str());
1149 res = hkl_sample_affine(tmp);
1151 hkl_sample_list_append(_diffractometer->samples, tmp);
1152 _diffractometer->samples->current = tmp;
1154 this->update_ub();
1155 this->update_ux_uy_uz();
1156 this->update_reflections_angles();
1159 return res;
1163 std::vector<std::string> TangoHKLAdapter::get_samples_names(void)
1165 omni_mutex_lock lock(_lock);
1167 std::vector<std::string> names;
1168 size_t i, len;
1169 HklSampleList *samples = _diffractometer->samples;
1171 len = hkl_sample_list_len(samples);
1172 for(i=0; i<len; ++i)
1173 names.push_back(hkl_sample_list_get_ith(samples, i)->name);
1175 return names;
1178 void TangoHKLAdapter::get_sample_parameter_values(Tango::DevVarDoubleStringArray *argout)
1180 omni_mutex_lock lock(_lock);
1182 HklSample *sample;
1183 HklParameter *parameter = NULL;
1184 std::string name;
1186 //check parameters
1187 if (argout->svalue.length() != 1)
1188 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1189 "only one string = parameter name");
1191 sample = _diffractometer->samples->current;
1192 if(sample){
1193 //parameters OK
1194 name = argout->svalue[0];
1195 if(name == "a")
1196 parameter = sample->lattice->a;
1197 else if(name == "b")
1198 parameter = sample->lattice->b;
1199 else if(name == "c")
1200 parameter = sample->lattice->c;
1201 else if(name == "alpha")
1202 parameter = sample->lattice->alpha;
1203 else if(name == "beta")
1204 parameter = sample->lattice->beta;
1205 else if(name == "gamma")
1206 parameter = sample->lattice->gamma;
1208 if (parameter){
1209 argout->dvalue[0] = parameter->range.min;
1210 argout->dvalue[1] = parameter->range.max;
1211 argout->dvalue[2] = !parameter->not_to_fit;
1212 }else
1213 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Wrong parameter name",
1214 "Select: a, b, c, alpha, beta, gamma");
1218 void TangoHKLAdapter::set_sample_parameter_values(Tango::DevVarDoubleStringArray const *argin)
1220 omni_mutex_lock lock(_lock);
1222 HklSample *sample;
1223 HklParameter *parameter = NULL;
1224 std::string name;
1226 // check parameters
1227 if(argin->dvalue.length() != 3)
1228 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1229 "set_crystal_parameter_values did not receive the right amount of scalar parameters: min, max, flag");
1230 if((argin->svalue.length() ) != 1)
1231 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1232 "set_crystal_parameter_values did not receive the right amount of string parameters: parameter name");
1234 // parameters OK
1235 sample = _diffractometer->samples->current;
1236 if(!sample)
1237 TANGO_EXCEPTION_THROW_WITHOUT_LOG("No current sample set",
1238 "Please set a current sample");
1240 name = argin->svalue[0];
1241 if(name == "a")
1242 parameter = sample->lattice->a;
1243 else if(name == "b")
1244 parameter = sample->lattice->b;
1245 else if(name == "c")
1246 parameter = sample->lattice->c;
1247 else if(name == "alpha")
1248 parameter = sample->lattice->alpha;
1249 else if(name == "beta")
1250 parameter = sample->lattice->beta;
1251 else if(name == "gamma")
1252 parameter = sample->lattice->gamma;
1254 if (parameter){
1255 parameter->range.min = argin->dvalue[0];
1256 parameter->range.max = argin->dvalue[1];
1257 parameter->not_to_fit = !argin->dvalue[2];
1258 }else
1259 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Wrong parameter name",
1260 "Select: a, b, c, alpha, beta, gamma");
1261 this->update_ub();
1262 this->update_ux_uy_uz();
1263 this->update_reflections_angles();
1266 void TangoHKLAdapter::compute_u(const Tango::DevVarLongArray *argin)
1268 omni_mutex_lock lock(_lock);
1270 HklSample *sample;
1272 // is parameter ok ?
1273 if (argin->length() != 2)
1274 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Need exactly two reflections indexes",
1275 "use the right number of parameters");
1277 sample = _diffractometer->samples->current;
1278 if (!sample)
1279 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not compute the U matrix without current sample set.",
1280 "Set a current sample");
1282 if (hkl_sample_compute_UB_busing_levy(sample, (*argin)[0], (*argin)[1]))
1283 TANGO_EXCEPTION_THROW_WITHOUT_LOG("can not compute the UB matrix using thoses reflections index",
1284 "Use other reflections");
1285 this->update_ub();
1286 this->update_ux_uy_uz();
1289 /*****************/
1290 /* hkl mode part */
1291 /*****************/
1293 char const *TangoHKLAdapter::read_mode(void)
1295 omni_mutex_lock lock(_lock);
1297 HklPseudoAxisEngine *engine;
1298 engine = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_r, "hkl");
1299 if (engine && engine->mode)
1300 return engine->mode->name;
1301 else
1302 return "";
1305 void TangoHKLAdapter::write_mode(Tango::DevString argin)
1307 omni_mutex_lock lock(_lock);
1309 HklPseudoAxisEngine *engine_r;
1310 HklPseudoAxisEngine *engine_w;
1311 engine_r = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_r, "hkl");
1312 engine_w = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_w, "hkl");
1313 if (engine_r && engine_w){
1314 size_t i;
1316 for(i=0; i<HKL_LIST_LEN(engine_r->modes); ++i)
1317 if(!strcasecmp(argin, engine_r->modes[i]->name))
1318 break;
1319 if(i<HKL_LIST_LEN(engine_r->modes)){
1320 hkl_pseudo_axis_engine_select_mode(engine_r, i);
1321 hkl_pseudo_axis_engine_select_mode(engine_w, i);
1322 this->update_mode_parameters_names();
1323 } else
1324 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Wrong mode name.",
1325 "Please set a correct mode name");
1327 }else
1328 TANGO_EXCEPTION_THROW_WITHOUT_LOG("No current mode set.",
1329 "Please set a mode");
1333 std::vector<std::string> TangoHKLAdapter::get_mode_parameters_names(void)
1335 omni_mutex_lock lock(_lock);
1337 std::vector<std::string> names;
1338 HklPseudoAxisEngine *engine;
1340 engine = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_r, "hkl");
1341 if (engine){
1342 size_t i;
1344 for(i=0; i<engine->getset->parameters_len; ++i)
1345 names.push_back(engine->getset->parameters[i].name);
1346 }else
1347 TANGO_EXCEPTION_THROW_WITHOUT_LOG("No current mode set.",
1348 "Please set a mode");
1350 return names;
1354 void TangoHKLAdapter::get_mode_parameters_values(Tango::DevVarDoubleStringArray *argout)
1356 omni_mutex_lock lock(_lock);
1358 HklPseudoAxisEngine *engine;
1360 engine = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_r, "hkl");
1361 if (engine && engine->mode){
1362 size_t i;
1363 size_t len = HKL_LIST_LEN(engine->mode->parameters);
1365 argout->svalue.length(len);
1366 argout->dvalue.length(len);
1367 for(i=0; i<len; ++i){
1368 argout->svalue[i] = CORBA::string_dup(engine->mode->parameters[i].name);
1369 argout->dvalue[i] = hkl_parameter_get_value_unit(&engine->mode->parameters[i]);
1371 }else
1372 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set the current Mode parameters values without a current mode set.",
1373 "");
1376 void TangoHKLAdapter::set_mode_parameters_values(const Tango::DevVarDoubleStringArray *argin)
1378 omni_mutex_lock lock(_lock);
1380 if(argin->svalue.length() != argin->dvalue.length())
1381 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1382 "set_mode_parameters_values did not receive the same amount between string and double values");
1384 HklPseudoAxisEngine *engine_r;
1385 HklPseudoAxisEngine *engine_w;
1387 engine_r = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_r, "hkl");
1388 engine_w = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_w, "hkl");
1389 if (engine_r && engine_w){
1390 size_t i;
1391 size_t len;
1393 len = argin->svalue.length();
1394 if (HKL_LIST_LEN(engine_r->mode->parameters) != len)
1395 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Not the right number of parameter",
1396 "gives the right number of parameters");
1398 for(i=0; i<len; ++i){
1399 double value = argin->dvalue[i];
1400 char const *name = argin->svalue[i];
1401 if(!strcmp(name, engine_r->mode->parameters[i].name)){
1402 hkl_parameter_set_value_unit(&engine_r->mode->parameters[i], value);
1403 hkl_parameter_set_value_unit(&engine_w->mode->parameters[i], value);
1406 }else
1407 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set the current Mode parameters values without a current mode set.",
1408 "");
1411 /*************/
1412 /* Axis part */
1413 /*************/
1415 void TangoHKLAdapter::read_axis(int idx, double & read, double & write)
1417 omni_mutex_lock lock(_lock);
1419 AxisAdapter & axis = _axes[idx];
1420 read = axis.get_read();
1421 write = axis.get_write();
1424 void TangoHKLAdapter::stop_all_axis(void)
1426 #ifdef WRITE_TO_PROXY_ALLOWED
1427 _proxies->command_inout(AXIS_COMMAND_STOP_NAME, true);
1428 #endif
1431 void TangoHKLAdapter::write_axis(AxisAdapter & axis, double value)
1433 omni_mutex_lock lock(_lock);
1435 this->write_axis_i(axis, value);
1438 void TangoHKLAdapter::write_axis_i(AxisAdapter & axis, double value)
1440 axis._read = axis._write = value;
1441 hkl_axis_set_value_unit(axis._axis_r, value);
1442 hkl_axis_set_value_unit(axis._axis_w, value);
1445 /*******************/
1446 /* pseudoAxis part */
1447 /*******************/
1449 std::vector<std::string> TangoHKLAdapter::pseudo_axis_get_names(void)
1451 omni_mutex_lock lock(_lock);
1453 std::vector<std::string> names;
1454 size_t i, j;
1456 for(i=0; i<HKL_LIST_LEN(_diffractometer->engines_r_real->engines); ++i){
1457 HklPseudoAxisEngine *engine;
1459 engine = _diffractometer->engines_r_real->engines[i];
1460 for(j=0; j<HKL_LIST_LEN(engine->pseudoAxes); ++j)
1461 names.push_back(((HklParameter *)(&engine->pseudoAxes[j]))->name);
1464 return names;
1467 PseudoAxisAdapter *TangoHKLAdapter::pseudo_axis_buffer_new(char const *name)
1469 omni_mutex_lock lock(_lock);
1471 PseudoAxisAdapter * buffer = NULL;
1472 HklPseudoAxis *pseudo_r;
1473 HklPseudoAxis *pseudo_w;
1475 pseudo_r = hkl_pseudo_axis_engine_list_get_pseudo_axis_by_name(
1476 _diffractometer->engines_r_real, name);
1477 pseudo_w = hkl_pseudo_axis_engine_list_get_pseudo_axis_by_name(
1478 _diffractometer->engines_w_real, name);
1480 if(pseudo_r && pseudo_w) {
1483 buffer = new PseudoAxisAdapter(*this, pseudo_r, pseudo_w);
1484 _pseudoAxisAdapters.push_back(buffer);
1486 catch (Tango::DevFailed)
1488 delete buffer;
1489 buffer = NULL;
1492 return buffer;
1495 void TangoHKLAdapter::pseudo_axis_init(PseudoAxisAdapter *buffer, bool init)
1497 omni_mutex_lock lock(_lock);
1499 hkl_pseudo_axis_engine_init(buffer->_pseudo_r->engine, _diffractometer->geometry_r_real,
1500 &_diffractometer->detector_real, _diffractometer->samples->current);
1502 hkl_pseudo_axis_engine_init(buffer->_pseudo_w->engine, _diffractometer->geometry_w_real,
1503 &_diffractometer->detector_real, _diffractometer->samples->current);
1507 void TangoHKLAdapter::pseudo_axis_write(PseudoAxisAdapter * buffer, double value)
1509 omni_mutex_lock lock(_lock);
1511 int res = HKL_FAIL;
1513 HklPseudoAxisEngineList *engines_w_real = _diffractometer->engines_w_real;
1514 HklPseudoAxisEngine *engine = buffer->_pseudo_w->engine;
1515 HklGeometry *geometry_w_real = _diffractometer->geometry_w_real;
1516 HklDetector *detector_real = &_diffractometer->detector_real;
1517 HklSample *sample = _diffractometer->samples->current;
1519 hkl_parameter_set_value_unit((HklParameter *)buffer->_pseudo_w, value);
1520 res = hkl_pseudo_axis_engine_setter(buffer->_pseudo_w->engine, geometry_w_real, detector_real, sample);
1521 //hkl_pseudo_axis_engine_fprintf(stdout, buffer->_pseudo_w->engine);
1522 if (HKL_SUCCESS == res){
1523 hkl_geometry_init_geometry(geometry_w_real, engine->engines->geometries->geometries[0]);
1524 hkl_pseudo_axis_engine_list_getter(engines_w_real, geometry_w_real, detector_real, sample);
1526 _angles_idx = 0;
1527 this->update_angles();
1528 buffer->to_proxies();
1529 this->update_axis_adapters();
1530 this->update_pseudo_axis_adapters_from_hkl();
1531 this->update_pseudo_axes_adapters_from_hkl();
1532 }else
1533 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not write on this pseudo axis",
1534 "Check the sample");
1538 Tango::DevString *TangoHKLAdapter::pseudo_axis_get_mode(PseudoAxisAdapter const *buffer)
1540 omni_mutex_lock lock(_lock);
1542 return const_cast<Tango::DevString *>(&buffer->_pseudo_r->engine->mode->name);
1545 void TangoHKLAdapter::pseudo_axis_set_mode(PseudoAxisAdapter *buffer, Tango::DevString const & mode)
1547 omni_mutex_lock lock(_lock);
1549 size_t i, len;
1551 len = HKL_LIST_LEN(buffer->_pseudo_r->engine->modes);
1552 for(i=0; i<len; ++i)
1553 if(!strcasecmp(mode, buffer->_pseudo_r->engine->modes[i]->name))
1554 break;
1555 if(i<len){
1556 hkl_pseudo_axis_engine_select_mode(buffer->_pseudo_r->engine, i);
1557 hkl_pseudo_axis_engine_select_mode(buffer->_pseudo_w->engine, i);
1561 void TangoHKLAdapter::pseudo_axis_get_mode_parameters(PseudoAxisAdapter *buffer, Tango::DevVarDoubleStringArray *argout)
1563 omni_mutex_lock lock(_lock);
1565 HklPseudoAxisEngine *engine = buffer->_pseudo_r->engine;
1566 if (engine && engine->mode){
1567 size_t i;
1568 size_t len = HKL_LIST_LEN(engine->mode->parameters);
1570 argout->svalue.length(len);
1571 argout->dvalue.length(len);
1572 for(i=0; i<len; ++i){
1573 argout->svalue[i] = CORBA::string_dup(engine->mode->parameters[i].name);
1574 argout->dvalue[i] = hkl_parameter_get_value_unit(&engine->mode->parameters[i]);
1576 }else
1577 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not get the current Mode parameters values without a current mode set.",
1578 "");
1581 void TangoHKLAdapter::pseudo_axis_set_mode_parameters(PseudoAxisAdapter *buffer, const Tango::DevVarDoubleStringArray *argin)
1583 omni_mutex_lock lock(_lock);
1585 if(argin->svalue.length() != argin->dvalue.length())
1586 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1587 "set_mode_parameters_values did not receive the same amount between string and double values");
1589 HklPseudoAxisEngine *engine_r = buffer->_pseudo_r->engine;
1590 HklPseudoAxisEngine *engine_w = buffer->_pseudo_w->engine;
1591 if (engine_r && engine_w){
1592 size_t i;
1593 size_t len;
1595 len = argin->svalue.length();
1596 if (HKL_LIST_LEN(engine_r->mode->parameters) != len)
1597 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Not the right number of parameter",
1598 "gives the right number of parameters");
1600 for(i=0; i<len; ++i){
1601 double value = argin->dvalue[i];
1602 char const *name = argin->svalue[i];
1603 if(!strcmp(name, engine_r->mode->parameters[i].name)){
1604 hkl_parameter_set_value_unit(&engine_r->mode->parameters[i], value);
1605 hkl_parameter_set_value_unit(&engine_w->mode->parameters[i], value);
1608 }else
1609 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set the current Mode parameters values without a current mode set.",
1610 "");
1613 /*******************/
1614 /* pseudoAxes part */
1615 /*******************/
1617 PseudoAxesAdapter *TangoHKLAdapter::pseudo_axes_adapter_get_by_name(std::string const & name)
1619 //omni_mutex_lock lock(_lock);
1621 unsigned int i;
1622 PseudoAxesAdapter *adapter = NULL;
1624 for(i=0; i<_pseudoAxesAdapters.size(); ++i)
1625 if(_pseudoAxesAdapters[i]->get_name() == name){
1626 adapter = _pseudoAxesAdapters[i];
1627 break;
1629 return adapter;
1633 void TangoHKLAdapter::pseudo_axes_write(size_t idx, Matrix<double> const & write)
1635 omni_mutex_lock lock(_lock);
1637 size_t i, len;
1638 int res = HKL_FAIL;
1639 HklPseudoAxisEngineList *engines_r, *engines_w;
1640 HklGeometry *geometry_r, *geometry_w;
1641 HklDetector *detector;
1642 HklSample *sample;
1644 engines_r = _diffractometer->engines_r;
1645 engines_w = _diffractometer->engines_w;
1646 len = HKL_LIST_LEN(engines_w->engines[idx]->pseudoAxes);
1648 geometry_r = _diffractometer->geometry_r;
1649 geometry_w = _diffractometer->geometry_w;
1651 detector = &_diffractometer->detector;
1653 sample = _diffractometer->samples->current;
1655 for(i=0; i<len; ++i)
1656 hkl_parameter_set_value_unit((HklParameter *)(engines_w->engines[idx]->pseudoAxes[i]), write.data[i]);
1658 res = hkl_pseudo_axis_engine_setter(engines_w->engines[idx], geometry_w, detector, sample);
1660 if (HKL_SUCCESS == res){
1661 hkl_geometry_init_geometry(geometry_w, engines_w->geometries->geometries[0]);
1662 hkl_pseudo_axis_engine_list_getter(engines_w, geometry_w, detector, sample);
1663 if(this->simulated){
1664 hkl_geometry_init_geometry(geometry_r, engines_w->geometries->geometries[0]);
1665 hkl_pseudo_axis_engine_list_getter(engines_r, geometry_r, detector, sample);
1668 _angles_idx = 0;
1669 this->update_angles();
1670 this->update_axis_adapters();
1671 this->update_pseudo_axis_adapters_from_hkl();
1672 this->update_pseudo_axes_adapters_from_hkl();
1673 }else
1674 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not write on this pseudo axis",
1675 "Check the sample");
1679 Tango::DevString *TangoHKLAdapter::pseudo_axes_get_mode(size_t idx)
1681 omni_mutex_lock lock(_lock);
1683 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1684 if(engine->mode)
1685 return const_cast<Tango::DevString *>(&engine->mode->name);
1686 else
1687 return NULL;
1690 void TangoHKLAdapter::pseudo_axes_set_mode(size_t idx, const Tango::DevString name)
1692 omni_mutex_lock lock(_lock);
1694 size_t i;
1695 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1697 // check if we try to set the same mode than the current one
1698 if (engine->mode)
1699 if(!strcasecmp(name, engine->mode->name))
1700 return;
1702 // no so set the mode if possible
1703 size_t len = HKL_LIST_LEN(engine->modes);
1704 for(i=0; i<len; ++i)
1705 if(!strcasecmp(name, engine->modes[i]->name))
1706 break;
1707 if(i<len){
1708 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_r->engines[idx], i);
1709 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_w->engines[idx], i);
1710 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_r_real->engines[idx], i);
1711 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_w_real->engines[idx], i);
1712 _pseudoAxesAdapters[idx]->update_axes_i(engine);
1713 _pseudoAxesAdapters[idx]->update_state_and_status_i();
1717 Matrix<char *> & TangoHKLAdapter::pseudo_axes_get_mode_parameters_names(size_t idx)
1719 omni_mutex_lock lock(_lock);
1721 size_t i;
1722 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1723 size_t len = HKL_LIST_LEN(engine->mode->parameters);
1724 PseudoAxesAdapter *adapter = _pseudoAxesAdapters[idx];
1725 adapter->_mode_parameters_names.resize(len, 1);
1726 for(i=0; i<len; ++i)
1727 adapter->_mode_parameters_names.data[i] = const_cast<char *>(engine->mode->parameters[i].name);
1728 return adapter->_mode_parameters_names;
1731 Matrix<double> const & TangoHKLAdapter::pseudo_axes_get_mode_parameters(size_t idx)
1733 omni_mutex_lock lock(_lock);
1735 size_t i;
1736 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1737 size_t len = HKL_LIST_LEN(engine->mode->parameters);
1738 PseudoAxesAdapter *adapter = _pseudoAxesAdapters[idx];
1739 adapter->_mode_parameters.resize(len, 1);
1740 for(i=0; i<len; ++i)
1741 adapter->_mode_parameters.data[i] = hkl_parameter_get_value_unit(&engine->mode->parameters[i]);
1742 return adapter->_mode_parameters;
1745 void TangoHKLAdapter::pseudo_axes_set_mode_parameters(size_t idx, Matrix<double> const & values)
1747 omni_mutex_lock lock(_lock);
1749 size_t i;
1750 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1751 size_t len = HKL_LIST_LEN(engine->mode->parameters);
1752 if(len == values.xdim)
1753 for(i=0; i<len; ++i){
1754 double & value = values.data[i];
1756 hkl_parameter_set_value_unit(&_diffractometer->engines_r->engines[idx]->mode->parameters[i],
1757 value);
1758 hkl_parameter_set_value_unit(&_diffractometer->engines_w->engines[idx]->mode->parameters[i],
1759 value);
1760 hkl_parameter_set_value_unit(&_diffractometer->engines_r_real->engines[idx]->mode->parameters[i],
1761 value);
1762 hkl_parameter_set_value_unit(&_diffractometer->engines_w_real->engines[idx]->mode->parameters[i],
1763 value);
1767 void TangoHKLAdapter::pseudo_axes_init(size_t idx)
1769 omni_mutex_lock lock(_lock);
1771 HklPseudoAxisEngine *engine_r = _diffractometer->engines_r->engines[idx];
1772 HklPseudoAxisEngine *engine_w = _diffractometer->engines_w->engines[idx];
1773 HklPseudoAxisEngine *engine_r_real = _diffractometer->engines_r_real->engines[idx];
1774 HklPseudoAxisEngine *engine_w_real = _diffractometer->engines_w_real->engines[idx];
1776 hkl_pseudo_axis_engine_init(engine_r, _diffractometer->geometry_r,
1777 &_diffractometer->detector, _diffractometer->samples->current);
1778 hkl_pseudo_axis_engine_init(engine_w, _diffractometer->geometry_w,
1779 &_diffractometer->detector, _diffractometer->samples->current);
1780 hkl_pseudo_axis_engine_init(engine_r_real, _diffractometer->geometry_r_real,
1781 &_diffractometer->detector_real, _diffractometer->samples->current);
1782 hkl_pseudo_axis_engine_init(engine_w_real, _diffractometer->geometry_w_real,
1783 &_diffractometer->detector_real, _diffractometer->samples->current);
1786 void TangoHKLAdapter::pseudo_axes_add_dynamic_attributes(size_t idx)
1788 //omni_mutex_lock lock(_lock);
1790 size_t i, j;
1792 // check if all the PseudoAxes were instantiated
1793 for(i=0; i<_pseudoAxesAdapters.size(); ++i)
1794 if(!_pseudoAxesAdapters[i]->_device)
1795 return;
1798 * we need to attach the dynamic attributes after all instance of
1799 * the PseudoAxes devices were started. otherwise it cause problem.
1801 for(i=0; i<_pseudoAxesAdapters.size(); ++i){
1802 PseudoAxesAdapter *adapter = _pseudoAxesAdapters[i];
1804 for(j=0; j<adapter->_dynamic_attribute_pseudo_axes_axis.size(); ++j)
1805 adapter->_device->add_attribute(adapter->_dynamic_attribute_pseudo_axes_axis[j]);
1809 void TangoHKLAdapter::pseudo_axes_remove_dynamic_attributes(size_t idx)
1811 size_t i;
1812 PseudoAxesAdapter *adapter;
1814 adapter = _pseudoAxesAdapters[idx];
1815 for(i=0; i<adapter->_dynamic_attribute_pseudo_axes_axis.size(); ++i)
1816 adapter->_device->remove_attribute(adapter->_dynamic_attribute_pseudo_axes_axis[i]);
1819 void TangoHKLAdapter::pseudo_axes_create_and_start_devices(void)
1821 omni_mutex_lock lock(_lock);
1823 unsigned int i, j;
1825 Tango::Util *tg = Tango::Util::instance();
1826 Tango::Database *db = tg->get_database();
1827 for(i=0; i<_pseudoAxesAdapters.size(); ++i){
1828 std::string dev_name = _pseudoAxesAdapters[i]->get_proxy_name();
1830 // first check if the device is already defined in the database
1831 try{
1832 Tango::DbDevImportInfo my_device_import_info;
1834 my_device_import_info = db->import_device(dev_name);
1835 } catch (Tango::DevFailed &) {
1836 Tango::DbDevInfo my_device_info;
1838 // add the device to the database
1839 my_device_info.name = dev_name.c_str();
1840 my_device_info._class = "PseudoAxes";
1841 my_device_info.server = tg->get_ds_name().c_str();
1843 db->add_device(my_device_info);
1845 // add the right properties to that device
1846 Tango::DbDatum DiffractometerProxy("DiffractometerProxy"), EngineName("EngineName");
1847 Tango::DbData properties;
1848 DiffractometerProxy << _device->name();
1849 EngineName << _pseudoAxesAdapters[i]->get_name();
1850 properties.push_back(DiffractometerProxy);
1851 properties.push_back(EngineName);
1852 db->put_device_property(dev_name,properties);
1855 // now start the device
1856 const std::vector<Tango::DeviceClass *> *cl_list = tg->get_class_list();
1857 for(j=0; j<cl_list->size(); ++j){
1858 if((*cl_list)[j]->get_name() == "PseudoAxes"){
1859 try{
1860 Tango::DevVarStringArray na;
1861 na.length(1);
1862 na[0] = dev_name.c_str();
1863 (*cl_list)[j]->device_factory(&na);
1864 std::cout << "Started " << dev_name << std::endl;
1865 break;
1867 catch (Tango::DevFailed &e)
1876 void TangoHKLAdapter::pseudo_axes_stop_and_remove_devices(void)
1878 unsigned int i, j;
1880 // remove all the dynamic attributes
1881 for(i=0; i<_pseudoAxesAdapters.size(); ++i){
1882 PseudoAxesAdapter *adapter = _pseudoAxesAdapters[i];
1884 for(j=0; j<adapter->_dynamic_attribute_pseudo_axes_axis.size(); ++j)
1885 adapter->_device->remove_attribute(adapter->_dynamic_attribute_pseudo_axes_axis[j]);
1888 // stop and delete
1889 Tango::Util *tg = Tango::Util::instance();
1890 Tango::Database *db = tg->get_database();
1891 const std::vector<Tango::DeviceClass *> *cl_list = tg->get_class_list();
1892 for(i=0; i<cl_list->size(); ++i){
1893 if((*cl_list)[i]->get_name() == "PseudoAxes"){
1894 for(j=0; j<_pseudoAxesAdapters.size(); ++j){
1895 std::string const & proxy = _pseudoAxesAdapters[j]->get_proxy_name();
1898 (*cl_list)[i]->device_destroyer(proxy);
1899 db->delete_device(proxy);
1900 std::cout << "Deleted " << proxy << std::endl;
1902 catch(Tango::DevFailed &e)
1904 std::cout << "Can not remove the " << proxy << "device" << std::endl;
1907 break;
1913 /**********************/
1914 /* Dynamic attributes */
1915 /**********************/
1917 void TangoHKLAdapter::create_axes_dynamic_attributes(void)
1919 size_t i;
1920 size_t len = _axes.size();
1921 _dynamic_attribute_axes_names.resize(len, 1);
1922 for(i=0; i<len; ++i){
1923 std::string name;
1924 AxisAttrib *att;
1926 // compute the pseudo axis name
1927 name = "axis";
1928 name += _axes[i].get_name();
1929 name[4] = toupper(name[4]);
1931 // create the PseudoAxesAttribut
1932 att = new AxisAttrib(name.c_str(), _axes[i]);
1933 _dynamic_attribute_axes.push_back(att);
1934 _dynamic_attribute_axes_names.data[i] = const_cast<char *>(att->get_name().c_str());
1938 void TangoHKLAdapter::add_dynamic_attributes_to_device(void)
1940 size_t i;
1942 for(i=0; i<_dynamic_attribute_axes.size(); ++i)
1943 _device->add_attribute(_dynamic_attribute_axes[i]);
1947 void TangoHKLAdapter::delete_dynamic_attributes(void)
1949 size_t i;
1951 for(i=0; i<_dynamic_attribute_axes.size(); ++i)
1952 _device->remove_attribute(_dynamic_attribute_axes[i], true);
1956 //+------------------------------------------------------------------
1958 * Internal calculation routine for HKL
1960 //+------------------------------------------------------------------
1961 bool TangoHKLAdapter::internal_compute_angles(
1962 double h, double k ,double l, std::string & status)
1964 std::ostringstream line;
1966 line << setprecision(4) << showpos;
1967 if (this->simulated)
1968 line << "SIMULATED : " ;
1969 else
1970 line << "REAL MOVE : " ;
1972 line << " hkl = <";
1973 line.width(9);
1974 line << h;
1975 line << ", ";
1976 line.width(9);
1977 line << k;
1978 line << ", ";
1979 line.width(9);
1980 line << l;
1981 line << "> ";
1982 status = line.str();
1984 // get UB matrix from current sample
1985 HklSample *sample = _diffractometer->samples->current;
1986 if (sample) {
1987 /**********************************************
1988 * CRITICAL SECTION
1989 **********************************************/
1990 omni_mutex_lock lock(_lock);
1992 HklPseudoAxisEngine *engine;
1994 engine = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_w, "hkl");
1996 hkl_parameter_set_value_unit((HklParameter *)engine->pseudoAxes[0], h);
1997 hkl_parameter_set_value_unit((HklParameter *)engine->pseudoAxes[1], k);
1998 hkl_parameter_set_value_unit((HklParameter *)engine->pseudoAxes[2], l);
2000 if (HKL_SUCCESS == hkl_pseudo_axis_engine_setter(engine,
2001 _diffractometer->geometry_w,
2002 &_diffractometer->detector,
2003 sample)){
2004 _angles_idx = 0;
2005 this->update_angles();
2006 hkl_geometry_init_geometry(_diffractometer->geometry_w, engine->engines->geometries->geometries[0]);
2007 hkl_pseudo_axis_engine_list_getter(_diffractometer->engines_w,
2008 _diffractometer->geometry_w,
2009 &_diffractometer->detector,
2010 sample);
2011 if (this->simulated){
2012 hkl_geometry_init_geometry(_diffractometer->geometry_r, engine->engines->geometries->geometries[0]);
2013 hkl_pseudo_axis_engine_list_getter(_diffractometer->engines_r,
2014 _diffractometer->geometry_r,
2015 &_diffractometer->detector,
2016 sample);
2018 this->update_axis_adapters();
2019 this->update_HKLBuffer_from_hkl();
2020 this->update_pseudo_axis_adapters_from_hkl();
2021 this->update_pseudo_axes_adapters_from_hkl();
2022 }else{
2023 status += "ERROR: computation unavailable";
2024 return false;
2026 /**********************************************
2027 * END OF CRITICAL SECTION
2028 **********************************************/
2029 } else {
2030 status += "ERROR: Can not compute if the current sample was not set";
2031 return false;
2033 return true;
2036 //+------------------------------------------------------------------
2038 * method: Diffractometer::goto_reflection
2040 * description: method to execute "GotoReflection"
2041 * Go to axis values of the given reflection
2043 * @param argin reflection number
2046 //+------------------------------------------------------------------
2047 void TangoHKLAdapter::goto_reflection(short reflection_number)
2050 hkl::Sample * sample = _diffractometer->samples().current();
2051 if (sample) {
2052 hkl::Reflection *reflection;
2053 reflection = sample->reflections()[reflection_number];
2054 if (reflection) {
2055 unsigned int i;
2056 double value;
2057 bool ok = true;
2058 hkl::AxeList const & axes = reflection->get_geometry().get_axes();
2059 // first check the axes validity
2060 for(i=0; i<axes.size(); ++i) {
2061 value = axes[i]->get_current().get_value() * HKL_RADTODEG;
2062 HklInterval & range = _axisBuffers[i]->config.range;
2063 if (value < range.min &&
2064 value > range.max) {
2065 ok = false;
2066 break;
2069 if (ok)
2070 for(i=0; i<axes.size(); ++i) {
2071 value = axes[i]->get_current().get_value() * HKL_RADTODEG;
2072 this->write_axis(i, value);
2079 void TangoHKLAdapter::set_simulated(bool simulated)
2081 bool old = this->simulated;
2082 this->simulated = simulated;
2083 if (old == true && simulated == false)
2084 this->update();
2087 } // namespace
2089 std::string hkl_axes_consign_as_string(HklAxis const **axes, size_t axes_len)
2091 size_t i;
2092 std::string out;
2094 std::ostringstream line, tmp;
2095 for(i=0; i<axes_len; ++i) {
2096 HklParameter const *axis = (HklParameter const *)axes[i];
2097 double value = hkl_parameter_get_value_unit(axis);
2099 out += " \"";
2100 out += axis->name;
2101 out + "\" ";
2102 std::ostringstream tmp;
2103 tmp << showpos;
2104 tmp << value << "°";
2105 out += tmp.str();
2108 return out;