* comment debug printf
[diffractometer.git] / src / TangoHKLAdapter.cpp
blob82e7d0cec7a0726b5437442a2fe39ab35e10cdf9
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 // 4 geometries
62 _diffractometer = new HklDiffractometer;
63 _diffractometer->geometry_r = hkl_geometry_factory_new(type, 50 * HKL_DEGTORAD);
64 _diffractometer->geometry_w = hkl_geometry_factory_new(type, 50 * HKL_DEGTORAD);
65 _diffractometer->geometry_r_real = hkl_geometry_factory_new(type, 50 * HKL_DEGTORAD);
66 _diffractometer->geometry_w_real = hkl_geometry_factory_new(type, 50 * HKL_DEGTORAD);
68 // 2 detectors
69 _diffractometer->detector = hkl_detector_factory_new(HKL_DETECTOR_TYPE_0D);
70 _diffractometer->detector->idx = 1;
72 _diffractometer->detector_real = hkl_detector_factory_new(HKL_DETECTOR_TYPE_0D);
73 _diffractometer->detector_real->idx = 1;
75 // 1 sample list
76 _diffractometer->samples = hkl_sample_list_new();
78 // the pseudoAxesenginesList (one per geometry)
79 _diffractometer->engines_r = hkl_pseudo_axis_engine_list_factory(type);
80 _diffractometer->engines_w = hkl_pseudo_axis_engine_list_factory(type);
81 _diffractometer->engines_r_real = hkl_pseudo_axis_engine_list_factory(type);
82 _diffractometer->engines_w_real = hkl_pseudo_axis_engine_list_factory(type);
83 this->update_pseudo_axis_engines();
85 // Build Group
86 Tango::GroupReply::enable_exception(true);
87 _proxies = new Tango::Group("Axis");
89 // fill the axisAdapter.
90 len = HKL_LIST_LEN(_diffractometer->geometry_r->axes);
91 axes_r = _diffractometer->geometry_r->axes;
92 axes_w = _diffractometer->geometry_w->axes;
93 axes_r_real = _diffractometer->geometry_r_real->axes;
94 axes_w_real = _diffractometer->geometry_w_real->axes;
95 for(i=0; i<len; ++i)
96 _axes.push_back(AxisAdapter(this, &axes_r[i], &axes_w[i], &axes_r_real[i], &axes_w_real[i]));
98 // hack to connect all axes the first time
99 this->simulated = false;
100 this->connect_all_proxies();
101 this->simulated = true;
103 // fill the pseudoAxesAdapters
105 omni_mutex_lock lock(_lock);
107 len = HKL_LIST_LEN(_diffractometer->engines_r->engines);
108 _pseudo_axes_proxies.resize(len, 1);
109 for(i=0; i<len; ++i){
110 PseudoAxesAdapter *adapter;
112 adapter = new PseudoAxesAdapter(this, i);
113 _pseudoAxesAdapters.push_back(adapter);
114 _pseudo_axes_proxies.data[i] = const_cast<char *>(adapter->_proxy_name.c_str());
118 // create the dynamic attributes
119 this->create_axes_dynamic_attributes();
121 // set the default lambda
122 this->set_lambda(1.54);
125 TangoHKLAdapter::~TangoHKLAdapter(void)
127 unsigned int i;
129 // remove all pseudo axis adapters
130 for(i=0;i<_pseudoAxisAdapters.size();i++)
131 delete _pseudoAxisAdapters[i];
133 // remove all pseudo axes adapters;
134 for(i=0; i<_pseudoAxesAdapters.size(); ++i)
135 delete _pseudoAxesAdapters[i];
137 // remove all axisAdapter
138 _axes.clear();
140 if(_proxies) {
141 _proxies->remove_all();
142 delete _proxies;
143 _proxies = NULL;
146 if (_lambdaAttributeProxy)
147 delete _lambdaAttributeProxy;
149 // remove the hkl part
150 hkl_geometry_free(_diffractometer->geometry_r);
151 hkl_geometry_free(_diffractometer->geometry_w);
152 hkl_geometry_free(_diffractometer->geometry_r_real);
153 hkl_geometry_free(_diffractometer->geometry_w_real);
154 hkl_detector_free(_diffractometer->detector);
155 hkl_detector_free(_diffractometer->detector_real);
156 hkl_sample_list_free(_diffractometer->samples);
157 hkl_pseudo_axis_engine_list_free(_diffractometer->engines_r);
158 hkl_pseudo_axis_engine_list_free(_diffractometer->engines_w);
159 hkl_pseudo_axis_engine_list_free(_diffractometer->engines_r_real);
160 hkl_pseudo_axis_engine_list_free(_diffractometer->engines_w_real);
162 if(_diffractometer) {
163 delete _diffractometer;
164 _diffractometer = NULL;
168 void TangoHKLAdapter::connect_all_proxies(void)
170 omni_mutex_lock lock(_lock);
172 // connect the lambda proxy
173 if ((!_lambdaAttributeProxy && !this->simulated)
174 && _device->lambdaAttributeProxy != "") {
177 _lambdaAttributeProxy = new Tango::AttributeProxy(_device->lambdaAttributeProxy);
179 catch(...) {
183 // connect the axes proxies
184 if (!this->ready && !this->simulated) {
185 unsigned int nb;
187 nb = _device->realAxisProxies.size();
188 if (nb != _axes.size()) {
189 _wrong_nb_of_axis_proxies = true;
190 return;
191 } else {
192 unsigned int i, j;
193 bool ready = true;
195 for(i=0; i<nb; ++i) {
196 AxisAdapter & axis = _axes[i];
197 if (!axis.is_ready()){
198 // Find axis in the proxy list
199 for(j=0; j<nb; ++j) {
200 char *line = strdup(_device->realAxisProxies[j].c_str());
201 char *last;
202 char *axis_name = strtok_r(line, ":", &last);
203 char *proxy_name = strtok_r(NULL, ":", &last);
204 if (axis.get_name() == axis_name){
205 Tango::Group *group = axis.connect(proxy_name);
206 if(group)
207 _proxies->add(group);
209 free(line);
211 if (!axis.is_ready())
212 ready = false;
215 this->ready = ready;
220 void TangoHKLAdapter::set_lambda(double lambda)
222 omni_mutex_lock lock(_lock);
224 if ((this->simulated || _device->lambdaAttributeProxy == "")
225 && lambda > 0){
226 _lambda = lambda;
227 _diffractometer->geometry_r->source.wave_length = lambda;
228 _diffractometer->geometry_w->source.wave_length = lambda;
229 _diffractometer->geometry_r_real->source.wave_length = lambda;
230 _diffractometer->geometry_w_real->source.wave_length = lambda;
234 // this method connect engines to the right geometry, detector and sample
235 void TangoHKLAdapter::update_pseudo_axis_engines(void)
237 hkl_pseudo_axis_engine_list_init(_diffractometer->engines_r,
238 _diffractometer->geometry_r,
239 _diffractometer->detector,
240 _diffractometer->samples->current);
242 hkl_pseudo_axis_engine_list_init(_diffractometer->engines_w,
243 _diffractometer->geometry_w,
244 _diffractometer->detector,
245 _diffractometer->samples->current);
247 hkl_pseudo_axis_engine_list_init(_diffractometer->engines_r_real,
248 _diffractometer->geometry_r_real,
249 _diffractometer->detector,
250 _diffractometer->samples->current);
252 hkl_pseudo_axis_engine_list_init(_diffractometer->engines_w_real,
253 _diffractometer->geometry_w_real,
254 _diffractometer->detector,
255 _diffractometer->samples->current);
258 void TangoHKLAdapter::update_lambda(void)
260 if (_lambdaAttributeProxy && !this->simulated){
261 try{
262 _lambdaAttributeProxy->read() >> _lambda;
263 _diffractometer->geometry_r->source.wave_length = _lambda;
264 _diffractometer->geometry_w->source.wave_length = _lambda;
265 _diffractometer->geometry_r_real->source.wave_length = _lambda;
266 _diffractometer->geometry_w_real->source.wave_length = _lambda;
268 catch (Tango::DevFailed &){
270 }else
271 _lambda = _diffractometer->geometry_r->source.wave_length;
275 * this method update the angles attribut from the engines->geometry list
277 void TangoHKLAdapter::update_angles(void)
279 size_t i, j;
280 size_t xdim;
281 size_t ydim;
282 HklPseudoAxisEngine *engine;
283 double *data;
284 HklGeometry **geometries;
286 if(this->simulated)
287 engine = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_w, "hkl");
288 else
289 engine = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_w_real, "hkl");
291 // update the computed_angles part
292 xdim = 1 + HKL_LIST_LEN(_diffractometer->geometry_r->axes);
293 ydim = HKL_LIST_LEN(engine->engines->geometries->geometries);
295 _angles.resize(xdim, ydim);
296 _angles.clear();
298 //fill the array
299 data = _angles.data;
300 geometries = engine->engines->geometries->geometries;
301 for(j=0; j<ydim; ++j){
302 HklGeometry *geom = geometries[j];
304 data[0] = j;
305 for(i=1; i<xdim; ++i)
306 data[i] = hkl_axis_get_value_unit(&geom->axes[i-1]);
307 data += xdim;
312 * this method update the reflections_angles when we change a sample parameter
314 void TangoHKLAdapter::update_reflections_angles(void)
316 HklSample *sample = _diffractometer->samples->current;
317 if (sample) {
318 unsigned int i, j;
319 size_t rdim;
320 double *data;
322 // the reflection Angles
323 rdim = HKL_LIST_LEN(sample->reflections);
324 _reflections_angles.resize(rdim, rdim);
325 _reflections_angles.clear();
327 data = _reflections_angles.data;
328 for(i=0; i<rdim; ++i) {
329 for(j=0; j<rdim; ++j) {
330 double angle = 0.;
331 if (j < i)
332 angle = hkl_sample_get_reflection_theoretical_angle(sample, i, j);
333 else if (j > i)
334 angle = hkl_sample_get_reflection_mesured_angle(sample, i, j);
336 *data = angle * HKL_RADTODEG;
337 data++;
343 void TangoHKLAdapter::update_reflections(void)
345 HklSample *sample = _diffractometer->samples->current;
346 if (sample) {
348 // Allocation of the image
349 unsigned int xdim = 6 + HKL_LIST_LEN(_diffractometer->geometry_r->axes);
350 unsigned int ydim = HKL_LIST_LEN(sample->reflections);
351 _reflections.resize(xdim, ydim);
353 size_t i = 0;
354 double *data = _reflections.data;
355 for(i=0; i<ydim; ++i) {
356 HklSampleReflection *r;
358 r = hkl_sample_get_ith_reflection(sample, i);
359 if (r) {
360 size_t k;
361 HklAxis *axes = r->geometry->axes;
363 data[0] = i;
364 data[1] = r->hkl.data[0];
365 data[2] = r->hkl.data[1];
366 data[3] = r->hkl.data[2];
367 data[4] = 0;
368 data[5] = (double)r->flag;
370 for(k=0; k<HKL_LIST_LEN(r->geometry->axes); ++k)
371 data[6 + k] = hkl_axis_get_value_unit(&axes[k]);
373 data += xdim;
378 void TangoHKLAdapter::update_ub(void)
380 HklSample const *sample = _diffractometer->samples->current;
381 if(sample){
382 size_t dim = 3;
383 _ub.resize(dim, dim);
384 _ub.set_data_from_buffer(&(sample->UB.data[0][0]), dim, dim);
388 void TangoHKLAdapter::update_ux_uy_uz(void)
390 HklSample *sample = _diffractometer->samples->current;
392 if(sample){
393 hkl_matrix_to_euler(&sample->U, &_ux, &_uy, &_uz);
394 _ux *= HKL_RADTODEG;
395 _uy *= HKL_RADTODEG;
396 _uz *= HKL_RADTODEG;
401 * this method update all the AxisAdapter from the proxy every 200 ms.
402 * this from_proxy get the real part from the proxy and the "sim" part
403 * from the HklAxis in simulated mode or from the proxy in real mode
404 * else it updates them from the HklAxis.
406 * every 200 ms
407 * simulated:
408 * real <- proxy
409 * sim <- HklAxis
410 * non simulated:
411 * real <- proxy
412 * sim <- proxy
413 * rest of the time
414 * real <- HklAxis
415 * simulated -> HklAxis
417 void TangoHKLAdapter::update_axis_adapters(void)
419 size_t i;
421 // first read from the proxy.
422 duration.Stop();
423 if(duration.GetDurationInMs() >= 200 && _proxies) {
424 for(size_t i=0; i<_axes.size(); ++i)
425 _axes[i].from_proxy(this->simulated);
426 duration.Start();
427 }else
428 for(i=0; i<_axes.size(); ++i)
429 _axes[i].from_HklAxis();
432 void TangoHKLAdapter::update_hkl_from_axis_adapters(void)
434 size_t i;
436 // set the axis
437 for(i=0; i<_axes.size(); ++i)
438 _axes[i].to_HklAxis();
440 // update the pseudo axes
441 if(_diffractometer && _diffractometer->samples){
442 hkl_pseudo_axis_engine_list_getter(_diffractometer->engines_r);
443 hkl_pseudo_axis_engine_list_getter(_diffractometer->engines_w);
444 hkl_pseudo_axis_engine_list_getter(_diffractometer->engines_r_real);
445 hkl_pseudo_axis_engine_list_getter(_diffractometer->engines_w_real);
449 void TangoHKLAdapter::update_pseudo_axis_adapters_from_hkl(void)
451 for(size_t i=0;i<_pseudoAxisAdapters.size();++i)
452 _pseudoAxisAdapters[i]->update();
455 void TangoHKLAdapter::update_proxies_from_axis_adapters(void)
457 _proxies->command_inout(AXIS_COMMAND_STOP_NAME);
458 for(size_t i=0; i<_axes.size(); ++i)
459 _axes[i].to_proxy();
462 void TangoHKLAdapter::update_proxies_from_pseudo_axis_adapters(PseudoAxisAdapter *adapter)
464 adapter->to_proxies();
467 void TangoHKLAdapter::update_pseudo_axes_adapters_from_hkl(void)
469 size_t i, j, len;
470 HklPseudoAxisEngine *engine_r, *engine_w;
472 for(i=0; i<_pseudoAxesAdapters.size(); ++i){
473 PseudoAxesAdapter *adapter;
475 adapter = _pseudoAxesAdapters[i];
476 engine_r = _diffractometer->engines_r->engines[i];
477 engine_w = _diffractometer->engines_w->engines[i];
478 len = HKL_LIST_LEN(engine_r->pseudoAxes);
479 for(j=0; j<len; ++j){
480 adapter->_read.data[j] = hkl_parameter_get_value_unit((HklParameter *)engine_r->pseudoAxes[j]);
481 adapter->_write.data[j] = hkl_parameter_get_value_unit((HklParameter *)engine_w->pseudoAxes[j]);
485 adapter->update_state_and_status_i();
489 void TangoHKLAdapter::update_state_and_status(void)
491 Tango::DevState state;
492 std::string status;
493 std::string extra_status;
495 state = Tango::STANDBY;
496 if (this->simulated)
497 status = "Simulated Mode: Motors will NOT move.";
498 else {
499 status = "REAL Mode : Motors will REALLY move.";
501 if (!this->ready) {
502 state = Tango::FAULT;
503 extra_status += "\nCan not connect to axes proxies";
504 // update the monochromator proxy status.
505 if (!_lambdaAttributeProxy && !this->simulated) {
506 extra_status += "\nCan not connect to the lambdaAttributeProxy";
507 extra_status += "\nCheck also the lambdaAttributeProxy property";
509 } else {
510 try {
511 for(unsigned int i=0; i<_axes.size(); ++i) {
512 AxisAdapter const & axis = _axes[i];
513 std::string const & device_name = axis.get_device_name();
514 Tango::DevState tmpState = axis.get_state();
516 ::compose_state(state, tmpState);
517 if (tmpState != Tango::STANDBY)
518 extra_status += "\n" + device_name + " is in " + Tango::DevStateName[tmpState];
520 } catch(...)
522 state = Tango::FAULT;
523 extra_status += "\nCan not connect to axes proxies";
529 if (_diffractometer){
530 status += "\nSample: ";
531 if(!_diffractometer->samples->current){
532 status += "Not yet Set";
533 state = Tango::FAULT;
534 } else
535 status += _diffractometer->samples->current->name;
536 if (state == Tango::STANDBY)
537 extra_status += "\nready to compute hkl";
538 }else{
539 state = Tango::FAULT;
540 extra_status += "\nhkl core not yet initialized !!!";
542 status += "\nDiffractometer status: ";
543 status += Tango::DevStateName[state];
544 status += extra_status;
546 _diffractometerConfig.state = state;
547 _diffractometerConfig.status = status;
550 void TangoHKLAdapter::update(void)
552 /**********************************************
553 * CRITICAL SECTION
554 **********************************************/
555 omni_mutex_lock lock(_lock);
557 this->update_lambda();
558 this->update_axis_adapters();
559 this->update_hkl_from_axis_adapters();
560 this->update_pseudo_axis_adapters_from_hkl();
561 this->update_pseudo_axes_adapters_from_hkl();
562 this->update_state_and_status();
563 /**********************************************
564 * END OF CRITICAL SECTION
565 **********************************************/
568 /********************/
569 /* State and status */
570 /********************/
571 void TangoHKLAdapter::get_diffractometer_config(DiffractometerConfig & config)
573 omni_mutex_lock lock(_lock);
575 config = _diffractometerConfig;
578 /************/
579 /* hkl part */
580 /************/
582 short & TangoHKLAdapter::get_angles_idx(void)
584 omni_mutex_lock lock(_lock);
586 return _angles_idx;
589 void TangoHKLAdapter::set_angles_idx(short idx)
591 omni_mutex_lock lock(_lock);
593 // A REVOIR
594 if(idx >= 0 && idx < (int)_angles.ydim){
595 size_t i;
596 double *values;
598 _angles_idx = idx;
599 values = &_angles.data[1 + idx * _angles.xdim];
600 for(i=0; i<_axes.size(); ++i)
601 this->write_axis_i(_axes[i], values[i]);
605 void TangoHKLAdapter::load(void)
607 this->load_1();
610 void TangoHKLAdapter::load_1(void)
612 unsigned long nb_properties;
614 // Get the Crystal Attributes properties.
615 Tango::DbData properties;
616 properties.push_back(Tango::DbDatum("Crystal"));
617 _device->get_db_device()->get_attribute_property(properties);
619 // the first one is the number of properties
620 properties[0] >> nb_properties;
622 if (nb_properties > 1) {
623 unsigned long i, j;
624 HklGeometry *geometry;
625 HklDetector *detector;
627 geometry = hkl_geometry_new_copy(_diffractometer->geometry_r);
628 detector = hkl_detector_new_copy(_diffractometer->detector);
630 hkl_sample_list_clear(_diffractometer->samples);
631 for(i=1; i<=nb_properties; ++i) {
632 // skip the _ver property
633 if(!strcasecmp("_ver", properties[i].name.c_str()))
634 continue;
636 HklSample * sample;
638 // The name of the property name is the name of a crystal.
639 sample = hkl_sample_new(properties[i].name.c_str(), HKL_SAMPLE_MONOCRYSTAL);
641 // Extract the lines store in the property
642 std::vector<std::string> lines;
643 properties[i] >> lines;
645 for(j=0; j<lines.size(); j++) {
646 char *line = strdup(lines[j].c_str());
647 char *last;
648 char *key = strtok_r(line, "=", &last);
650 if (!strcmp(key,"lattice")) {
651 double a = atof(strtok_r(NULL, ";", &last));
652 double b = atof(strtok_r(NULL, ";", &last));
653 double c = atof(strtok_r(NULL, ";", &last));
654 double alpha = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
655 double beta = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
656 double gamma = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
657 hkl_sample_set_lattice(sample, a, b, c, alpha, beta, gamma);
659 sample->lattice->a->fit = atoi(strtok_r(NULL, ";", &last));
660 sample->lattice->b->fit = atoi(strtok_r(NULL, ";", &last));
661 sample->lattice->c->fit = atoi(strtok_r(NULL, ";", &last));
662 sample->lattice->alpha->fit = atoi(strtok_r(NULL, ";", &last));
663 sample->lattice->beta->fit = atoi(strtok_r(NULL, ";", &last));
664 sample->lattice->gamma->fit = atoi(strtok_r(NULL, ";", &last));
665 } else if (!strcmp(key, "uxuyuz")){
666 double ux = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
667 double uy = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
668 double uz = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
669 hkl_sample_set_U_from_euler(sample, ux, uy, uz);
670 } else if (!strcmp(key,"reflection")) {
671 unsigned int idx = 0;
672 HklSampleReflection *reflection;
674 double wavelength = atof(strtok_r(NULL, ";", &last));
675 double h = atof(strtok_r(NULL, ";", &last));
676 double k = atof(strtok_r(NULL, ";", &last));
677 double l = atof(strtok_r(NULL, ";", &last));
678 int flag = atoi(strtok_r(NULL, ";", &last));
680 // first set the geometry axes
681 while(key = strtok_r(NULL, ";", &last))
682 hkl_axis_set_value_unit(&geometry->axes[idx++], atof(key));
683 geometry->source.wave_length = wavelength;
685 reflection = hkl_sample_add_reflection(sample, geometry, detector, h, k, l);
686 reflection->flag = flag;
688 free(line);
689 // End of key research
690 }// End for each parameters
691 hkl_sample_list_append(_diffractometer->samples, sample);
692 }// End for each property
694 hkl_detector_free(detector);
695 hkl_geometry_free(geometry);
697 //_device->refresh_crystal_parameters();
701 void TangoHKLAdapter::save(void)
703 omni_mutex_lock lock(_lock);
705 size_t i, j, k;
706 size_t len;
707 Tango::DbData crystal_prop;
708 Tango::DbData data_put;
710 // Step 1 : clean all properties
711 // FP Le mieux serait sans doute de ne pas effacer les propriétés d'attribut
712 // avant d'avoir crée correctement un data_put.
713 crystal_prop.push_back(Tango::DbDatum("Crystal"));
714 _device->get_db_device()->get_attribute_property(crystal_prop);
715 long number_of_prop = 0;
716 crystal_prop[0] >> number_of_prop ;
717 if( number_of_prop > 0)
718 _device->get_db_device()->delete_attribute_property(crystal_prop);
720 // Step 2 : create the Crystal properties
721 Tango::DbDatum properties("Crystal");
722 // Put number of properties (= nb of samples + 1)
723 len = hkl_sample_list_len(_diffractometer->samples);
724 properties << (long)(len + 1);
725 data_put.push_back(properties);
727 // first property is the format version
728 Tango::DbDatum version("_ver");
729 version << (long)FORMAT_VERSION;
730 data_put.push_back(version);
732 // now each sample
733 for(k=0; k<len; ++k){
734 HklSample *sample;
735 std::vector<std::string> lines;
736 char line[256];
738 // the lattices values
739 sample = hkl_sample_list_get_ith(_diffractometer->samples, k);
740 double a = hkl_parameter_get_value_unit(sample->lattice->a);
741 double b = hkl_parameter_get_value_unit(sample->lattice->b);
742 double c = hkl_parameter_get_value_unit(sample->lattice->c);
743 double alpha = hkl_parameter_get_value_unit(sample->lattice->alpha);
744 double beta = hkl_parameter_get_value_unit(sample->lattice->beta);
745 double gamma = hkl_parameter_get_value_unit(sample->lattice->gamma);
746 // the fit flag
747 int a_fit = sample->lattice->a->fit;
748 int b_fit = sample->lattice->b->fit;
749 int c_fit = sample->lattice->c->fit;
750 int alpha_fit = sample->lattice->alpha->fit;
751 int beta_fit = sample->lattice->beta->fit;
752 int gamma_fit = sample->lattice->gamma->fit;
754 snprintf(line, 255, "lattice=%f;%f;%f;%f;%f;%f;%d;%d;%d;%d;%d;%d",
755 a, b, c, alpha, beta, gamma,
756 a_fit, b_fit, c_fit, alpha_fit, beta_fit, gamma_fit);
757 lines.push_back(line);
759 // the UxUyUz parameters
760 double ux, uy, uz;
761 hkl_matrix_to_euler(&sample->U, &ux, &uy, &uz);
762 ux *= HKL_RADTODEG;
763 uy *= HKL_RADTODEG;
764 uz *= HKL_RADTODEG;
766 snprintf(line, 255, "uxuyuz=%f;%f;%f", ux, uy, uz);
767 lines.push_back(line);
769 // the reflections
770 for(i=0; i<HKL_LIST_LEN(sample->reflections); ++i) {
771 HklSampleReflection *reflection;
773 reflection = hkl_sample_get_ith_reflection(sample, i);
774 double wavelength = reflection->geometry->source.wave_length;
775 double h = reflection->hkl.data[0];
776 double k = reflection->hkl.data[1];
777 double l = reflection->hkl.data[2];
778 int flag = reflection->flag;
780 snprintf(line, 255, "reflection=%f;%f;%f;%f;%d",
781 wavelength, h, k, l, flag);
782 // Extract values of each axes
783 for(j=0; j<HKL_LIST_LEN(reflection->geometry->axes); ++j) {
784 char pos[256];
785 double rad = hkl_axis_get_value_unit(&reflection->geometry->axes[j]);
786 snprintf(pos, 255, ";%f", rad);
787 strncat(line, pos, 255);
789 lines.push_back(line);
792 // Try to create property
793 // Get crystal name
794 Tango::DbDatum property(sample->name);
795 property << lines;
796 data_put.push_back(property);
799 //update database for this property
800 _device->get_db_device()->put_attribute_property(data_put);
803 /***************/
804 /* sample part */
805 /***************/
807 char const *TangoHKLAdapter::get_sample_name(void)
809 omni_mutex_lock lock(_lock);
811 HklSample *sample = _diffractometer->samples->current;
812 if(sample)
813 return sample->name;
814 else
815 return "";
818 void TangoHKLAdapter::set_current_sample(char const * name)
820 omni_mutex_lock lock(_lock);
822 HklSample *last;
824 last = _diffractometer->samples->current;
825 if (HKL_SUCCESS == hkl_sample_list_select_current(_diffractometer->samples, name))
826 if (last != _diffractometer->samples->current){
827 this->update_pseudo_axis_engines();
828 this->update_ub();
829 this->update_ux_uy_uz();
830 this->update_reflections_angles();
831 this->update_reflections();
832 this->update_state_and_status();
836 void TangoHKLAdapter::get_sample_lattices(double *a, double *b, double *c,
837 double *alpha, double *beta, double *gamma,
838 double *a_star, double *b_star, double *c_star,
839 double *alpha_star, double *beta_star, double *gamma_star)
841 omni_mutex_lock lock(_lock);
843 HklSample * sample = _diffractometer->samples->current;
844 if (!sample)
845 return;
847 HklLattice const *lattice = sample->lattice;
848 HklLattice *reciprocal = hkl_lattice_new_copy(lattice);
850 hkl_lattice_reciprocal(lattice, reciprocal);
852 // direct space
853 *a = hkl_parameter_get_value_unit(lattice->a);
854 *b = hkl_parameter_get_value_unit(lattice->b);
855 *c = hkl_parameter_get_value_unit(lattice->c);
856 *alpha = hkl_parameter_get_value_unit(lattice->alpha);
857 *beta = hkl_parameter_get_value_unit(lattice->beta);
858 *gamma = hkl_parameter_get_value_unit(lattice->gamma);
860 // reciprocal space
861 *a_star = hkl_parameter_get_value_unit(reciprocal->a);
862 *b_star = hkl_parameter_get_value_unit(reciprocal->b);
863 *c_star = hkl_parameter_get_value_unit(reciprocal->c);
864 *alpha_star = hkl_parameter_get_value_unit(reciprocal->alpha);
865 *beta_star = hkl_parameter_get_value_unit(reciprocal->beta);
866 *gamma_star = hkl_parameter_get_value_unit(reciprocal->gamma);
868 hkl_lattice_free(reciprocal);
871 void TangoHKLAdapter::set_sample_Ux(double ux)
873 HklSample *sample;
875 sample = _diffractometer->samples->current;
876 if (sample){
877 if (HKL_SUCCESS == hkl_sample_set_U_from_euler(sample,
878 ux * HKL_DEGTORAD,
879 _uy * HKL_DEGTORAD,
880 _uz * HKL_DEGTORAD)){
881 _ux = ux;
882 this->update_ub();
883 }else
884 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this Ux value",
885 "Set a correct value");
889 void TangoHKLAdapter::set_sample_Uy(double uy)
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 _uy = uy;
900 this->update_ub();
901 }else
902 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this Uy value",
903 "Set a correct value");
907 void TangoHKLAdapter::set_sample_Uz(double uz)
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 _uz = uz;
918 this->update_ub();
919 }else
920 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this Uz value",
921 "Set a correct value");
925 void TangoHKLAdapter::add_new_sample(std::string const & name)
927 omni_mutex_lock lock(_lock);
929 HklSample *sample = hkl_sample_new(name.c_str(), HKL_SAMPLE_MONOCRYSTAL);
931 if (!hkl_sample_list_append(_diffractometer->samples, sample)){
932 hkl_sample_free(sample);
933 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not add a sample with this name",
934 "A sample with the same name is already present in the sample list");
938 void TangoHKLAdapter::copy_sample_as(Tango::DevString copy_name)
940 omni_mutex_lock lock(_lock);
942 HklSample *sample;
943 HklSample const *current;
945 current = _diffractometer->samples->current;
946 if(!current)
947 TANGO_EXCEPTION_THROW_WITHOUT_LOG("No current sample set",
948 "Please set a current sample");
950 sample = hkl_sample_list_get_by_name(_diffractometer->samples, copy_name);
951 if (sample)
952 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not add a sample with this name",
953 "A sample with the same name is already present in the sample list");
955 sample = hkl_sample_new_copy(current);
956 if(sample){
957 hkl_sample_set_name(sample, copy_name);
958 hkl_sample_list_append(_diffractometer->samples, sample);
962 void TangoHKLAdapter::del_sample(void)
964 omni_mutex_lock lock(_lock);
966 HklSampleList *samples = _diffractometer->samples;
967 hkl_sample_list_del(samples, samples->current);
969 // add a default sample if no more sample in the list
970 if(hkl_sample_list_len(samples) == 0){
971 HklSample *sample = hkl_sample_new("default", HKL_SAMPLE_MONOCRYSTAL);
972 samples->current = hkl_sample_list_append(samples, sample);
973 }else
974 samples->current = hkl_sample_list_get_ith(samples, 0);
975 this->update_ub();
976 this->update_ux_uy_uz();
977 this->update_reflections_angles();
978 this->update_reflections();
981 void TangoHKLAdapter::set_lattice(const Tango::DevVarDoubleArray *argin)
983 omni_mutex_lock lock(_lock);
985 if (argin && argin->length() != 6)
986 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
987 "Did not receive the exact amount of crystal parameters: A, B, C, alpha, beta, gamma");
989 HklSample *sample = _diffractometer->samples->current;
990 if (HKL_FAIL == hkl_sample_set_lattice(sample,
991 (*argin)[0],(*argin)[1], (*argin)[2],
992 (*argin)[3] * HKL_DEGTORAD,
993 (*argin)[4] * HKL_DEGTORAD,
994 (*argin)[5] * HKL_DEGTORAD))
996 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this lattice combination.",
997 "Please set a good combination");
998 this->update_ub();
999 this->update_reflections_angles();
1002 void TangoHKLAdapter::add_reflection(void)
1004 omni_mutex_lock lock(_lock);
1006 HklSample *sample = _diffractometer->samples->current;
1008 if(sample){
1009 double h, k, l;
1010 HklPseudoAxisEngine *engine;
1011 HklSampleReflection *ref;
1013 engine = hkl_pseudo_axis_engine_list_get_by_name(
1014 _diffractometer->engines_r, "hkl");
1016 h = hkl_parameter_get_value_unit((HklParameter *)engine->pseudoAxes[0]);
1017 k = hkl_parameter_get_value_unit((HklParameter *)engine->pseudoAxes[1]);
1018 l = hkl_parameter_get_value_unit((HklParameter *)engine->pseudoAxes[2]);
1020 ref = hkl_sample_add_reflection(sample,
1021 _diffractometer->geometry_r,
1022 _diffractometer->detector,
1023 h, k, l);
1024 if(ref){
1025 this->update_reflections_angles();
1026 this->update_reflections();
1031 void TangoHKLAdapter::del_reflection(Tango::DevShort argin)
1033 omni_mutex_lock lock(_lock);
1035 if (HKL_FAIL == hkl_sample_del_reflection(_diffractometer->samples->current, argin))
1036 TANGO_EXCEPTION_THROW_WITHOUT_LOG("index out of range",
1037 "change the reflection index");
1038 this->update_reflections_angles();
1039 this->update_reflections();
1042 void TangoHKLAdapter::set_reflections(Matrix<double> const & img)
1044 omni_mutex_lock lock(_lock);
1046 HklSample *sample = _diffractometer->samples->current;
1047 if (sample
1048 && img.xdim == _reflections.xdim
1049 && img.ydim == _reflections.ydim) {
1051 size_t i = 0;
1052 size_t j = 0;
1053 for(i=0; i<HKL_LIST_LEN(sample->reflections); ++i) {
1054 HklSampleReflection *r;
1056 r = hkl_sample_get_ith_reflection(sample, i);
1057 if (r) {
1058 hkl_sample_reflection_set_hkl(r, img.data[j+1], img.data[j+2], img.data[j+3]);
1059 hkl_sample_reflection_set_flag(r, (int)img.data[j+5]);
1061 j += _reflections.xdim;
1063 this->update_reflections();
1064 this->update_reflections_angles();
1068 double TangoHKLAdapter::affine_sample(std::string name)
1070 omni_mutex_lock lock(_lock);
1072 HklSample *sample;
1073 double res = 0.;
1075 sample = hkl_sample_list_get_by_name(_diffractometer->samples, name.c_str());
1076 if(sample){
1077 HklSample *tmp;
1079 // check if the affine sample is already in the HklSampleList
1080 std::string name = sample->name;
1081 name += "(affine)";
1082 tmp = hkl_sample_list_get_by_name(_diffractometer->samples, name.c_str());
1083 hkl_sample_list_del(_diffractometer->samples, tmp);
1085 tmp = hkl_sample_new_copy(sample);
1086 hkl_sample_set_name(tmp, name.c_str());
1087 res = hkl_sample_affine(tmp);
1089 hkl_sample_list_append(_diffractometer->samples, tmp);
1090 _diffractometer->samples->current = tmp;
1092 this->update_ub();
1093 this->update_ux_uy_uz();
1094 this->update_reflections_angles();
1097 return res;
1101 std::vector<std::string> TangoHKLAdapter::get_samples_names(void)
1103 omni_mutex_lock lock(_lock);
1105 std::vector<std::string> names;
1106 size_t i, len;
1107 HklSampleList *samples = _diffractometer->samples;
1109 len = hkl_sample_list_len(samples);
1110 for(i=0; i<len; ++i)
1111 names.push_back(hkl_sample_list_get_ith(samples, i)->name);
1113 return names;
1116 void TangoHKLAdapter::get_sample_parameter_values(Tango::DevVarDoubleStringArray *argout)
1118 omni_mutex_lock lock(_lock);
1120 HklSample *sample;
1121 HklParameter *parameter = NULL;
1122 std::string name;
1124 //check parameters
1125 if (argout->svalue.length() != 1)
1126 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1127 "only one string = parameter name");
1129 sample = _diffractometer->samples->current;
1130 if(sample){
1131 //parameters OK
1132 name = argout->svalue[0];
1133 if(name == "a")
1134 parameter = sample->lattice->a;
1135 else if(name == "b")
1136 parameter = sample->lattice->b;
1137 else if(name == "c")
1138 parameter = sample->lattice->c;
1139 else if(name == "alpha")
1140 parameter = sample->lattice->alpha;
1141 else if(name == "beta")
1142 parameter = sample->lattice->beta;
1143 else if(name == "gamma")
1144 parameter = sample->lattice->gamma;
1146 if (parameter){
1147 argout->dvalue[0] = parameter->range.min;
1148 argout->dvalue[1] = parameter->range.max;
1149 argout->dvalue[2] = parameter->fit;
1150 }else
1151 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Wrong parameter name",
1152 "Select: a, b, c, alpha, beta, gamma");
1156 void TangoHKLAdapter::set_sample_parameter_values(Tango::DevVarDoubleStringArray const *argin)
1158 omni_mutex_lock lock(_lock);
1160 HklSample *sample;
1161 HklParameter *parameter = NULL;
1162 std::string name;
1164 // check parameters
1165 if(argin->dvalue.length() != 3)
1166 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1167 "set_crystal_parameter_values did not receive the right amount of scalar parameters: min, max, flag");
1168 if((argin->svalue.length() ) != 1)
1169 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1170 "set_crystal_parameter_values did not receive the right amount of string parameters: parameter name");
1172 // parameters OK
1173 sample = _diffractometer->samples->current;
1174 if(!sample)
1175 TANGO_EXCEPTION_THROW_WITHOUT_LOG("No current sample set",
1176 "Please set a current sample");
1178 name = argin->svalue[0];
1179 if(name == "a")
1180 parameter = sample->lattice->a;
1181 else if(name == "b")
1182 parameter = sample->lattice->b;
1183 else if(name == "c")
1184 parameter = sample->lattice->c;
1185 else if(name == "alpha")
1186 parameter = sample->lattice->alpha;
1187 else if(name == "beta")
1188 parameter = sample->lattice->beta;
1189 else if(name == "gamma")
1190 parameter = sample->lattice->gamma;
1192 if (parameter){
1193 parameter->range.min = argin->dvalue[0];
1194 parameter->range.max = argin->dvalue[1];
1195 parameter->fit = argin->dvalue[2] != 0.;
1196 }else
1197 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Wrong parameter name",
1198 "Select: a, b, c, alpha, beta, gamma");
1199 this->update_ub();
1200 this->update_ux_uy_uz();
1201 this->update_reflections_angles();
1204 void TangoHKLAdapter::compute_u(const Tango::DevVarLongArray *argin)
1206 omni_mutex_lock lock(_lock);
1208 HklSample *sample;
1210 // is parameter ok ?
1211 if (argin->length() != 2)
1212 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Need exactly two reflections indexes",
1213 "use the right number of parameters");
1215 sample = _diffractometer->samples->current;
1216 if (!sample)
1217 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not compute the U matrix without current sample set.",
1218 "Set a current sample");
1220 if (hkl_sample_compute_UB_busing_levy(sample, (*argin)[0], (*argin)[1]))
1221 TANGO_EXCEPTION_THROW_WITHOUT_LOG("can not compute the UB matrix using thoses reflections index",
1222 "Use other reflections");
1223 this->update_ub();
1224 this->update_ux_uy_uz();
1227 /*************/
1228 /* Axis part */
1229 /*************/
1231 void TangoHKLAdapter::read_axis(int idx, double & read, double & write)
1233 omni_mutex_lock lock(_lock);
1235 AxisAdapter & axis = _axes[idx];
1236 read = axis.get_read();
1237 write = axis.get_write();
1240 void TangoHKLAdapter::stop_all_axis(void)
1242 #ifdef WRITE_TO_PROXY_ALLOWED
1243 _proxies->command_inout(AXIS_COMMAND_STOP_NAME, true);
1244 #endif
1247 void TangoHKLAdapter::write_axis(AxisAdapter & axis, double value)
1249 omni_mutex_lock lock(_lock);
1251 this->write_axis_i(axis, value);
1254 void TangoHKLAdapter::write_axis_i(AxisAdapter & axis, double value)
1256 axis._read = axis._write = value;
1257 hkl_axis_set_value_unit(axis._axis_r, value);
1258 hkl_axis_set_value_unit(axis._axis_w, value);
1261 /*******************/
1262 /* pseudoAxis part */
1263 /*******************/
1265 std::vector<std::string> TangoHKLAdapter::pseudo_axis_get_names(void)
1267 omni_mutex_lock lock(_lock);
1269 std::vector<std::string> names;
1270 size_t i, j;
1272 for(i=0; i<HKL_LIST_LEN(_diffractometer->engines_r_real->engines); ++i){
1273 HklPseudoAxisEngine *engine;
1275 engine = _diffractometer->engines_r_real->engines[i];
1276 for(j=0; j<HKL_LIST_LEN(engine->pseudoAxes); ++j)
1277 names.push_back(((HklParameter *)(&engine->pseudoAxes[j]))->name);
1280 return names;
1283 PseudoAxisAdapter *TangoHKLAdapter::pseudo_axis_buffer_new(char const *name)
1285 omni_mutex_lock lock(_lock);
1287 PseudoAxisAdapter * buffer = NULL;
1288 HklPseudoAxis *pseudo_r;
1289 HklPseudoAxis *pseudo_w;
1291 pseudo_r = hkl_pseudo_axis_engine_list_get_pseudo_axis_by_name(
1292 _diffractometer->engines_r_real, name);
1293 pseudo_w = hkl_pseudo_axis_engine_list_get_pseudo_axis_by_name(
1294 _diffractometer->engines_w_real, name);
1296 if(pseudo_r && pseudo_w) {
1299 buffer = new PseudoAxisAdapter(*this, pseudo_r, pseudo_w);
1300 _pseudoAxisAdapters.push_back(buffer);
1302 catch (Tango::DevFailed)
1304 delete buffer;
1305 buffer = NULL;
1308 return buffer;
1311 void TangoHKLAdapter::pseudo_axis_init(PseudoAxisAdapter *buffer, bool init)
1313 omni_mutex_lock lock(_lock);
1315 hkl_pseudo_axis_engine_init(buffer->_pseudo_r->engine);
1316 hkl_pseudo_axis_engine_init(buffer->_pseudo_w->engine);
1319 void TangoHKLAdapter::pseudo_axis_write(PseudoAxisAdapter * buffer, double value)
1321 omni_mutex_lock lock(_lock);
1323 int res = HKL_FAIL;
1325 HklPseudoAxisEngineList *engines_w_real = _diffractometer->engines_w_real;
1326 HklPseudoAxisEngine *engine = buffer->_pseudo_w->engine;
1327 HklGeometry *geometry_w_real = _diffractometer->geometry_w_real;
1329 hkl_parameter_set_value_unit((HklParameter *)buffer->_pseudo_w, value);
1330 res = hkl_pseudo_axis_engine_setter(buffer->_pseudo_w->engine);
1331 //hkl_pseudo_axis_engine_fprintf(stdout, buffer->_pseudo_w->engine);
1332 if (HKL_SUCCESS == res){
1333 hkl_geometry_init_geometry(geometry_w_real, engine->engines->geometries->geometries[0]);
1334 hkl_pseudo_axis_engine_list_getter(engines_w_real);
1336 _angles_idx = 0;
1337 this->update_angles();
1338 buffer->to_proxies();
1339 this->update_axis_adapters();
1340 this->update_pseudo_axis_adapters_from_hkl();
1341 this->update_pseudo_axes_adapters_from_hkl();
1342 }else
1343 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not write on this pseudo axis",
1344 "Check the sample");
1348 Tango::DevString *TangoHKLAdapter::pseudo_axis_get_mode(PseudoAxisAdapter const *buffer)
1350 omni_mutex_lock lock(_lock);
1352 return const_cast<Tango::DevString *>(&buffer->_pseudo_r->engine->mode->name);
1355 void TangoHKLAdapter::pseudo_axis_set_mode(PseudoAxisAdapter *buffer, Tango::DevString const & mode)
1357 omni_mutex_lock lock(_lock);
1359 size_t i, len;
1361 len = HKL_LIST_LEN(buffer->_pseudo_r->engine->modes);
1362 for(i=0; i<len; ++i)
1363 if(!strcasecmp(mode, buffer->_pseudo_r->engine->modes[i]->name))
1364 break;
1365 if(i<len){
1366 hkl_pseudo_axis_engine_select_mode(buffer->_pseudo_r->engine, i);
1367 hkl_pseudo_axis_engine_select_mode(buffer->_pseudo_w->engine, i);
1371 void TangoHKLAdapter::pseudo_axis_get_mode_parameters(PseudoAxisAdapter *buffer, Tango::DevVarDoubleStringArray *argout)
1373 omni_mutex_lock lock(_lock);
1375 HklPseudoAxisEngine *engine = buffer->_pseudo_r->engine;
1376 if (engine && engine->mode){
1377 size_t i;
1378 size_t len = HKL_LIST_LEN(engine->mode->parameters);
1380 argout->svalue.length(len);
1381 argout->dvalue.length(len);
1382 for(i=0; i<len; ++i){
1383 argout->svalue[i] = CORBA::string_dup(engine->mode->parameters[i].name);
1384 argout->dvalue[i] = hkl_parameter_get_value_unit(&engine->mode->parameters[i]);
1386 }else
1387 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not get the current Mode parameters values without a current mode set.",
1388 "");
1391 void TangoHKLAdapter::pseudo_axis_set_mode_parameters(PseudoAxisAdapter *buffer, const Tango::DevVarDoubleStringArray *argin)
1393 omni_mutex_lock lock(_lock);
1395 if(argin->svalue.length() != argin->dvalue.length())
1396 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1397 "set_mode_parameters_values did not receive the same amount between string and double values");
1399 HklPseudoAxisEngine *engine_r = buffer->_pseudo_r->engine;
1400 HklPseudoAxisEngine *engine_w = buffer->_pseudo_w->engine;
1401 if (engine_r && engine_w){
1402 size_t i;
1403 size_t len;
1405 len = argin->svalue.length();
1406 if (HKL_LIST_LEN(engine_r->mode->parameters) != len)
1407 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Not the right number of parameter",
1408 "gives the right number of parameters");
1410 for(i=0; i<len; ++i){
1411 double value = argin->dvalue[i];
1412 char const *name = argin->svalue[i];
1413 if(!strcmp(name, engine_r->mode->parameters[i].name)){
1414 hkl_parameter_set_value_unit(&engine_r->mode->parameters[i], value);
1415 hkl_parameter_set_value_unit(&engine_w->mode->parameters[i], value);
1418 }else
1419 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set the current Mode parameters values without a current mode set.",
1420 "");
1423 /*******************/
1424 /* pseudoAxes part */
1425 /*******************/
1427 PseudoAxesAdapter *TangoHKLAdapter::pseudo_axes_adapter_get_by_name(std::string const & name)
1429 //omni_mutex_lock lock(_lock);
1431 unsigned int i;
1432 PseudoAxesAdapter *adapter = NULL;
1434 for(i=0; i<_pseudoAxesAdapters.size(); ++i)
1435 if(_pseudoAxesAdapters[i]->get_name() == name){
1436 adapter = _pseudoAxesAdapters[i];
1437 break;
1439 return adapter;
1443 void TangoHKLAdapter::pseudo_axes_write(size_t idx, Matrix<double> const & write)
1445 omni_mutex_lock lock(_lock);
1447 size_t i, len;
1448 int res = HKL_FAIL;
1449 HklPseudoAxisEngineList *engines_r, *engines_w;
1450 HklGeometry *geometry_r, *geometry_w;
1452 engines_r = _diffractometer->engines_r;
1453 engines_w = _diffractometer->engines_w;
1454 len = HKL_LIST_LEN(engines_w->engines[idx]->pseudoAxes);
1456 geometry_r = _diffractometer->geometry_r;
1457 geometry_w = _diffractometer->geometry_w;
1459 for(i=0; i<len; ++i)
1460 hkl_parameter_set_value_unit((HklParameter *)(engines_w->engines[idx]->pseudoAxes[i]), write.data[i]);
1462 res = hkl_pseudo_axis_engine_setter(engines_w->engines[idx]);
1463 // hkl_pseudo_axis_engine_fprintf(stderr, engines_w->engines[idx]);
1464 // hkl_geometry_fprintf(stderr, geometry_w);
1466 if (HKL_SUCCESS == res){
1467 hkl_geometry_init_geometry(geometry_w, engines_w->geometries->geometries[0]);
1468 hkl_pseudo_axis_engine_list_getter(engines_w);
1469 if(this->simulated){
1470 hkl_geometry_init_geometry(geometry_r, engines_w->geometries->geometries[0]);
1471 hkl_pseudo_axis_engine_list_getter(engines_r);
1474 _angles_idx = 0;
1475 this->update_angles();
1476 this->update_axis_adapters();
1477 this->update_pseudo_axis_adapters_from_hkl();
1478 this->update_pseudo_axes_adapters_from_hkl();
1479 }else
1480 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not write on this pseudo axis",
1481 "Check the sample");
1485 Tango::DevString *TangoHKLAdapter::pseudo_axes_get_mode(size_t idx)
1487 omni_mutex_lock lock(_lock);
1489 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1490 if(engine->mode)
1491 return const_cast<Tango::DevString *>(&engine->mode->name);
1492 else
1493 return NULL;
1496 void TangoHKLAdapter::pseudo_axes_set_mode(size_t idx, const Tango::DevString name)
1498 omni_mutex_lock lock(_lock);
1500 size_t i;
1501 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1503 // check if we try to set the same mode than the current one
1504 if (engine->mode)
1505 if(!strcasecmp(name, engine->mode->name))
1506 return;
1508 // no so set the mode if possible
1509 size_t len = HKL_LIST_LEN(engine->modes);
1510 for(i=0; i<len; ++i)
1511 if(!strcasecmp(name, engine->modes[i]->name))
1512 break;
1513 if(i<len){
1514 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_r->engines[idx], i);
1515 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_w->engines[idx], i);
1516 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_r_real->engines[idx], i);
1517 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_w_real->engines[idx], i);
1518 _pseudoAxesAdapters[idx]->update_axes_i(engine);
1519 _pseudoAxesAdapters[idx]->update_state_and_status_i();
1523 Matrix<char *> & TangoHKLAdapter::pseudo_axes_get_mode_parameters_names(size_t idx)
1525 omni_mutex_lock lock(_lock);
1527 size_t i;
1528 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1529 size_t len = HKL_LIST_LEN(engine->mode->parameters);
1530 PseudoAxesAdapter *adapter = _pseudoAxesAdapters[idx];
1531 adapter->_mode_parameters_names.resize(len, 1);
1532 for(i=0; i<len; ++i)
1533 adapter->_mode_parameters_names.data[i] = const_cast<char *>(engine->mode->parameters[i].name);
1534 return adapter->_mode_parameters_names;
1537 Matrix<double> const & TangoHKLAdapter::pseudo_axes_get_mode_parameters(size_t idx)
1539 omni_mutex_lock lock(_lock);
1541 size_t i;
1542 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1543 size_t len = HKL_LIST_LEN(engine->mode->parameters);
1544 PseudoAxesAdapter *adapter = _pseudoAxesAdapters[idx];
1545 adapter->_mode_parameters.resize(len, 1);
1546 for(i=0; i<len; ++i)
1547 adapter->_mode_parameters.data[i] = hkl_parameter_get_value_unit(&engine->mode->parameters[i]);
1548 return adapter->_mode_parameters;
1551 void TangoHKLAdapter::pseudo_axes_set_mode_parameters(size_t idx, Matrix<double> const & values)
1553 omni_mutex_lock lock(_lock);
1555 size_t i;
1556 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1557 size_t len = HKL_LIST_LEN(engine->mode->parameters);
1558 if(len == values.xdim)
1559 for(i=0; i<len; ++i){
1560 double & value = values.data[i];
1562 hkl_parameter_set_value_unit(&_diffractometer->engines_r->engines[idx]->mode->parameters[i],
1563 value);
1564 hkl_parameter_set_value_unit(&_diffractometer->engines_w->engines[idx]->mode->parameters[i],
1565 value);
1566 hkl_parameter_set_value_unit(&_diffractometer->engines_r_real->engines[idx]->mode->parameters[i],
1567 value);
1568 hkl_parameter_set_value_unit(&_diffractometer->engines_w_real->engines[idx]->mode->parameters[i],
1569 value);
1573 void TangoHKLAdapter::pseudo_axes_init(size_t idx)
1575 omni_mutex_lock lock(_lock);
1577 HklPseudoAxisEngine *engine_r = _diffractometer->engines_r->engines[idx];
1578 HklPseudoAxisEngine *engine_w = _diffractometer->engines_w->engines[idx];
1579 HklPseudoAxisEngine *engine_r_real = _diffractometer->engines_r_real->engines[idx];
1580 HklPseudoAxisEngine *engine_w_real = _diffractometer->engines_w_real->engines[idx];
1582 hkl_pseudo_axis_engine_init(engine_r);
1583 hkl_pseudo_axis_engine_init(engine_w);
1584 hkl_pseudo_axis_engine_init(engine_r_real);
1585 hkl_pseudo_axis_engine_init(engine_w_real);
1588 void TangoHKLAdapter::pseudo_axes_add_dynamic_attributes(size_t idx)
1590 //omni_mutex_lock lock(_lock);
1592 size_t i, j;
1594 // check if all the PseudoAxes were instantiated
1595 for(i=0; i<_pseudoAxesAdapters.size(); ++i)
1596 if(!_pseudoAxesAdapters[i]->_device)
1597 return;
1600 * we need to attach the dynamic attributes after all instance of
1601 * the PseudoAxes devices were started. otherwise it cause problem.
1603 for(i=0; i<_pseudoAxesAdapters.size(); ++i){
1604 PseudoAxesAdapter *adapter = _pseudoAxesAdapters[i];
1606 for(j=0; j<adapter->_dynamic_attribute_pseudo_axes_axis.size(); ++j)
1607 adapter->_device->add_attribute(adapter->_dynamic_attribute_pseudo_axes_axis[j]);
1611 void TangoHKLAdapter::pseudo_axes_remove_dynamic_attributes(size_t idx)
1613 size_t i;
1614 PseudoAxesAdapter *adapter;
1616 adapter = _pseudoAxesAdapters[idx];
1617 for(i=0; i<adapter->_dynamic_attribute_pseudo_axes_axis.size(); ++i)
1618 adapter->_device->remove_attribute(adapter->_dynamic_attribute_pseudo_axes_axis[i]);
1621 void TangoHKLAdapter::pseudo_axes_create_and_start_devices(void)
1623 omni_mutex_lock lock(_lock);
1625 unsigned int i, j;
1627 Tango::Util *tg = Tango::Util::instance();
1628 Tango::Database *db = tg->get_database();
1629 for(i=0; i<_pseudoAxesAdapters.size(); ++i){
1630 std::string dev_name = _pseudoAxesAdapters[i]->get_proxy_name();
1632 // first check if the device is already defined in the database
1633 try{
1634 Tango::DbDevImportInfo my_device_import_info;
1636 my_device_import_info = db->import_device(dev_name);
1637 } catch (Tango::DevFailed &) {
1638 Tango::DbDevInfo my_device_info;
1640 // add the device to the database
1641 my_device_info.name = dev_name.c_str();
1642 my_device_info._class = "PseudoAxes";
1643 my_device_info.server = tg->get_ds_name().c_str();
1645 db->add_device(my_device_info);
1647 // add the right properties to that device
1648 Tango::DbDatum DiffractometerProxy("DiffractometerProxy"), EngineName("EngineName");
1649 Tango::DbData properties;
1650 DiffractometerProxy << _device->name();
1651 EngineName << _pseudoAxesAdapters[i]->get_name();
1652 properties.push_back(DiffractometerProxy);
1653 properties.push_back(EngineName);
1654 db->put_device_property(dev_name,properties);
1657 // now start the device
1658 const std::vector<Tango::DeviceClass *> *cl_list = tg->get_class_list();
1659 for(j=0; j<cl_list->size(); ++j){
1660 if((*cl_list)[j]->get_name() == "PseudoAxes"){
1661 try{
1662 Tango::DevVarStringArray na;
1663 na.length(1);
1664 na[0] = dev_name.c_str();
1665 (*cl_list)[j]->device_factory(&na);
1666 std::cout << "Started " << dev_name << std::endl;
1667 break;
1669 catch (Tango::DevFailed &e)
1678 /**********************/
1679 /* Dynamic attributes */
1680 /**********************/
1682 void TangoHKLAdapter::create_axes_dynamic_attributes(void)
1684 size_t i;
1685 size_t len = _axes.size();
1686 _dynamic_attribute_axes_names.resize(len, 1);
1687 for(i=0; i<len; ++i){
1688 std::string name;
1689 AxisAttrib *att;
1691 // compute the pseudo axis name
1692 name = "axis";
1693 name += _axes[i].get_name();
1694 name[4] = toupper(name[4]);
1696 // create the PseudoAxesAttribut
1697 att = new AxisAttrib(name.c_str(), _axes[i]);
1698 _dynamic_attribute_axes.push_back(att);
1699 _dynamic_attribute_axes_names.data[i] = const_cast<char *>(att->get_name().c_str());
1703 void TangoHKLAdapter::add_dynamic_attributes_to_device(void)
1705 size_t i;
1707 for(i=0; i<_dynamic_attribute_axes.size(); ++i)
1708 _device->add_attribute(_dynamic_attribute_axes[i]);
1712 void TangoHKLAdapter::delete_dynamic_attributes(void)
1714 size_t i;
1716 for(i=0; i<_dynamic_attribute_axes.size(); ++i)
1717 _device->remove_attribute(_dynamic_attribute_axes[i], true);
1721 void TangoHKLAdapter::set_simulated(bool simulated)
1723 bool old = this->simulated;
1724 this->simulated = simulated;
1725 if (old == true && simulated == false)
1726 this->update();
1729 } // namespace
1731 std::string hkl_axes_consign_as_string(HklAxis const **axes, size_t axes_len)
1733 size_t i;
1734 std::string out;
1736 std::ostringstream line, tmp;
1737 for(i=0; i<axes_len; ++i) {
1738 HklParameter const *axis = (HklParameter const *)axes[i];
1739 double value = hkl_parameter_get_value_unit(axis);
1741 out += " \"";
1742 out += axis->name;
1743 out + "\" ";
1744 std::ostringstream tmp;
1745 tmp << showpos;
1746 tmp << value << "°";
1747 out += tmp.str();
1750 return out;