Merge branch 'maint' into next
[diffractometer.git] / src / TangoHKLAdapter.cpp
blobe8f257d7818c3a1134025d59b679749c2861c0fc
1 #include <iomanip>
3 #include <hkl/hkl-pseudoaxis.h>
5 #include "macros.h"
6 #include "TangoHKLAdapter.h"
7 #include "Diffractometer.h"
8 #include "PseudoAxes.h"
9 #include "AxisAdapter.h"
10 #include "AxisAttrib.h"
11 #include "PseudoAxesAttrib.h"
13 //#define DEBUG
14 #ifndef NDEBUG
15 # define STDOUT(stream) std::cout << stream
16 #else
17 # define STDOUT(stream) {};
18 #endif
20 namespace Diffractometer_ns
22 //+----------------------------------------------------------------------------
24 // method : TangoHKLAdapter::TangoHKLAdapter(string &s)
26 // description : constructor for the adapter between HKl library and Tango
28 // in : - type : Type of diffractometer to instancate
30 //-----------------------------------------------------------------------------
31 TangoHKLAdapter::TangoHKLAdapter(Diffractometer *device, HklGeometryType type) :
32 _device(device),
33 _type(type)
35 size_t i, len;
36 HklAxis *axes_r;
37 HklAxis *axes_w;
38 HklAxis *axes_r_real;
39 HklAxis *axes_w_real;
40 const HklGeometryConfig *config;
42 this->ready = false;
43 _auto_update_from_proxies = false;
44 _lambdaAttributeProxy = NULL;
45 _wrong_nb_of_axis_proxies = false;
46 _ux = 0;
47 _uy = 0;
48 _uz = 0;
49 _uxfit = true;
50 _uyfit = true;
51 _uzfit = true;
52 _angles_idx = 0;
54 duration.Start();
56 // Create the hkl part
57 // 4 geometries
58 config = hkl_geometry_factory_get_config_from_type(type);
60 _diffractometer = new HklDiffractometer;
61 _diffractometer->geometry_r = hkl_geometry_factory_new(config, 50 * HKL_DEGTORAD);
62 _diffractometer->geometry_w = hkl_geometry_factory_new(config, 50 * HKL_DEGTORAD);
63 _diffractometer->geometry_r_real = hkl_geometry_factory_new(config, 50 * HKL_DEGTORAD);
64 _diffractometer->geometry_w_real = hkl_geometry_factory_new(config, 50 * HKL_DEGTORAD);
66 // 2 detectors
67 _diffractometer->detector = hkl_detector_factory_new(HKL_DETECTOR_TYPE_0D);
68 _diffractometer->detector->idx = 1;
70 _diffractometer->detector_real = hkl_detector_factory_new(HKL_DETECTOR_TYPE_0D);
71 _diffractometer->detector_real->idx = 1;
73 // 1 sample list
74 _diffractometer->samples = hkl_sample_list_new();
76 // the pseudoAxesenginesList (one per geometry)
77 _diffractometer->engines_r = hkl_pseudo_axis_engine_list_factory(config);
78 _diffractometer->engines_w = hkl_pseudo_axis_engine_list_factory(config);
79 _diffractometer->engines_r_real = hkl_pseudo_axis_engine_list_factory(config);
80 _diffractometer->engines_w_real = hkl_pseudo_axis_engine_list_factory(config);
81 this->update_pseudo_axis_engines();
83 // fill the axisAdapter.
84 len = HKL_LIST_LEN(_diffractometer->geometry_r->axes);
85 axes_r = _diffractometer->geometry_r->axes;
86 axes_w = _diffractometer->geometry_w->axes;
87 axes_r_real = _diffractometer->geometry_r_real->axes;
88 axes_w_real = _diffractometer->geometry_w_real->axes;
89 for(i=0; i<len; ++i)
90 _axes.push_back(AxisAdapter(this, &axes_r[i], &axes_w[i], &axes_r_real[i], &axes_w_real[i]));
92 // hack to connect all axes the first time
93 _auto_update_from_proxies = true;
94 this->connect_all_proxies();
95 _auto_update_from_proxies = false;
97 // fill the pseudoAxesAdapters
99 omni_mutex_lock lock(_lock);
101 len = HKL_LIST_LEN(_diffractometer->engines_r->engines);
102 _pseudo_axes_proxies.resize(len, 1);
103 for(i=0; i<len; ++i){
104 PseudoAxesAdapter *adapter;
105 HklPseudoAxisEngine *engine_r = _diffractometer->engines_r->engines[i];
106 HklPseudoAxisEngine *engine_w = _diffractometer->engines_w->engines[i];
107 adapter = new PseudoAxesAdapter(this, i, engine_r, engine_w);
108 _pseudoAxesAdapters.push_back(adapter);
109 _pseudo_axes_proxies.data[i] = const_cast<char *>(adapter->_proxy_name.c_str());
113 // create the dynamic attributes
114 this->create_axes_dynamic_attributes();
116 // set the default lambda
117 this->set_lambda(1.54);
120 TangoHKLAdapter::~TangoHKLAdapter(void)
122 unsigned int i;
124 this->destroy_axes_dynamic_attributes();
126 // remove all pseudo axis adapters
127 for(i=0;i<_pseudoAxisAdapters.size();i++)
128 delete _pseudoAxisAdapters[i];
130 // remove all pseudo axes adapters;
131 for(i=0; i<_pseudoAxesAdapters.size(); ++i)
132 delete _pseudoAxesAdapters[i];
134 // remove all axisAdapter
135 _axes.clear();
137 if (_lambdaAttributeProxy)
138 delete _lambdaAttributeProxy;
140 // remove the hkl part
141 hkl_geometry_free(_diffractometer->geometry_r);
142 hkl_geometry_free(_diffractometer->geometry_w);
143 hkl_geometry_free(_diffractometer->geometry_r_real);
144 hkl_geometry_free(_diffractometer->geometry_w_real);
145 hkl_detector_free(_diffractometer->detector);
146 hkl_detector_free(_diffractometer->detector_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 && _auto_update_from_proxies)
165 && _device->lambdaAttributeProxy != "") {
168 _lambdaAttributeProxy = new Tango::AttributeProxy(_device->lambdaAttributeProxy);
170 catch(...) {
174 // connect the axes proxies
175 if (!this->ready && _auto_update_from_proxies) {
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 axis.connect(proxy_name);
197 free(line);
199 if (!axis.is_ready())
200 ready = false;
203 this->ready = ready;
208 void TangoHKLAdapter::set_lambda(double lambda)
210 omni_mutex_lock lock(_lock);
212 if ((!_auto_update_from_proxies || _device->lambdaAttributeProxy == "")
213 && lambda > 0){
214 _lambda = lambda;
215 _diffractometer->geometry_r->source.wave_length = lambda;
216 _diffractometer->geometry_w->source.wave_length = lambda;
217 _diffractometer->geometry_r_real->source.wave_length = lambda;
218 _diffractometer->geometry_w_real->source.wave_length = lambda;
222 // this method connect engines to the right geometry, detector and sample
223 void TangoHKLAdapter::update_pseudo_axis_engines(void)
225 hkl_pseudo_axis_engine_list_init(_diffractometer->engines_r,
226 _diffractometer->geometry_r,
227 _diffractometer->detector,
228 _diffractometer->samples->current);
230 hkl_pseudo_axis_engine_list_init(_diffractometer->engines_w,
231 _diffractometer->geometry_w,
232 _diffractometer->detector,
233 _diffractometer->samples->current);
235 hkl_pseudo_axis_engine_list_init(_diffractometer->engines_r_real,
236 _diffractometer->geometry_r_real,
237 _diffractometer->detector,
238 _diffractometer->samples->current);
240 hkl_pseudo_axis_engine_list_init(_diffractometer->engines_w_real,
241 _diffractometer->geometry_w_real,
242 _diffractometer->detector,
243 _diffractometer->samples->current);
246 void TangoHKLAdapter::update_lambda(void)
248 if (_lambdaAttributeProxy && _auto_update_from_proxies){
249 try{
250 _lambdaAttributeProxy->read() >> _lambda;
251 _diffractometer->geometry_r->source.wave_length = _lambda;
252 _diffractometer->geometry_w->source.wave_length = _lambda;
253 _diffractometer->geometry_r_real->source.wave_length = _lambda;
254 _diffractometer->geometry_w_real->source.wave_length = _lambda;
256 catch (Tango::DevFailed &){
258 }else
259 _lambda = _diffractometer->geometry_r->source.wave_length;
263 * this method update the angles attribut from the engines->geometry list
265 void TangoHKLAdapter::update_angles(void)
267 size_t i, j;
268 size_t xdim;
269 size_t ydim;
270 HklPseudoAxisEngine *engine;
271 double *data;
272 HklGeometryListItem **items;
274 if(!_auto_update_from_proxies)
275 engine = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_w, "hkl");
276 else
277 engine = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_w_real, "hkl");
279 // update the computed_angles part
280 xdim = 1 + HKL_LIST_LEN(_diffractometer->geometry_r->axes);
281 ydim = hkl_geometry_list_len(engine->engines->geometries);
283 _angles.resize(xdim, ydim);
284 _angles.clear();
286 //fill the array
287 data = _angles.data;
288 items = engine->engines->geometries->items;
289 for(j=0; j<ydim; ++j){
290 HklGeometry *geom = items[j]->geometry;
292 data[0] = j;
293 for(i=1; i<xdim; ++i)
294 data[i] = hkl_axis_get_value_unit(&geom->axes[i-1]);
295 data += xdim;
300 * this method update the reflections_angles when we change a sample parameter
302 void TangoHKLAdapter::update_reflections_angles(void)
304 HklSample *sample = _diffractometer->samples->current;
305 if (sample) {
306 unsigned int i, j;
307 size_t rdim;
308 double *data;
310 // the reflection Angles
311 rdim = HKL_LIST_LEN(sample->reflections);
312 _reflections_angles.resize(rdim, rdim);
313 _reflections_angles.clear();
315 data = _reflections_angles.data;
316 for(i=0; i<rdim; ++i) {
317 for(j=0; j<rdim; ++j) {
318 double angle = 0.;
319 if (j < i)
320 angle = hkl_sample_get_reflection_theoretical_angle(sample, i, j);
321 else if (j > i)
322 angle = hkl_sample_get_reflection_mesured_angle(sample, i, j);
324 *data = angle * HKL_RADTODEG;
325 data++;
331 void TangoHKLAdapter::update_reflections(void)
333 HklSample *sample = _diffractometer->samples->current;
334 if (sample) {
336 // Allocation of the image
337 unsigned int xdim = 6 + HKL_LIST_LEN(_diffractometer->geometry_r->axes);
338 unsigned int ydim = HKL_LIST_LEN(sample->reflections);
339 _reflections.resize(xdim, ydim);
341 size_t i = 0;
342 double *data = _reflections.data;
343 for(i=0; i<ydim; ++i) {
344 HklSampleReflection *r;
346 r = hkl_sample_get_ith_reflection(sample, i);
347 if (r) {
348 size_t k;
349 HklAxis *axes = r->geometry->axes;
351 data[0] = i;
352 data[1] = r->hkl.data[0];
353 data[2] = r->hkl.data[1];
354 data[3] = r->hkl.data[2];
355 data[4] = 0;
356 data[5] = (double)r->flag;
358 for(k=0; k<HKL_LIST_LEN(r->geometry->axes); ++k)
359 data[6 + k] = hkl_axis_get_value_unit(&axes[k]);
361 data += xdim;
366 void TangoHKLAdapter::update_ub(void)
368 HklSample const *sample = _diffractometer->samples->current;
369 if(sample){
370 size_t dim = 3;
371 _ub.resize(dim, dim);
372 _ub.set_data_from_buffer(&(sample->UB.data[0][0]), dim, dim);
376 void TangoHKLAdapter::update_ux_uy_uz(void)
378 HklSample *sample = _diffractometer->samples->current;
380 if(sample){
381 hkl_matrix_to_euler(&sample->U, &_ux, &_uy, &_uz);
382 _ux *= HKL_RADTODEG;
383 _uy *= HKL_RADTODEG;
384 _uz *= HKL_RADTODEG;
389 * this method update all the AxisAdapter from the proxy every 200 ms.
390 * this from_proxy get the real part from the proxy and the "sim" part
391 * from the HklAxis in simulated mode or from the proxy in real mode
392 * else it updates them from the HklAxis.
394 * every 200 ms
395 * simulated:
396 * real <- proxy
397 * sim <- HklAxis
398 * non simulated:
399 * real <- proxy
400 * sim <- proxy
401 * rest of the time
402 * real <- HklAxis
403 * simulated -> HklAxis
405 void TangoHKLAdapter::update_axis_adapters(void)
407 size_t i;
409 // first read from the proxy.
410 duration.Stop();
411 if(duration.GetDurationInMs() >= 200) {
412 for(size_t i=0; i<_axes.size(); ++i)
413 _axes[i].from_proxy(!_auto_update_from_proxies);
414 duration.Start();
415 }else
416 for(i=0; i<_axes.size(); ++i)
417 _axes[i].from_HklAxis();
420 void TangoHKLAdapter::update_hkl_from_axis_adapters(void)
422 size_t i;
424 // set the axis
425 for(i=0; i<_axes.size(); ++i)
426 _axes[i].to_HklAxis();
428 // update the pseudo axes
429 if(_diffractometer && _diffractometer->samples){
430 hkl_pseudo_axis_engine_list_get(_diffractometer->engines_r);
431 hkl_pseudo_axis_engine_list_get(_diffractometer->engines_w);
432 hkl_pseudo_axis_engine_list_get(_diffractometer->engines_r_real);
433 hkl_pseudo_axis_engine_list_get(_diffractometer->engines_w_real);
437 void TangoHKLAdapter::update_pseudo_axis_adapters_from_hkl(void)
439 for(size_t i=0;i<_pseudoAxisAdapters.size();++i)
440 _pseudoAxisAdapters[i]->update();
443 void TangoHKLAdapter::update_proxies_from_axis_adapters(void)
445 size_t i;
447 // first stop motion of all axes.
448 for(i=0; i<_axes.size(); ++i)
449 _axes[i].stop();
451 // then send write values to the proxies
452 for(i=0; i<_axes.size(); ++i)
453 _axes[i].to_proxy();
456 void TangoHKLAdapter::update_proxies_from_pseudo_axis_adapters(PseudoAxisAdapter *adapter)
458 adapter->to_proxies();
461 void TangoHKLAdapter::update_pseudo_axes_adapters_from_hkl(void)
463 for(size_t i=0; i<_pseudoAxesAdapters.size(); ++i)
464 _pseudoAxesAdapters[i]->update();
467 void TangoHKLAdapter::update_state_and_status(void)
469 Tango::DevState state;
470 std::string status;
471 std::string extra_status;
473 state = Tango::STANDBY;
474 if (!_auto_update_from_proxies)
475 status = "AutoUpdateFromProxies OFF";
476 else {
477 status = "AutoUpdateFromProxies ON";
479 if (!this->ready) {
480 state = Tango::FAULT;
481 extra_status += "\nCan not connect to axes proxies";
482 // update the monochromator proxy status.
483 if (!_lambdaAttributeProxy && _auto_update_from_proxies) {
484 extra_status += "\nCan not connect to the lambdaAttributeProxy";
485 extra_status += "\nCheck also the lambdaAttributeProxy property";
487 } else {
488 try {
489 for(unsigned int i=0; i<_axes.size(); ++i) {
490 AxisAdapter const & axis = _axes[i];
491 std::string proxy_name = axis.get_proxy_name();
492 Tango::DevState tmpState = axis.get_state();
494 ::compose_state(state, tmpState);
495 if (tmpState != Tango::STANDBY)
496 extra_status += "\n" + proxy_name + " is in " + Tango::DevStateName[tmpState];
498 } catch(...)
500 state = Tango::FAULT;
501 extra_status += "\nCan not connect to axes proxies";
507 if (_diffractometer){
508 status += "\nSample: ";
509 if(!_diffractometer->samples->current){
510 status += "Not yet Set";
511 state = Tango::FAULT;
512 } else
513 status += _diffractometer->samples->current->name;
514 if (state == Tango::STANDBY)
515 extra_status += "\nready to compute hkl";
516 }else{
517 state = Tango::FAULT;
518 extra_status += "\nhkl core not yet initialized !!!";
520 status += "\nDiffractometer status: ";
521 status += Tango::DevStateName[state];
522 status += extra_status;
524 _diffractometerConfig.state = state;
525 _diffractometerConfig.status = status;
528 void TangoHKLAdapter::update(void)
530 /**********************************************
531 * CRITICAL SECTION
532 **********************************************/
533 omni_mutex_lock lock(_lock);
535 this->update_lambda();
536 this->update_axis_adapters();
537 this->update_hkl_from_axis_adapters();
538 this->update_pseudo_axis_adapters_from_hkl();
539 this->update_pseudo_axes_adapters_from_hkl();
540 this->update_state_and_status();
541 /**********************************************
542 * END OF CRITICAL SECTION
543 **********************************************/
546 /********************/
547 /* State and status */
548 /********************/
549 void TangoHKLAdapter::get_diffractometer_config(DiffractometerConfig & config)
551 omni_mutex_lock lock(_lock);
553 config = _diffractometerConfig;
556 /************/
557 /* hkl part */
558 /************/
560 short & TangoHKLAdapter::get_angles_idx(void)
562 omni_mutex_lock lock(_lock);
564 return _angles_idx;
567 void TangoHKLAdapter::set_angles_idx(short idx)
569 omni_mutex_lock lock(_lock);
571 // A REVOIR
572 if(idx >= 0 && idx < (int)_angles.ydim){
573 size_t i;
574 double *values;
576 _angles_idx = idx;
577 values = &_angles.data[1 + idx * _angles.xdim];
578 for(i=0; i<_axes.size(); ++i)
579 this->write_axis_i(_axes[i], values[i]);
583 void TangoHKLAdapter::load(void)
585 this->load_1();
588 void TangoHKLAdapter::load_1(void)
590 unsigned long nb_properties;
592 // Get the Crystal Attributes properties.
593 Tango::DbData properties;
594 properties.push_back(Tango::DbDatum("Crystal"));
595 _device->get_db_device()->get_attribute_property(properties);
597 // the first one is the number of properties
598 properties[0] >> nb_properties;
600 if (nb_properties > 1) {
601 unsigned long i, j;
602 HklGeometry *geometry;
603 HklDetector *detector;
605 geometry = hkl_geometry_new_copy(_diffractometer->geometry_r);
606 detector = hkl_detector_new_copy(_diffractometer->detector);
608 hkl_sample_list_clear(_diffractometer->samples);
609 for(i=1; i<=nb_properties; ++i) {
610 // skip the _ver property
611 if(!strcasecmp("_ver", properties[i].name.c_str()))
612 continue;
614 HklSample * sample;
616 // The name of the property name is the name of a crystal.
617 sample = hkl_sample_new(properties[i].name.c_str(), HKL_SAMPLE_TYPE_MONOCRYSTAL);
619 // Extract the lines store in the property
620 std::vector<std::string> lines;
621 properties[i] >> lines;
623 for(j=0; j<lines.size(); j++) {
624 char *line = strdup(lines[j].c_str());
625 char *last;
626 char *key = strtok_r(line, "=", &last);
628 if (!strcmp(key,"lattice")) {
629 double a = atof(strtok_r(NULL, ";", &last));
630 double b = atof(strtok_r(NULL, ";", &last));
631 double c = atof(strtok_r(NULL, ";", &last));
632 double alpha = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
633 double beta = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
634 double gamma = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
635 hkl_sample_set_lattice(sample, a, b, c, alpha, beta, gamma);
637 sample->lattice->a->fit = atoi(strtok_r(NULL, ";", &last));
638 sample->lattice->b->fit = atoi(strtok_r(NULL, ";", &last));
639 sample->lattice->c->fit = atoi(strtok_r(NULL, ";", &last));
640 sample->lattice->alpha->fit = atoi(strtok_r(NULL, ";", &last));
641 sample->lattice->beta->fit = atoi(strtok_r(NULL, ";", &last));
642 sample->lattice->gamma->fit = atoi(strtok_r(NULL, ";", &last));
643 } else if (!strcmp(key, "uxuyuz")){
644 double ux = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
645 double uy = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
646 double uz = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
647 hkl_sample_set_U_from_euler(sample, ux, uy, uz);
648 } else if (!strcmp(key,"reflection")) {
649 unsigned int idx = 0;
650 HklSampleReflection *reflection;
652 double wavelength = atof(strtok_r(NULL, ";", &last));
653 double h = atof(strtok_r(NULL, ";", &last));
654 double k = atof(strtok_r(NULL, ";", &last));
655 double l = atof(strtok_r(NULL, ";", &last));
656 int flag = atoi(strtok_r(NULL, ";", &last));
658 // first set the geometry axes
659 while(key = strtok_r(NULL, ";", &last))
660 hkl_axis_set_value_unit(&geometry->axes[idx++], atof(key));
661 geometry->source.wave_length = wavelength;
663 reflection = hkl_sample_add_reflection(sample, geometry, detector, h, k, l);
664 reflection->flag = flag;
666 free(line);
667 // End of key research
668 }// End for each parameters
669 hkl_sample_list_append(_diffractometer->samples, sample);
670 }// End for each property
672 hkl_detector_free(detector);
673 hkl_geometry_free(geometry);
675 //_device->refresh_crystal_parameters();
679 void TangoHKLAdapter::save(void)
681 omni_mutex_lock lock(_lock);
683 size_t i, j, k;
684 size_t len;
685 Tango::DbData crystal_prop;
686 Tango::DbData data_put;
688 // Step 1 : clean all properties
689 // FP Le mieux serait sans doute de ne pas effacer les propriétés d'attribut
690 // avant d'avoir crée correctement un data_put.
691 crystal_prop.push_back(Tango::DbDatum("Crystal"));
692 _device->get_db_device()->get_attribute_property(crystal_prop);
693 long number_of_prop = 0;
694 crystal_prop[0] >> number_of_prop ;
695 if( number_of_prop > 0)
696 _device->get_db_device()->delete_attribute_property(crystal_prop);
698 // Step 2 : create the Crystal properties
699 Tango::DbDatum properties("Crystal");
700 // Put number of properties (= nb of samples + 1)
701 len = hkl_sample_list_len(_diffractometer->samples);
702 properties << (long)(len + 1);
703 data_put.push_back(properties);
705 // first property is the format version
706 Tango::DbDatum version("_ver");
707 version << (long)FORMAT_VERSION;
708 data_put.push_back(version);
710 // now each sample
711 for(k=0; k<len; ++k){
712 HklSample *sample;
713 std::vector<std::string> lines;
714 char line[256];
716 // the lattices values
717 sample = hkl_sample_list_get_ith(_diffractometer->samples, k);
718 double a = hkl_parameter_get_value_unit(sample->lattice->a);
719 double b = hkl_parameter_get_value_unit(sample->lattice->b);
720 double c = hkl_parameter_get_value_unit(sample->lattice->c);
721 double alpha = hkl_parameter_get_value_unit(sample->lattice->alpha);
722 double beta = hkl_parameter_get_value_unit(sample->lattice->beta);
723 double gamma = hkl_parameter_get_value_unit(sample->lattice->gamma);
724 // the fit flag
725 int a_fit = sample->lattice->a->fit;
726 int b_fit = sample->lattice->b->fit;
727 int c_fit = sample->lattice->c->fit;
728 int alpha_fit = sample->lattice->alpha->fit;
729 int beta_fit = sample->lattice->beta->fit;
730 int gamma_fit = sample->lattice->gamma->fit;
732 snprintf(line, 255, "lattice=%f;%f;%f;%f;%f;%f;%d;%d;%d;%d;%d;%d",
733 a, b, c, alpha, beta, gamma,
734 a_fit, b_fit, c_fit, alpha_fit, beta_fit, gamma_fit);
735 lines.push_back(line);
737 // the UxUyUz parameters
738 double ux, uy, uz;
739 hkl_matrix_to_euler(&sample->U, &ux, &uy, &uz);
740 ux *= HKL_RADTODEG;
741 uy *= HKL_RADTODEG;
742 uz *= HKL_RADTODEG;
744 snprintf(line, 255, "uxuyuz=%f;%f;%f", ux, uy, uz);
745 lines.push_back(line);
747 // the reflections
748 for(i=0; i<HKL_LIST_LEN(sample->reflections); ++i) {
749 HklSampleReflection *reflection;
751 reflection = hkl_sample_get_ith_reflection(sample, i);
752 double wavelength = reflection->geometry->source.wave_length;
753 double h = reflection->hkl.data[0];
754 double k = reflection->hkl.data[1];
755 double l = reflection->hkl.data[2];
756 int flag = reflection->flag;
758 snprintf(line, 255, "reflection=%f;%f;%f;%f;%d",
759 wavelength, h, k, l, flag);
760 // Extract values of each axes
761 for(j=0; j<HKL_LIST_LEN(reflection->geometry->axes); ++j) {
762 char pos[256];
763 double rad = hkl_axis_get_value_unit(&reflection->geometry->axes[j]);
764 snprintf(pos, 255, ";%f", rad);
765 strncat(line, pos, 255);
767 lines.push_back(line);
770 // Try to create property
771 // Get crystal name
772 Tango::DbDatum property(sample->name);
773 property << lines;
774 data_put.push_back(property);
777 //update database for this property
778 _device->get_db_device()->put_attribute_property(data_put);
781 /***************/
782 /* sample part */
783 /***************/
785 char const *TangoHKLAdapter::get_sample_name(void)
787 omni_mutex_lock lock(_lock);
789 HklSample *sample = _diffractometer->samples->current;
790 if(sample)
791 return sample->name;
792 else
793 return "";
796 void TangoHKLAdapter::set_current_sample(char const * name)
798 omni_mutex_lock lock(_lock);
800 HklSample *last;
802 last = _diffractometer->samples->current;
803 if (HKL_SUCCESS == hkl_sample_list_select_current(_diffractometer->samples, name))
804 if (last != _diffractometer->samples->current){
805 this->update_pseudo_axis_engines();
806 this->update_ub();
807 this->update_ux_uy_uz();
808 this->update_reflections_angles();
809 this->update_reflections();
810 this->update_state_and_status();
814 void TangoHKLAdapter::get_sample_lattices(double *a, double *b, double *c,
815 double *alpha, double *beta, double *gamma,
816 double *a_star, double *b_star, double *c_star,
817 double *alpha_star, double *beta_star, double *gamma_star)
819 omni_mutex_lock lock(_lock);
821 HklSample * sample = _diffractometer->samples->current;
822 if (!sample)
823 return;
825 HklLattice const *lattice = sample->lattice;
826 HklLattice *reciprocal = hkl_lattice_new_copy(lattice);
828 hkl_lattice_reciprocal(lattice, reciprocal);
830 // direct space
831 *a = hkl_parameter_get_value_unit(lattice->a);
832 *b = hkl_parameter_get_value_unit(lattice->b);
833 *c = hkl_parameter_get_value_unit(lattice->c);
834 *alpha = hkl_parameter_get_value_unit(lattice->alpha);
835 *beta = hkl_parameter_get_value_unit(lattice->beta);
836 *gamma = hkl_parameter_get_value_unit(lattice->gamma);
838 // reciprocal space
839 *a_star = hkl_parameter_get_value_unit(reciprocal->a);
840 *b_star = hkl_parameter_get_value_unit(reciprocal->b);
841 *c_star = hkl_parameter_get_value_unit(reciprocal->c);
842 *alpha_star = hkl_parameter_get_value_unit(reciprocal->alpha);
843 *beta_star = hkl_parameter_get_value_unit(reciprocal->beta);
844 *gamma_star = hkl_parameter_get_value_unit(reciprocal->gamma);
846 hkl_lattice_free(reciprocal);
849 void TangoHKLAdapter::get_sample_fit(bool *afit, bool *bfit, bool *cfit,
850 bool *alphafit, bool *betafit, bool *gammafit,
851 bool *uxfit, bool *uyfit, bool *uzfit)
853 omni_mutex_lock lock(_lock);
855 HklSample * sample = _diffractometer->samples->current;
856 if (!sample)
857 return;
859 HklLattice const *lattice = sample->lattice;
861 *afit = lattice->a->fit;
862 *bfit = lattice->b->fit;
863 *cfit = lattice->c->fit;
864 *alphafit = lattice->alpha->fit;
865 *betafit = lattice->beta->fit;
866 *gammafit = lattice->gamma->fit;
867 *uxfit = _uxfit;
868 *uyfit = _uyfit;
869 *uzfit = _uzfit;
873 void TangoHKLAdapter::set_sample_Ux(double ux)
875 HklSample *sample;
877 sample = _diffractometer->samples->current;
878 if (sample){
879 if (HKL_SUCCESS == hkl_sample_set_U_from_euler(sample,
880 ux * HKL_DEGTORAD,
881 _uy * HKL_DEGTORAD,
882 _uz * HKL_DEGTORAD)){
883 _ux = ux;
884 this->update_ub();
885 }else
886 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this Ux value",
887 "Set a correct value");
891 void TangoHKLAdapter::set_sample_Uy(double uy)
893 HklSample *sample;
895 sample = _diffractometer->samples->current;
896 if (sample){
897 if (HKL_SUCCESS == hkl_sample_set_U_from_euler(sample,
898 _ux * HKL_DEGTORAD,
899 uy * HKL_DEGTORAD,
900 _uz * HKL_DEGTORAD)){
901 _uy = uy;
902 this->update_ub();
903 }else
904 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this Uy value",
905 "Set a correct value");
909 void TangoHKLAdapter::set_sample_Uz(double uz)
911 HklSample *sample;
913 sample = _diffractometer->samples->current;
914 if (sample){
915 if (HKL_SUCCESS == hkl_sample_set_U_from_euler(sample,
916 _ux * HKL_DEGTORAD,
917 _uy * HKL_DEGTORAD,
918 uz * HKL_DEGTORAD)){
919 _uz = uz;
920 this->update_ub();
921 }else
922 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this Uz value",
923 "Set a correct value");
927 void TangoHKLAdapter::set_sample_AFit(bool fit)
929 HklSample *sample;
931 sample = _diffractometer->samples->current;
932 if (sample)
933 sample->lattice->a->fit = fit;
936 void TangoHKLAdapter::set_sample_BFit(bool fit)
938 HklSample *sample;
940 sample = _diffractometer->samples->current;
941 if (sample)
942 sample->lattice->b->fit = fit;
945 void TangoHKLAdapter::set_sample_CFit(bool fit)
947 HklSample *sample;
949 sample = _diffractometer->samples->current;
950 if (sample)
951 sample->lattice->c->fit = fit;
954 void TangoHKLAdapter::set_sample_AlphaFit(bool fit)
956 HklSample *sample;
958 sample = _diffractometer->samples->current;
959 if (sample)
960 sample->lattice->alpha->fit = fit;
963 void TangoHKLAdapter::set_sample_BetaFit(bool fit)
965 HklSample *sample;
967 sample = _diffractometer->samples->current;
968 if (sample)
969 sample->lattice->beta->fit = fit;
972 void TangoHKLAdapter::set_sample_GammaFit(bool fit)
974 HklSample *sample;
976 sample = _diffractometer->samples->current;
977 if (sample)
978 sample->lattice->gamma->fit = fit;
981 void TangoHKLAdapter::set_sample_UxFit(bool fit)
983 HklSample *sample;
985 sample = _diffractometer->samples->current;
986 if (sample)
987 _uxfit = _uyfit = _uzfit = fit;
990 void TangoHKLAdapter::set_sample_UyFit(bool fit)
992 HklSample *sample;
994 sample = _diffractometer->samples->current;
995 if (sample)
996 _uxfit = _uyfit = _uzfit = fit;
999 void TangoHKLAdapter::set_sample_UzFit(bool fit)
1001 HklSample *sample;
1003 sample = _diffractometer->samples->current;
1004 if (sample)
1005 _uxfit = _uyfit = _uzfit = fit;
1008 void TangoHKLAdapter::add_new_sample(std::string const & name)
1010 omni_mutex_lock lock(_lock);
1012 HklSample *sample = hkl_sample_new(name.c_str(), HKL_SAMPLE_TYPE_MONOCRYSTAL);
1014 if (!hkl_sample_list_append(_diffractometer->samples, sample)){
1015 hkl_sample_free(sample);
1016 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not add a sample with this name",
1017 "A sample with the same name is already present in the sample list");
1021 void TangoHKLAdapter::copy_sample_as(Tango::DevString copy_name)
1023 omni_mutex_lock lock(_lock);
1025 HklSample *sample;
1026 HklSample const *current;
1028 current = _diffractometer->samples->current;
1029 if(!current)
1030 TANGO_EXCEPTION_THROW_WITHOUT_LOG("No current sample set",
1031 "Please set a current sample");
1033 sample = hkl_sample_list_get_by_name(_diffractometer->samples, copy_name);
1034 if (sample)
1035 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not add a sample with this name",
1036 "A sample with the same name is already present in the sample list");
1038 sample = hkl_sample_new_copy(current);
1039 if(sample){
1040 hkl_sample_set_name(sample, copy_name);
1041 hkl_sample_list_append(_diffractometer->samples, sample);
1045 void TangoHKLAdapter::del_sample(void)
1047 omni_mutex_lock lock(_lock);
1049 HklSampleList *samples = _diffractometer->samples;
1050 hkl_sample_list_del(samples, samples->current);
1052 // add a default sample if no more sample in the list
1053 if(hkl_sample_list_len(samples) == 0){
1054 HklSample *sample = hkl_sample_new("default", HKL_SAMPLE_TYPE_MONOCRYSTAL);
1055 samples->current = hkl_sample_list_append(samples, sample);
1056 }else
1057 samples->current = hkl_sample_list_get_ith(samples, 0);
1058 this->update_ub();
1059 this->update_ux_uy_uz();
1060 this->update_reflections_angles();
1061 this->update_reflections();
1064 void TangoHKLAdapter::set_lattice(const Tango::DevVarDoubleArray *argin)
1066 omni_mutex_lock lock(_lock);
1068 if (argin && argin->length() != 6)
1069 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1070 "Did not receive the exact amount of crystal parameters: A, B, C, alpha, beta, gamma");
1072 HklSample *sample = _diffractometer->samples->current;
1073 if (HKL_FAIL == hkl_sample_set_lattice(sample,
1074 (*argin)[0],(*argin)[1], (*argin)[2],
1075 (*argin)[3] * HKL_DEGTORAD,
1076 (*argin)[4] * HKL_DEGTORAD,
1077 (*argin)[5] * HKL_DEGTORAD))
1079 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this lattice combination.",
1080 "Please set a good combination");
1081 this->update_ub();
1082 this->update_reflections_angles();
1085 void TangoHKLAdapter::add_reflection(const Tango::DevVarDoubleArray *argin)
1087 omni_mutex_lock lock(_lock);
1089 HklSample *sample = _diffractometer->samples->current;
1091 if(sample){
1092 double h, k, l;
1093 HklSampleReflection *ref;
1095 if(argin && argin->length() == 3){
1096 h = (*argin)[0];
1097 k = (*argin)[1];
1098 l = (*argin)[2];
1099 }else{
1100 HklPseudoAxisEngine *engine;
1102 engine = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_r, "hkl");
1104 h = hkl_parameter_get_value_unit((HklParameter *)engine->pseudoAxes[0]);
1105 k = hkl_parameter_get_value_unit((HklParameter *)engine->pseudoAxes[1]);
1106 l = hkl_parameter_get_value_unit((HklParameter *)engine->pseudoAxes[2]);
1109 ref = hkl_sample_add_reflection(sample,
1110 _diffractometer->geometry_r,
1111 _diffractometer->detector,
1112 h, k, l);
1113 if(ref){
1114 this->update_reflections_angles();
1115 this->update_reflections();
1120 void TangoHKLAdapter::del_reflection(Tango::DevShort argin)
1122 omni_mutex_lock lock(_lock);
1124 if (HKL_FAIL == hkl_sample_del_reflection(_diffractometer->samples->current, argin))
1125 TANGO_EXCEPTION_THROW_WITHOUT_LOG("index out of range",
1126 "change the reflection index");
1127 this->update_reflections_angles();
1128 this->update_reflections();
1131 void TangoHKLAdapter::set_reflections(Matrix<double> const & img)
1133 omni_mutex_lock lock(_lock);
1135 HklSample *sample = _diffractometer->samples->current;
1136 if (sample
1137 && img.xdim == _reflections.xdim
1138 && img.ydim == _reflections.ydim) {
1140 size_t i = 0;
1141 size_t j = 0;
1142 for(i=0; i<HKL_LIST_LEN(sample->reflections); ++i) {
1143 HklSampleReflection *r;
1145 r = hkl_sample_get_ith_reflection(sample, i);
1146 if (r) {
1147 hkl_sample_reflection_set_hkl(r, img.data[j+1], img.data[j+2], img.data[j+3]);
1148 hkl_sample_reflection_set_flag(r, (int)img.data[j+5]);
1149 if(!_device->protectReflectionAxes){
1150 HklAxis *axes;
1151 size_t len;
1152 size_t k;
1154 len = HKL_LIST_LEN(r->geometry->axes);
1155 axes = &r->geometry->axes[0];
1157 for(k=6; k<6+len; ++k)
1158 hkl_axis_set_value_unit(axes++, img.data[j+k]);
1160 hkl_geometry_update(r->geometry);
1161 hkl_sample_reflection_set_geometry(r, r->geometry);
1164 j += _reflections.xdim;
1166 this->update_reflections();
1167 this->update_reflections_angles();
1171 double TangoHKLAdapter::affine_sample(std::string name)
1173 omni_mutex_lock lock(_lock);
1175 HklSample *sample;
1176 double res = 0.;
1178 sample = hkl_sample_list_get_by_name(_diffractometer->samples, name.c_str());
1179 if(sample){
1180 HklSample *tmp;
1182 // check if the affine sample is already in the HklSampleList
1183 std::string name = sample->name;
1184 name += "(affine)";
1185 tmp = hkl_sample_list_get_by_name(_diffractometer->samples, name.c_str());
1186 hkl_sample_list_del(_diffractometer->samples, tmp);
1188 tmp = hkl_sample_new_copy(sample);
1189 hkl_sample_set_name(tmp, name.c_str());
1190 res = hkl_sample_affine(tmp);
1192 hkl_sample_list_append(_diffractometer->samples, tmp);
1193 _diffractometer->samples->current = tmp;
1195 this->update_ub();
1196 this->update_ux_uy_uz();
1197 this->update_reflections_angles();
1200 return res;
1204 std::vector<std::string> TangoHKLAdapter::get_samples_names(void)
1206 omni_mutex_lock lock(_lock);
1208 std::vector<std::string> names;
1209 size_t i, len;
1210 HklSampleList *samples = _diffractometer->samples;
1212 len = hkl_sample_list_len(samples);
1213 for(i=0; i<len; ++i)
1214 names.push_back(hkl_sample_list_get_ith(samples, i)->name);
1216 return names;
1219 // DEPRECATED
1220 void TangoHKLAdapter::get_sample_parameter_values(Tango::DevVarDoubleStringArray *argout)
1222 omni_mutex_lock lock(_lock);
1224 HklSample *sample;
1225 HklParameter *parameter = NULL;
1226 std::string name;
1228 //check parameters
1229 if (argout->svalue.length() != 1)
1230 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1231 "only one string = parameter name");
1233 sample = _diffractometer->samples->current;
1234 if(sample){
1235 //parameters OK
1236 name = argout->svalue[0];
1237 if(name == "a")
1238 parameter = sample->lattice->a;
1239 else if(name == "b")
1240 parameter = sample->lattice->b;
1241 else if(name == "c")
1242 parameter = sample->lattice->c;
1243 else if(name == "alpha")
1244 parameter = sample->lattice->alpha;
1245 else if(name == "beta")
1246 parameter = sample->lattice->beta;
1247 else if(name == "gamma")
1248 parameter = sample->lattice->gamma;
1250 if (parameter){
1251 argout->dvalue[0] = parameter->range.min;
1252 argout->dvalue[1] = parameter->range.max;
1253 argout->dvalue[2] = parameter->fit;
1254 }else
1255 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Wrong parameter name",
1256 "Select: a, b, c, alpha, beta, gamma");
1260 //DEPRECATED
1261 void TangoHKLAdapter::set_sample_parameter_values(Tango::DevVarDoubleStringArray const *argin)
1263 omni_mutex_lock lock(_lock);
1265 HklSample *sample;
1266 HklParameter *parameter = NULL;
1267 std::string name;
1269 // check parameters
1270 if(argin->dvalue.length() != 3)
1271 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1272 "set_crystal_parameter_values did not receive the right amount of scalar parameters: min, max, flag");
1273 if((argin->svalue.length() ) != 1)
1274 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1275 "set_crystal_parameter_values did not receive the right amount of string parameters: parameter name");
1277 // parameters OK
1278 sample = _diffractometer->samples->current;
1279 if(!sample)
1280 TANGO_EXCEPTION_THROW_WITHOUT_LOG("No current sample set",
1281 "Please set a current sample");
1283 name = argin->svalue[0];
1284 if(name == "a")
1285 parameter = sample->lattice->a;
1286 else if(name == "b")
1287 parameter = sample->lattice->b;
1288 else if(name == "c")
1289 parameter = sample->lattice->c;
1290 else if(name == "alpha")
1291 parameter = sample->lattice->alpha;
1292 else if(name == "beta")
1293 parameter = sample->lattice->beta;
1294 else if(name == "gamma")
1295 parameter = sample->lattice->gamma;
1297 if (parameter){
1298 parameter->range.min = argin->dvalue[0];
1299 parameter->range.max = argin->dvalue[1];
1300 parameter->fit = argin->dvalue[2] != 0.;
1301 }else
1302 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Wrong parameter name",
1303 "Select: a, b, c, alpha, beta, gamma");
1304 this->update_ub();
1305 this->update_ux_uy_uz();
1306 this->update_reflections_angles();
1309 void TangoHKLAdapter::compute_u(const Tango::DevVarLongArray *argin)
1311 omni_mutex_lock lock(_lock);
1313 HklSample *sample;
1315 // is parameter ok ?
1316 if (argin->length() != 2)
1317 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Need exactly two reflections indexes",
1318 "use the right number of parameters");
1320 sample = _diffractometer->samples->current;
1321 if (!sample)
1322 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not compute the U matrix without current sample set.",
1323 "Set a current sample");
1325 if (hkl_sample_compute_UB_busing_levy(sample, (*argin)[0], (*argin)[1]))
1326 TANGO_EXCEPTION_THROW_WITHOUT_LOG("can not compute the UB matrix using thoses reflections index",
1327 "Use other reflections");
1328 this->update_ub();
1329 this->update_ux_uy_uz();
1332 /*************/
1333 /* Axis part */
1334 /*************/
1336 void TangoHKLAdapter::read_axis(int idx, double & read, double & write)
1338 omni_mutex_lock lock(_lock);
1340 AxisAdapter & axis = _axes[idx];
1341 read = axis.get_read();
1342 write = axis.get_write();
1345 void TangoHKLAdapter::stop_all_axis(void)
1347 #ifdef WRITE_TO_PROXY_ALLOWED
1348 size_t i;
1349 for(i=0; i<_axes.size(); ++i)
1350 _axes[i].stop();
1351 #endif
1354 void TangoHKLAdapter::write_axis(AxisAdapter & axis, double value)
1356 omni_mutex_lock lock(_lock);
1358 size_t i;
1360 this->write_axis_i(axis, value);
1362 // when we write on an Axis you must let all pseudo axes be synchronized
1363 for(i=0; i<_pseudoAxesAdapters.size(); ++i)
1364 _pseudoAxesAdapters[i]->_synchronize = true;
1367 void TangoHKLAdapter::write_axis_i(AxisAdapter & axis, double value)
1369 axis._read = axis._write = value;
1370 hkl_axis_set_value_unit(axis._axis_r, value);
1371 hkl_axis_set_value_unit(axis._axis_w, value);
1374 /*******************/
1375 /* pseudoAxis part */
1376 /*******************/
1378 std::vector<std::string> TangoHKLAdapter::pseudo_axis_get_names(void)
1380 omni_mutex_lock lock(_lock);
1382 std::vector<std::string> names;
1383 size_t i, j;
1385 for(i=0; i<HKL_LIST_LEN(_diffractometer->engines_r_real->engines); ++i){
1386 HklPseudoAxisEngine *engine;
1388 engine = _diffractometer->engines_r_real->engines[i];
1389 for(j=0; j<HKL_LIST_LEN(engine->pseudoAxes); ++j)
1390 names.push_back(((HklParameter *)(&engine->pseudoAxes[j]))->name);
1393 return names;
1396 PseudoAxisAdapter *TangoHKLAdapter::pseudo_axis_buffer_new(char const *name)
1398 omni_mutex_lock lock(_lock);
1400 PseudoAxisAdapter * buffer = NULL;
1401 HklPseudoAxis *pseudo_r;
1402 HklPseudoAxis *pseudo_w;
1404 pseudo_r = hkl_pseudo_axis_engine_list_get_pseudo_axis_by_name(
1405 _diffractometer->engines_r_real, name);
1406 pseudo_w = hkl_pseudo_axis_engine_list_get_pseudo_axis_by_name(
1407 _diffractometer->engines_w_real, name);
1409 if(pseudo_r && pseudo_w) {
1412 buffer = new PseudoAxisAdapter(*this, pseudo_r, pseudo_w);
1413 _pseudoAxisAdapters.push_back(buffer);
1415 catch (Tango::DevFailed)
1417 delete buffer;
1418 buffer = NULL;
1421 return buffer;
1424 void TangoHKLAdapter::pseudo_axis_set_initialized(PseudoAxisAdapter *buffer,
1425 Tango::DevBoolean initialized)
1427 if(initialized){
1428 this->update();
1430 omni_mutex_lock lock(_lock);
1432 hkl_pseudo_axis_engine_initialize(buffer->_pseudo_r->engine, NULL);
1433 hkl_pseudo_axis_engine_initialize(buffer->_pseudo_w->engine, NULL);
1437 void TangoHKLAdapter::pseudo_axis_set_position(PseudoAxisAdapter *buffer,
1438 const Tango::DevDouble & position)
1440 omni_mutex_lock lock(_lock);
1442 double value = position - buffer->_config.offset;
1443 int res = HKL_FAIL;
1445 HklPseudoAxisEngineList *engines_w_real = _diffractometer->engines_w_real;
1446 HklPseudoAxisEngine *engine = buffer->_pseudo_w->engine;
1447 HklGeometry *geometry_w_real = _diffractometer->geometry_w_real;
1449 hkl_parameter_set_value_unit((HklParameter *)buffer->_pseudo_w, value);
1450 res = hkl_pseudo_axis_engine_set(buffer->_pseudo_w->engine, NULL);
1451 if (HKL_SUCCESS == res){
1452 hkl_geometry_init_geometry(geometry_w_real,
1453 engine->engines->geometries->items[0]->geometry);
1454 hkl_pseudo_axis_engine_list_get(engines_w_real);
1456 _angles_idx = 0;
1457 this->update_angles();
1458 buffer->to_proxies();
1459 this->update_axis_adapters();
1460 this->update_pseudo_axis_adapters_from_hkl();
1461 this->update_pseudo_axes_adapters_from_hkl();
1462 }else
1463 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not write on this pseudo axis",
1464 "Check the sample");
1468 PseudoAxisConfig TangoHKLAdapter::pseudo_axis_get_config(PseudoAxisAdapter *buffer)
1470 this->update();
1472 omni_mutex_lock lock(_lock);
1474 return buffer->_config;
1477 void TangoHKLAdapter::pseudo_axis_set_mode(PseudoAxisAdapter *buffer, Tango::DevString const & mode)
1479 omni_mutex_lock lock(_lock);
1481 size_t i, len;
1483 len = HKL_LIST_LEN(buffer->_pseudo_r->engine->modes);
1484 for(i=0; i<len; ++i)
1485 if(!strcasecmp(mode, buffer->_pseudo_r->engine->modes[i]->name))
1486 break;
1487 if(i<len){
1488 hkl_pseudo_axis_engine_select_mode(buffer->_pseudo_r->engine, i);
1489 hkl_pseudo_axis_engine_select_mode(buffer->_pseudo_w->engine, i);
1493 void TangoHKLAdapter::pseudo_axis_get_mode_parameters(PseudoAxisAdapter *buffer, Tango::DevVarDoubleStringArray *argout)
1495 omni_mutex_lock lock(_lock);
1497 HklPseudoAxisEngine *engine = buffer->_pseudo_r->engine;
1498 if (engine && engine->mode){
1499 size_t i;
1500 size_t len = HKL_LIST_LEN(engine->mode->parameters);
1502 argout->svalue.length(len);
1503 argout->dvalue.length(len);
1504 for(i=0; i<len; ++i){
1505 argout->svalue[i] = CORBA::string_dup(engine->mode->parameters[i].name);
1506 argout->dvalue[i] = hkl_parameter_get_value_unit(&engine->mode->parameters[i]);
1508 }else
1509 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not get the current Mode parameters values without a current mode set.",
1510 "");
1513 void TangoHKLAdapter::pseudo_axis_set_mode_parameters(PseudoAxisAdapter *buffer, const Tango::DevVarDoubleStringArray *argin)
1515 omni_mutex_lock lock(_lock);
1517 if(argin->svalue.length() != argin->dvalue.length())
1518 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1519 "set_mode_parameters_values did not receive the same amount between string and double values");
1521 HklPseudoAxisEngine *engine_r = buffer->_pseudo_r->engine;
1522 HklPseudoAxisEngine *engine_w = buffer->_pseudo_w->engine;
1523 if (engine_r && engine_w){
1524 size_t i;
1525 size_t len;
1527 len = argin->svalue.length();
1528 if (HKL_LIST_LEN(engine_r->mode->parameters) != len)
1529 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Not the right number of parameter",
1530 "gives the right number of parameters");
1532 for(i=0; i<len; ++i){
1533 double value = argin->dvalue[i];
1534 char const *name = argin->svalue[i];
1535 if(!strcmp(name, engine_r->mode->parameters[i].name)){
1536 hkl_parameter_set_value_unit(&engine_r->mode->parameters[i], value);
1537 hkl_parameter_set_value_unit(&engine_w->mode->parameters[i], value);
1540 }else
1541 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set the current Mode parameters values without a current mode set.",
1542 "");
1545 void TangoHKLAdapter::pseudo_axis_on(PseudoAxisAdapter *buffer)
1547 omni_mutex_lock lock(_lock);
1549 for(size_t i=0; i<buffer->_axes.size(); ++i)
1550 buffer->_axes[i]->on();
1553 /*******************/
1554 /* pseudoAxes part */
1555 /*******************/
1557 PseudoAxesAdapter *TangoHKLAdapter::pseudo_axes_adapter_get_by_name(std::string const & name)
1559 //omni_mutex_lock lock(_lock);
1561 unsigned int i;
1562 PseudoAxesAdapter *adapter = NULL;
1564 for(i=0; i<_pseudoAxesAdapters.size(); ++i)
1565 if(_pseudoAxesAdapters[i]->get_name() == name){
1566 adapter = _pseudoAxesAdapters[i];
1567 break;
1569 return adapter;
1572 PseudoAxesConfig TangoHKLAdapter::pseudo_axes_get_config(size_t idx)
1574 this->update();
1576 omni_mutex_lock lock(_lock);
1578 return _pseudoAxesAdapters[idx]->_config;
1581 void TangoHKLAdapter::pseudo_axes_set_axis_value(size_t idx, size_t p_idx, double value)
1583 omni_mutex_lock lock(_lock);
1585 size_t i;
1587 for(i=0; i<_pseudoAxesAdapters.size(); ++i)
1588 if(i == idx){
1589 // first unsynchronize the current PseudoAxes
1590 _pseudoAxesAdapters[i]->_synchronize = false;
1591 _pseudoAxesAdapters[i]->_config.write.data[p_idx] = value;
1592 } else {
1593 // resynchronize all other pseudoAxes
1594 _pseudoAxesAdapters[i]->_synchronize = true;
1598 void TangoHKLAdapter::pseudo_axes_apply(size_t idx, Matrix<double> const & write) throw (Tango::DevFailed)
1600 omni_mutex_lock lock(_lock);
1602 size_t i, len;
1603 int res = HKL_FAIL;
1604 HklPseudoAxisEngineList *engines_r, *engines_w;
1605 HklGeometry *geometry_r, *geometry_w;
1607 engines_r = _diffractometer->engines_r;
1608 engines_w = _diffractometer->engines_w;
1609 len = HKL_LIST_LEN(engines_w->engines[idx]->pseudoAxes);
1611 geometry_r = _diffractometer->geometry_r;
1612 geometry_w = _diffractometer->geometry_w;
1614 for(i=0; i<len; ++i)
1615 hkl_parameter_set_value_unit((HklParameter *)(engines_w->engines[idx]->pseudoAxes[i]), write.data[i]);
1617 res = hkl_pseudo_axis_engine_set(engines_w->engines[idx], NULL);
1619 if (HKL_SUCCESS == res){
1620 // force auto update OFF when we write on a PseudoAxes.
1621 _auto_update_from_proxies = false;
1623 for(i=0; i<_pseudoAxesAdapters.size(); ++i)
1624 _pseudoAxesAdapters[i]->_synchronize = true;
1626 hkl_geometry_init_geometry(geometry_w,
1627 engines_w->geometries->items[0]->geometry);
1628 hkl_pseudo_axis_engine_list_get(engines_w);
1629 hkl_geometry_init_geometry(geometry_r,
1630 engines_w->geometries->items[0]->geometry);
1631 hkl_pseudo_axis_engine_list_get(engines_r);
1633 _angles_idx = 0;
1634 this->update_angles();
1635 this->update_axis_adapters();
1636 this->update_pseudo_axis_adapters_from_hkl();
1637 this->update_pseudo_axes_adapters_from_hkl();
1638 }else
1639 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not write on this pseudo axis",
1640 "Check the sample");
1644 void TangoHKLAdapter::pseudo_axes_set_mode(size_t idx, const Tango::DevString name)
1646 omni_mutex_lock lock(_lock);
1648 size_t i;
1649 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1651 // check if we try to set the same mode than the current one
1652 if (engine->mode)
1653 if(!strcasecmp(name, engine->mode->name))
1654 return;
1656 // no so set the mode if possible
1657 size_t len = HKL_LIST_LEN(engine->modes);
1658 for(i=0; i<len; ++i)
1659 if(!strcasecmp(name, engine->modes[i]->name))
1660 break;
1661 if(i<len){
1662 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_r->engines[idx], i);
1663 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_w->engines[idx], i);
1664 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_r_real->engines[idx], i);
1665 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_w_real->engines[idx], i);
1666 _pseudoAxesAdapters[idx]->update_axes_i(engine);
1667 _pseudoAxesAdapters[idx]->update();
1671 void TangoHKLAdapter::pseudo_axes_set_mode_parameters(size_t idx, Matrix<double> const & values)
1673 omni_mutex_lock lock(_lock);
1675 size_t i;
1676 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1677 size_t len = HKL_LIST_LEN(engine->mode->parameters);
1678 if(len == values.xdim)
1679 for(i=0; i<len; ++i){
1680 double & value = values.data[i];
1682 hkl_parameter_set_value_unit(&_diffractometer->engines_r->engines[idx]->mode->parameters[i],
1683 value);
1684 hkl_parameter_set_value_unit(&_diffractometer->engines_w->engines[idx]->mode->parameters[i],
1685 value);
1686 hkl_parameter_set_value_unit(&_diffractometer->engines_r_real->engines[idx]->mode->parameters[i],
1687 value);
1688 hkl_parameter_set_value_unit(&_diffractometer->engines_w_real->engines[idx]->mode->parameters[i],
1689 value);
1693 void TangoHKLAdapter::pseudo_axes_init(size_t idx)
1695 // temporary until the CAPOEIRA applycation has been modify
1696 if(_diffractometer->engines_r->engines[idx]->mode->initialize){
1697 omni_mutex_lock lock(_lock);
1699 HklPseudoAxisEngine *engine_r = _diffractometer->engines_r->engines[idx];
1700 HklPseudoAxisEngine *engine_w = _diffractometer->engines_w->engines[idx];
1701 HklPseudoAxisEngine *engine_r_real = _diffractometer->engines_r_real->engines[idx];
1702 HklPseudoAxisEngine *engine_w_real = _diffractometer->engines_w_real->engines[idx];
1704 hkl_pseudo_axis_engine_initialize(engine_r, NULL);
1705 hkl_pseudo_axis_engine_initialize(engine_w, NULL);
1706 hkl_pseudo_axis_engine_initialize(engine_r_real, NULL);
1707 hkl_pseudo_axis_engine_initialize(engine_w_real, NULL);
1708 }else
1709 this->pseudo_axes_apply(idx, _pseudoAxesAdapters[idx]->_config.write);
1712 void TangoHKLAdapter::pseudo_axes_add_dynamic_attributes(size_t idx)
1714 size_t i;
1716 // check if all the PseudoAxes were instantiated
1717 for(i=0; i<_pseudoAxesAdapters.size(); ++i)
1718 if(!_pseudoAxesAdapters[i]->_device)
1719 return;
1722 * we need to attach the dynamic attributes after all instance of
1723 * the PseudoAxes devices were started. otherwise it cause problem.
1724 * only add the attributs if they were not already added.
1726 for(i=0; i<_pseudoAxesAdapters.size(); ++i)
1727 _pseudoAxesAdapters[i]->add_dynamic_attributes_i();
1730 void TangoHKLAdapter::pseudo_axes_remove_dynamic_attributes(size_t idx)
1732 size_t i;
1733 PseudoAxesAdapter *adapter;
1735 adapter = _pseudoAxesAdapters[idx];
1736 if(adapter->_device){
1737 for(i=0; i<adapter->_dynamic_attribute_pseudo_axes_axis.size(); ++i)
1738 adapter->_device->remove_attribute(adapter->_dynamic_attribute_pseudo_axes_axis[i], false);
1739 adapter->_device = NULL;
1743 void TangoHKLAdapter::pseudo_axes_create_and_start_devices(void)
1745 omni_mutex_lock lock(_lock);
1747 unsigned int i, j;
1749 Tango::Util *tg = Tango::Util::instance();
1750 Tango::Database *db = tg->get_database();
1751 for(i=0; i<_pseudoAxesAdapters.size(); ++i){
1752 std::string dev_name = _pseudoAxesAdapters[i]->get_proxy_name();
1754 // first check if the device is already defined in the database
1755 try{
1756 Tango::DbDevImportInfo my_device_import_info;
1758 my_device_import_info = db->import_device(dev_name);
1759 } catch (Tango::DevFailed &) {
1760 Tango::DbDevInfo my_device_info;
1762 // add the device to the database
1763 my_device_info.name = dev_name.c_str();
1764 my_device_info._class = "PseudoAxes";
1765 my_device_info.server = tg->get_ds_name().c_str();
1767 db->add_device(my_device_info);
1769 // add the right properties to that device
1770 Tango::DbDatum DiffractometerProxy("DiffractometerProxy"), EngineName("EngineName");
1771 Tango::DbData properties;
1772 DiffractometerProxy << _device->name();
1773 EngineName << _pseudoAxesAdapters[i]->get_name();
1774 properties.push_back(DiffractometerProxy);
1775 properties.push_back(EngineName);
1776 db->put_device_property(dev_name,properties);
1779 // now start the device
1780 const std::vector<Tango::DeviceClass *> *cl_list = tg->get_class_list();
1781 for(j=0; j<cl_list->size(); ++j){
1782 if((*cl_list)[j]->get_name() == "PseudoAxes"){
1783 try{
1784 Tango::DevVarStringArray na;
1785 na.length(1);
1786 na[0] = dev_name.c_str();
1787 (*cl_list)[j]->device_factory(&na);
1788 std::cout << "Started " << dev_name << std::endl;
1789 break;
1791 catch (Tango::DevFailed &e)
1800 void TangoHKLAdapter::pseudo_axes_set_initialized(size_t idx, bool initialized)
1802 if(initialized){
1803 this->update();
1805 omni_mutex_lock lock(_lock);
1807 HklPseudoAxisEngine *engine_r = _diffractometer->engines_r->engines[idx];
1808 HklPseudoAxisEngine *engine_w = _diffractometer->engines_w->engines[idx];
1809 HklPseudoAxisEngine *engine_r_real = _diffractometer->engines_r_real->engines[idx];
1810 HklPseudoAxisEngine *engine_w_real = _diffractometer->engines_w_real->engines[idx];
1812 hkl_pseudo_axis_engine_initialize(engine_r, NULL);
1813 hkl_pseudo_axis_engine_initialize(engine_w, NULL);
1814 hkl_pseudo_axis_engine_initialize(engine_r_real, NULL);
1815 hkl_pseudo_axis_engine_initialize(engine_w_real, NULL);
1819 /**********************/
1820 /* Dynamic attributes */
1821 /**********************/
1823 void TangoHKLAdapter::create_axes_dynamic_attributes(void)
1825 size_t i;
1826 size_t len = _axes.size();
1827 _dynamic_attribute_axes_names.resize(len, 1);
1828 for(i=0; i<len; ++i){
1829 std::string name;
1830 AxisAttrib *att;
1831 size_t l;
1833 // compute the diffractometer axis names
1834 name = "Axis";
1835 l = name.size();
1836 name += _axes[i].get_name();
1837 name[l] = toupper(name[l]);
1839 // create the AxisAttrib to deal with the proxy connection.
1840 att = new AxisAttrib(name.c_str(), _axes[i]);
1841 _dynamic_attribute_axes.push_back(att);
1842 _dynamic_attribute_axes_names.data[i] = const_cast<char *>(att->get_name().c_str());
1846 void TangoHKLAdapter::destroy_axes_dynamic_attributes(void)
1848 size_t i;
1849 size_t len = _dynamic_attribute_axes.size();
1851 for(i=0; i<len; ++i)
1852 delete _dynamic_attribute_axes[i];
1855 void TangoHKLAdapter::attach_dynamic_attributes_to_device(void)
1857 size_t i;
1859 for(i=0; i<_dynamic_attribute_axes.size(); ++i)
1860 _device->add_attribute(_dynamic_attribute_axes[i]);
1864 void TangoHKLAdapter::detach_dynamic_attributes_from_device(void)
1866 size_t i;
1868 for(i=0; i<_dynamic_attribute_axes.size(); ++i)
1869 _device->remove_attribute(_dynamic_attribute_axes[i], false);
1873 bool TangoHKLAdapter::get_auto_update_from_proxies(void)
1875 omni_mutex_lock lock(_lock);
1877 return _auto_update_from_proxies;
1880 void TangoHKLAdapter::set_auto_update_from_proxies(bool update)
1882 bool old = _auto_update_from_proxies;
1883 _auto_update_from_proxies = update;
1884 if(old = false && update == true)
1885 this->update();
1888 } // namespace
1890 std::string hkl_axes_consign_as_string(HklAxis const **axes, size_t axes_len)
1892 size_t i;
1893 std::string out;
1895 std::ostringstream line, tmp;
1896 for(i=0; i<axes_len; ++i) {
1897 HklParameter const *axis = (HklParameter const *)axes[i];
1898 double value = hkl_parameter_get_value_unit(axis);
1900 out += " \"";
1901 out += axis->name;
1902 out + "\" ";
1903 std::ostringstream tmp;
1904 tmp << showpos;
1905 tmp << value << "°";
1906 out += tmp.str();
1909 return out;