* add the HklPseudoAxisEngine (read/write) in the PseudoAxesAdapter class
[diffractometer.git] / src / TangoHKLAdapter.cpp
blobc0350f66a87b0b91ac0f1cc332845805233c0c69
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 _auto_update_from_proxies = false;
51 _lambdaAttributeProxy = NULL;
52 _wrong_nb_of_axis_proxies = false;
53 _ux = 0;
54 _uy = 0;
55 _uz = 0;
56 _uxfit = true;
57 _uyfit = true;
58 _uzfit = true;
59 _angles_idx = 0;
61 duration.Start();
63 // Create the hkl part
64 // 4 geometries
65 _diffractometer = new HklDiffractometer;
66 _diffractometer->geometry_r = hkl_geometry_factory_new(type, 50 * HKL_DEGTORAD);
67 _diffractometer->geometry_w = hkl_geometry_factory_new(type, 50 * HKL_DEGTORAD);
68 _diffractometer->geometry_r_real = hkl_geometry_factory_new(type, 50 * HKL_DEGTORAD);
69 _diffractometer->geometry_w_real = hkl_geometry_factory_new(type, 50 * HKL_DEGTORAD);
71 // 2 detectors
72 _diffractometer->detector = hkl_detector_factory_new(HKL_DETECTOR_TYPE_0D);
73 _diffractometer->detector->idx = 1;
75 _diffractometer->detector_real = hkl_detector_factory_new(HKL_DETECTOR_TYPE_0D);
76 _diffractometer->detector_real->idx = 1;
78 // 1 sample list
79 _diffractometer->samples = hkl_sample_list_new();
81 // the pseudoAxesenginesList (one per geometry)
82 _diffractometer->engines_r = hkl_pseudo_axis_engine_list_factory(type);
83 _diffractometer->engines_w = hkl_pseudo_axis_engine_list_factory(type);
84 _diffractometer->engines_r_real = hkl_pseudo_axis_engine_list_factory(type);
85 _diffractometer->engines_w_real = hkl_pseudo_axis_engine_list_factory(type);
86 this->update_pseudo_axis_engines();
88 // fill the axisAdapter.
89 len = HKL_LIST_LEN(_diffractometer->geometry_r->axes);
90 axes_r = _diffractometer->geometry_r->axes;
91 axes_w = _diffractometer->geometry_w->axes;
92 axes_r_real = _diffractometer->geometry_r_real->axes;
93 axes_w_real = _diffractometer->geometry_w_real->axes;
94 for(i=0; i<len; ++i)
95 _axes.push_back(AxisAdapter(this, &axes_r[i], &axes_w[i], &axes_r_real[i], &axes_w_real[i]));
97 // hack to connect all axes the first time
98 _auto_update_from_proxies = true;
99 this->connect_all_proxies();
100 _auto_update_from_proxies = false;
102 // fill the pseudoAxesAdapters
104 omni_mutex_lock lock(_lock);
106 len = HKL_LIST_LEN(_diffractometer->engines_r->engines);
107 _pseudo_axes_proxies.resize(len, 1);
108 for(i=0; i<len; ++i){
109 PseudoAxesAdapter *adapter;
110 HklPseudoAxisEngine *engine_r = _diffractometer->engines_r->engines[i];
111 HklPseudoAxisEngine *engine_w = _diffractometer->engines_w->engines[i];
112 adapter = new PseudoAxesAdapter(this, i, engine_r, engine_w);
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 this->destroy_axes_dynamic_attributes();
131 // remove all pseudo axis adapters
132 for(i=0;i<_pseudoAxisAdapters.size();i++)
133 delete _pseudoAxisAdapters[i];
135 // remove all pseudo axes adapters;
136 for(i=0; i<_pseudoAxesAdapters.size(); ++i)
137 delete _pseudoAxesAdapters[i];
139 // remove all axisAdapter
140 _axes.clear();
142 if (_lambdaAttributeProxy)
143 delete _lambdaAttributeProxy;
145 // remove the hkl part
146 hkl_geometry_free(_diffractometer->geometry_r);
147 hkl_geometry_free(_diffractometer->geometry_w);
148 hkl_geometry_free(_diffractometer->geometry_r_real);
149 hkl_geometry_free(_diffractometer->geometry_w_real);
150 hkl_detector_free(_diffractometer->detector);
151 hkl_detector_free(_diffractometer->detector_real);
152 hkl_sample_list_free(_diffractometer->samples);
153 hkl_pseudo_axis_engine_list_free(_diffractometer->engines_r);
154 hkl_pseudo_axis_engine_list_free(_diffractometer->engines_w);
155 hkl_pseudo_axis_engine_list_free(_diffractometer->engines_r_real);
156 hkl_pseudo_axis_engine_list_free(_diffractometer->engines_w_real);
158 if(_diffractometer) {
159 delete _diffractometer;
160 _diffractometer = NULL;
164 void TangoHKLAdapter::connect_all_proxies(void)
166 omni_mutex_lock lock(_lock);
168 // connect the lambda proxy
169 if ((!_lambdaAttributeProxy && _auto_update_from_proxies)
170 && _device->lambdaAttributeProxy != "") {
173 _lambdaAttributeProxy = new Tango::AttributeProxy(_device->lambdaAttributeProxy);
175 catch(...) {
179 // connect the axes proxies
180 if (!this->ready && _auto_update_from_proxies) {
181 unsigned int nb;
183 nb = _device->realAxisProxies.size();
184 if (nb != _axes.size()) {
185 _wrong_nb_of_axis_proxies = true;
186 return;
187 } else {
188 unsigned int i, j;
189 bool ready = true;
191 for(i=0; i<nb; ++i) {
192 AxisAdapter & axis = _axes[i];
193 if (!axis.is_ready()){
194 // Find axis in the proxy list
195 for(j=0; j<nb; ++j) {
196 char *line = strdup(_device->realAxisProxies[j].c_str());
197 char *last;
198 char *axis_name = strtok_r(line, ":", &last);
199 char *proxy_name = strtok_r(NULL, ":", &last);
200 if (axis.get_name() == axis_name)
201 axis.connect(proxy_name);
202 free(line);
204 if (!axis.is_ready())
205 ready = false;
208 this->ready = ready;
213 void TangoHKLAdapter::set_lambda(double lambda)
215 omni_mutex_lock lock(_lock);
217 if ((!_auto_update_from_proxies || _device->lambdaAttributeProxy == "")
218 && lambda > 0){
219 _lambda = lambda;
220 _diffractometer->geometry_r->source.wave_length = lambda;
221 _diffractometer->geometry_w->source.wave_length = lambda;
222 _diffractometer->geometry_r_real->source.wave_length = lambda;
223 _diffractometer->geometry_w_real->source.wave_length = lambda;
227 // this method connect engines to the right geometry, detector and sample
228 void TangoHKLAdapter::update_pseudo_axis_engines(void)
230 hkl_pseudo_axis_engine_list_init(_diffractometer->engines_r,
231 _diffractometer->geometry_r,
232 _diffractometer->detector,
233 _diffractometer->samples->current);
235 hkl_pseudo_axis_engine_list_init(_diffractometer->engines_w,
236 _diffractometer->geometry_w,
237 _diffractometer->detector,
238 _diffractometer->samples->current);
240 hkl_pseudo_axis_engine_list_init(_diffractometer->engines_r_real,
241 _diffractometer->geometry_r_real,
242 _diffractometer->detector,
243 _diffractometer->samples->current);
245 hkl_pseudo_axis_engine_list_init(_diffractometer->engines_w_real,
246 _diffractometer->geometry_w_real,
247 _diffractometer->detector,
248 _diffractometer->samples->current);
251 void TangoHKLAdapter::update_lambda(void)
253 if (_lambdaAttributeProxy && _auto_update_from_proxies){
254 try{
255 _lambdaAttributeProxy->read() >> _lambda;
256 _diffractometer->geometry_r->source.wave_length = _lambda;
257 _diffractometer->geometry_w->source.wave_length = _lambda;
258 _diffractometer->geometry_r_real->source.wave_length = _lambda;
259 _diffractometer->geometry_w_real->source.wave_length = _lambda;
261 catch (Tango::DevFailed &){
263 }else
264 _lambda = _diffractometer->geometry_r->source.wave_length;
268 * this method update the angles attribut from the engines->geometry list
270 void TangoHKLAdapter::update_angles(void)
272 size_t i, j;
273 size_t xdim;
274 size_t ydim;
275 HklPseudoAxisEngine *engine;
276 double *data;
277 HklGeometry **geometries;
279 if(!_auto_update_from_proxies)
280 engine = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_w, "hkl");
281 else
282 engine = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_w_real, "hkl");
284 // update the computed_angles part
285 xdim = 1 + HKL_LIST_LEN(_diffractometer->geometry_r->axes);
286 ydim = HKL_LIST_LEN(engine->engines->geometries->geometries);
288 _angles.resize(xdim, ydim);
289 _angles.clear();
291 //fill the array
292 data = _angles.data;
293 geometries = engine->engines->geometries->geometries;
294 for(j=0; j<ydim; ++j){
295 HklGeometry *geom = geometries[j];
297 data[0] = j;
298 for(i=1; i<xdim; ++i)
299 data[i] = hkl_axis_get_value_unit(&geom->axes[i-1]);
300 data += xdim;
305 * this method update the reflections_angles when we change a sample parameter
307 void TangoHKLAdapter::update_reflections_angles(void)
309 HklSample *sample = _diffractometer->samples->current;
310 if (sample) {
311 unsigned int i, j;
312 size_t rdim;
313 double *data;
315 // the reflection Angles
316 rdim = HKL_LIST_LEN(sample->reflections);
317 _reflections_angles.resize(rdim, rdim);
318 _reflections_angles.clear();
320 data = _reflections_angles.data;
321 for(i=0; i<rdim; ++i) {
322 for(j=0; j<rdim; ++j) {
323 double angle = 0.;
324 if (j < i)
325 angle = hkl_sample_get_reflection_theoretical_angle(sample, i, j);
326 else if (j > i)
327 angle = hkl_sample_get_reflection_mesured_angle(sample, i, j);
329 *data = angle * HKL_RADTODEG;
330 data++;
336 void TangoHKLAdapter::update_reflections(void)
338 HklSample *sample = _diffractometer->samples->current;
339 if (sample) {
341 // Allocation of the image
342 unsigned int xdim = 6 + HKL_LIST_LEN(_diffractometer->geometry_r->axes);
343 unsigned int ydim = HKL_LIST_LEN(sample->reflections);
344 _reflections.resize(xdim, ydim);
346 size_t i = 0;
347 double *data = _reflections.data;
348 for(i=0; i<ydim; ++i) {
349 HklSampleReflection *r;
351 r = hkl_sample_get_ith_reflection(sample, i);
352 if (r) {
353 size_t k;
354 HklAxis *axes = r->geometry->axes;
356 data[0] = i;
357 data[1] = r->hkl.data[0];
358 data[2] = r->hkl.data[1];
359 data[3] = r->hkl.data[2];
360 data[4] = 0;
361 data[5] = (double)r->flag;
363 for(k=0; k<HKL_LIST_LEN(r->geometry->axes); ++k)
364 data[6 + k] = hkl_axis_get_value_unit(&axes[k]);
366 data += xdim;
371 void TangoHKLAdapter::update_ub(void)
373 HklSample const *sample = _diffractometer->samples->current;
374 if(sample){
375 size_t dim = 3;
376 _ub.resize(dim, dim);
377 _ub.set_data_from_buffer(&(sample->UB.data[0][0]), dim, dim);
381 void TangoHKLAdapter::update_ux_uy_uz(void)
383 HklSample *sample = _diffractometer->samples->current;
385 if(sample){
386 hkl_matrix_to_euler(&sample->U, &_ux, &_uy, &_uz);
387 _ux *= HKL_RADTODEG;
388 _uy *= HKL_RADTODEG;
389 _uz *= HKL_RADTODEG;
394 * this method update all the AxisAdapter from the proxy every 200 ms.
395 * this from_proxy get the real part from the proxy and the "sim" part
396 * from the HklAxis in simulated mode or from the proxy in real mode
397 * else it updates them from the HklAxis.
399 * every 200 ms
400 * simulated:
401 * real <- proxy
402 * sim <- HklAxis
403 * non simulated:
404 * real <- proxy
405 * sim <- proxy
406 * rest of the time
407 * real <- HklAxis
408 * simulated -> HklAxis
410 void TangoHKLAdapter::update_axis_adapters(void)
412 size_t i;
414 // first read from the proxy.
415 duration.Stop();
416 if(duration.GetDurationInMs() >= 200) {
417 for(size_t i=0; i<_axes.size(); ++i)
418 _axes[i].from_proxy(!_auto_update_from_proxies);
419 duration.Start();
420 }else
421 for(i=0; i<_axes.size(); ++i)
422 _axes[i].from_HklAxis();
425 void TangoHKLAdapter::update_hkl_from_axis_adapters(void)
427 size_t i;
429 // set the axis
430 for(i=0; i<_axes.size(); ++i)
431 _axes[i].to_HklAxis();
433 // update the pseudo axes
434 if(_diffractometer && _diffractometer->samples){
435 hkl_pseudo_axis_engine_list_get(_diffractometer->engines_r);
436 hkl_pseudo_axis_engine_list_get(_diffractometer->engines_w);
437 hkl_pseudo_axis_engine_list_get(_diffractometer->engines_r_real);
438 hkl_pseudo_axis_engine_list_get(_diffractometer->engines_w_real);
442 void TangoHKLAdapter::update_pseudo_axis_adapters_from_hkl(void)
444 for(size_t i=0;i<_pseudoAxisAdapters.size();++i)
445 _pseudoAxisAdapters[i]->update();
448 void TangoHKLAdapter::update_proxies_from_axis_adapters(void)
450 size_t i;
452 // first stop motion of all axes.
453 for(i=0; i<_axes.size(); ++i)
454 _axes[i].stop();
456 // then send write values to the proxies
457 for(i=0; i<_axes.size(); ++i)
458 _axes[i].to_proxy();
461 void TangoHKLAdapter::update_proxies_from_pseudo_axis_adapters(PseudoAxisAdapter *adapter)
463 adapter->to_proxies();
466 void TangoHKLAdapter::update_pseudo_axes_adapters_from_hkl(void)
468 size_t i, j, len;
469 HklPseudoAxisEngine *engine_r, *engine_w;
471 for(i=0; i<_pseudoAxesAdapters.size(); ++i){
472 PseudoAxesAdapter *adapter;
474 adapter = _pseudoAxesAdapters[i];
475 engine_r = _diffractometer->engines_r->engines[i];
476 engine_w = _diffractometer->engines_w->engines[i];
477 len = HKL_LIST_LEN(engine_r->pseudoAxes);
478 for(j=0; j<len; ++j){
479 adapter->_read.data[j] = hkl_parameter_get_value_unit((HklParameter *)engine_r->pseudoAxes[j]);
480 adapter->_write.data[j] = hkl_parameter_get_value_unit((HklParameter *)engine_w->pseudoAxes[j]);
483 adapter->update();
487 void TangoHKLAdapter::update_state_and_status(void)
489 Tango::DevState state;
490 std::string status;
491 std::string extra_status;
493 state = Tango::STANDBY;
494 if (!_auto_update_from_proxies)
495 status = "AutoUpdateFromProxies OFF";
496 else {
497 status = "AutoUpdateFromProxies ON";
499 if (!this->ready) {
500 state = Tango::FAULT;
501 extra_status += "\nCan not connect to axes proxies";
502 // update the monochromator proxy status.
503 if (!_lambdaAttributeProxy && _auto_update_from_proxies) {
504 extra_status += "\nCan not connect to the lambdaAttributeProxy";
505 extra_status += "\nCheck also the lambdaAttributeProxy property";
507 } else {
508 try {
509 for(unsigned int i=0; i<_axes.size(); ++i) {
510 AxisAdapter const & axis = _axes[i];
511 std::string proxy_name = axis.get_proxy_name();
512 Tango::DevState tmpState = axis.get_state();
514 ::compose_state(state, tmpState);
515 if (tmpState != Tango::STANDBY)
516 extra_status += "\n" + proxy_name + " is in " + Tango::DevStateName[tmpState];
518 } catch(...)
520 state = Tango::FAULT;
521 extra_status += "\nCan not connect to axes proxies";
527 if (_diffractometer){
528 status += "\nSample: ";
529 if(!_diffractometer->samples->current){
530 status += "Not yet Set";
531 state = Tango::FAULT;
532 } else
533 status += _diffractometer->samples->current->name;
534 if (state == Tango::STANDBY)
535 extra_status += "\nready to compute hkl";
536 }else{
537 state = Tango::FAULT;
538 extra_status += "\nhkl core not yet initialized !!!";
540 status += "\nDiffractometer status: ";
541 status += Tango::DevStateName[state];
542 status += extra_status;
544 _diffractometerConfig.state = state;
545 _diffractometerConfig.status = status;
548 void TangoHKLAdapter::update(void)
550 /**********************************************
551 * CRITICAL SECTION
552 **********************************************/
553 omni_mutex_lock lock(_lock);
555 this->update_lambda();
556 this->update_axis_adapters();
557 this->update_hkl_from_axis_adapters();
558 this->update_pseudo_axis_adapters_from_hkl();
559 this->update_pseudo_axes_adapters_from_hkl();
560 this->update_state_and_status();
561 /**********************************************
562 * END OF CRITICAL SECTION
563 **********************************************/
566 /********************/
567 /* State and status */
568 /********************/
569 void TangoHKLAdapter::get_diffractometer_config(DiffractometerConfig & config)
571 omni_mutex_lock lock(_lock);
573 config = _diffractometerConfig;
576 /************/
577 /* hkl part */
578 /************/
580 short & TangoHKLAdapter::get_angles_idx(void)
582 omni_mutex_lock lock(_lock);
584 return _angles_idx;
587 void TangoHKLAdapter::set_angles_idx(short idx)
589 omni_mutex_lock lock(_lock);
591 // A REVOIR
592 if(idx >= 0 && idx < (int)_angles.ydim){
593 size_t i;
594 double *values;
596 _angles_idx = idx;
597 values = &_angles.data[1 + idx * _angles.xdim];
598 for(i=0; i<_axes.size(); ++i)
599 this->write_axis_i(_axes[i], values[i]);
603 void TangoHKLAdapter::load(void)
605 this->load_1();
608 void TangoHKLAdapter::load_1(void)
610 unsigned long nb_properties;
612 // Get the Crystal Attributes properties.
613 Tango::DbData properties;
614 properties.push_back(Tango::DbDatum("Crystal"));
615 _device->get_db_device()->get_attribute_property(properties);
617 // the first one is the number of properties
618 properties[0] >> nb_properties;
620 if (nb_properties > 1) {
621 unsigned long i, j;
622 HklGeometry *geometry;
623 HklDetector *detector;
625 geometry = hkl_geometry_new_copy(_diffractometer->geometry_r);
626 detector = hkl_detector_new_copy(_diffractometer->detector);
628 hkl_sample_list_clear(_diffractometer->samples);
629 for(i=1; i<=nb_properties; ++i) {
630 // skip the _ver property
631 if(!strcasecmp("_ver", properties[i].name.c_str()))
632 continue;
634 HklSample * sample;
636 // The name of the property name is the name of a crystal.
637 sample = hkl_sample_new(properties[i].name.c_str(), HKL_SAMPLE_MONOCRYSTAL);
639 // Extract the lines store in the property
640 std::vector<std::string> lines;
641 properties[i] >> lines;
643 for(j=0; j<lines.size(); j++) {
644 char *line = strdup(lines[j].c_str());
645 char *last;
646 char *key = strtok_r(line, "=", &last);
648 if (!strcmp(key,"lattice")) {
649 double a = atof(strtok_r(NULL, ";", &last));
650 double b = atof(strtok_r(NULL, ";", &last));
651 double c = atof(strtok_r(NULL, ";", &last));
652 double alpha = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
653 double beta = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
654 double gamma = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
655 hkl_sample_set_lattice(sample, a, b, c, alpha, beta, gamma);
657 sample->lattice->a->fit = atoi(strtok_r(NULL, ";", &last));
658 sample->lattice->b->fit = atoi(strtok_r(NULL, ";", &last));
659 sample->lattice->c->fit = atoi(strtok_r(NULL, ";", &last));
660 sample->lattice->alpha->fit = atoi(strtok_r(NULL, ";", &last));
661 sample->lattice->beta->fit = atoi(strtok_r(NULL, ";", &last));
662 sample->lattice->gamma->fit = atoi(strtok_r(NULL, ";", &last));
663 } else if (!strcmp(key, "uxuyuz")){
664 double ux = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
665 double uy = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
666 double uz = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
667 hkl_sample_set_U_from_euler(sample, ux, uy, uz);
668 } else if (!strcmp(key,"reflection")) {
669 unsigned int idx = 0;
670 HklSampleReflection *reflection;
672 double wavelength = atof(strtok_r(NULL, ";", &last));
673 double h = atof(strtok_r(NULL, ";", &last));
674 double k = atof(strtok_r(NULL, ";", &last));
675 double l = atof(strtok_r(NULL, ";", &last));
676 int flag = atoi(strtok_r(NULL, ";", &last));
678 // first set the geometry axes
679 while(key = strtok_r(NULL, ";", &last))
680 hkl_axis_set_value_unit(&geometry->axes[idx++], atof(key));
681 geometry->source.wave_length = wavelength;
683 reflection = hkl_sample_add_reflection(sample, geometry, detector, h, k, l);
684 reflection->flag = flag;
686 free(line);
687 // End of key research
688 }// End for each parameters
689 hkl_sample_list_append(_diffractometer->samples, sample);
690 }// End for each property
692 hkl_detector_free(detector);
693 hkl_geometry_free(geometry);
695 //_device->refresh_crystal_parameters();
699 void TangoHKLAdapter::save(void)
701 omni_mutex_lock lock(_lock);
703 size_t i, j, k;
704 size_t len;
705 Tango::DbData crystal_prop;
706 Tango::DbData data_put;
708 // Step 1 : clean all properties
709 // FP Le mieux serait sans doute de ne pas effacer les propriétés d'attribut
710 // avant d'avoir crée correctement un data_put.
711 crystal_prop.push_back(Tango::DbDatum("Crystal"));
712 _device->get_db_device()->get_attribute_property(crystal_prop);
713 long number_of_prop = 0;
714 crystal_prop[0] >> number_of_prop ;
715 if( number_of_prop > 0)
716 _device->get_db_device()->delete_attribute_property(crystal_prop);
718 // Step 2 : create the Crystal properties
719 Tango::DbDatum properties("Crystal");
720 // Put number of properties (= nb of samples + 1)
721 len = hkl_sample_list_len(_diffractometer->samples);
722 properties << (long)(len + 1);
723 data_put.push_back(properties);
725 // first property is the format version
726 Tango::DbDatum version("_ver");
727 version << (long)FORMAT_VERSION;
728 data_put.push_back(version);
730 // now each sample
731 for(k=0; k<len; ++k){
732 HklSample *sample;
733 std::vector<std::string> lines;
734 char line[256];
736 // the lattices values
737 sample = hkl_sample_list_get_ith(_diffractometer->samples, k);
738 double a = hkl_parameter_get_value_unit(sample->lattice->a);
739 double b = hkl_parameter_get_value_unit(sample->lattice->b);
740 double c = hkl_parameter_get_value_unit(sample->lattice->c);
741 double alpha = hkl_parameter_get_value_unit(sample->lattice->alpha);
742 double beta = hkl_parameter_get_value_unit(sample->lattice->beta);
743 double gamma = hkl_parameter_get_value_unit(sample->lattice->gamma);
744 // the fit flag
745 int a_fit = sample->lattice->a->fit;
746 int b_fit = sample->lattice->b->fit;
747 int c_fit = sample->lattice->c->fit;
748 int alpha_fit = sample->lattice->alpha->fit;
749 int beta_fit = sample->lattice->beta->fit;
750 int gamma_fit = sample->lattice->gamma->fit;
752 snprintf(line, 255, "lattice=%f;%f;%f;%f;%f;%f;%d;%d;%d;%d;%d;%d",
753 a, b, c, alpha, beta, gamma,
754 a_fit, b_fit, c_fit, alpha_fit, beta_fit, gamma_fit);
755 lines.push_back(line);
757 // the UxUyUz parameters
758 double ux, uy, uz;
759 hkl_matrix_to_euler(&sample->U, &ux, &uy, &uz);
760 ux *= HKL_RADTODEG;
761 uy *= HKL_RADTODEG;
762 uz *= HKL_RADTODEG;
764 snprintf(line, 255, "uxuyuz=%f;%f;%f", ux, uy, uz);
765 lines.push_back(line);
767 // the reflections
768 for(i=0; i<HKL_LIST_LEN(sample->reflections); ++i) {
769 HklSampleReflection *reflection;
771 reflection = hkl_sample_get_ith_reflection(sample, i);
772 double wavelength = reflection->geometry->source.wave_length;
773 double h = reflection->hkl.data[0];
774 double k = reflection->hkl.data[1];
775 double l = reflection->hkl.data[2];
776 int flag = reflection->flag;
778 snprintf(line, 255, "reflection=%f;%f;%f;%f;%d",
779 wavelength, h, k, l, flag);
780 // Extract values of each axes
781 for(j=0; j<HKL_LIST_LEN(reflection->geometry->axes); ++j) {
782 char pos[256];
783 double rad = hkl_axis_get_value_unit(&reflection->geometry->axes[j]);
784 snprintf(pos, 255, ";%f", rad);
785 strncat(line, pos, 255);
787 lines.push_back(line);
790 // Try to create property
791 // Get crystal name
792 Tango::DbDatum property(sample->name);
793 property << lines;
794 data_put.push_back(property);
797 //update database for this property
798 _device->get_db_device()->put_attribute_property(data_put);
801 /***************/
802 /* sample part */
803 /***************/
805 char const *TangoHKLAdapter::get_sample_name(void)
807 omni_mutex_lock lock(_lock);
809 HklSample *sample = _diffractometer->samples->current;
810 if(sample)
811 return sample->name;
812 else
813 return "";
816 void TangoHKLAdapter::set_current_sample(char const * name)
818 omni_mutex_lock lock(_lock);
820 HklSample *last;
822 last = _diffractometer->samples->current;
823 if (HKL_SUCCESS == hkl_sample_list_select_current(_diffractometer->samples, name))
824 if (last != _diffractometer->samples->current){
825 this->update_pseudo_axis_engines();
826 this->update_ub();
827 this->update_ux_uy_uz();
828 this->update_reflections_angles();
829 this->update_reflections();
830 this->update_state_and_status();
834 void TangoHKLAdapter::get_sample_lattices(double *a, double *b, double *c,
835 double *alpha, double *beta, double *gamma,
836 double *a_star, double *b_star, double *c_star,
837 double *alpha_star, double *beta_star, double *gamma_star)
839 omni_mutex_lock lock(_lock);
841 HklSample * sample = _diffractometer->samples->current;
842 if (!sample)
843 return;
845 HklLattice const *lattice = sample->lattice;
846 HklLattice *reciprocal = hkl_lattice_new_copy(lattice);
848 hkl_lattice_reciprocal(lattice, reciprocal);
850 // direct space
851 *a = hkl_parameter_get_value_unit(lattice->a);
852 *b = hkl_parameter_get_value_unit(lattice->b);
853 *c = hkl_parameter_get_value_unit(lattice->c);
854 *alpha = hkl_parameter_get_value_unit(lattice->alpha);
855 *beta = hkl_parameter_get_value_unit(lattice->beta);
856 *gamma = hkl_parameter_get_value_unit(lattice->gamma);
858 // reciprocal space
859 *a_star = hkl_parameter_get_value_unit(reciprocal->a);
860 *b_star = hkl_parameter_get_value_unit(reciprocal->b);
861 *c_star = hkl_parameter_get_value_unit(reciprocal->c);
862 *alpha_star = hkl_parameter_get_value_unit(reciprocal->alpha);
863 *beta_star = hkl_parameter_get_value_unit(reciprocal->beta);
864 *gamma_star = hkl_parameter_get_value_unit(reciprocal->gamma);
866 hkl_lattice_free(reciprocal);
869 void TangoHKLAdapter::get_sample_fit(bool *afit, bool *bfit, bool *cfit,
870 bool *alphafit, bool *betafit, bool *gammafit,
871 bool *uxfit, bool *uyfit, bool *uzfit)
873 omni_mutex_lock lock(_lock);
875 HklSample * sample = _diffractometer->samples->current;
876 if (!sample)
877 return;
879 HklLattice const *lattice = sample->lattice;
881 *afit = lattice->a->fit;
882 *bfit = lattice->b->fit;
883 *cfit = lattice->c->fit;
884 *alphafit = lattice->alpha->fit;
885 *betafit = lattice->beta->fit;
886 *gammafit = lattice->gamma->fit;
887 *uxfit = _uxfit;
888 *uyfit = _uyfit;
889 *uzfit = _uzfit;
893 void TangoHKLAdapter::set_sample_Ux(double ux)
895 HklSample *sample;
897 sample = _diffractometer->samples->current;
898 if (sample){
899 if (HKL_SUCCESS == hkl_sample_set_U_from_euler(sample,
900 ux * HKL_DEGTORAD,
901 _uy * HKL_DEGTORAD,
902 _uz * HKL_DEGTORAD)){
903 _ux = ux;
904 this->update_ub();
905 }else
906 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this Ux value",
907 "Set a correct value");
911 void TangoHKLAdapter::set_sample_Uy(double uy)
913 HklSample *sample;
915 sample = _diffractometer->samples->current;
916 if (sample){
917 if (HKL_SUCCESS == hkl_sample_set_U_from_euler(sample,
918 _ux * HKL_DEGTORAD,
919 uy * HKL_DEGTORAD,
920 _uz * HKL_DEGTORAD)){
921 _uy = uy;
922 this->update_ub();
923 }else
924 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this Uy value",
925 "Set a correct value");
929 void TangoHKLAdapter::set_sample_Uz(double uz)
931 HklSample *sample;
933 sample = _diffractometer->samples->current;
934 if (sample){
935 if (HKL_SUCCESS == hkl_sample_set_U_from_euler(sample,
936 _ux * HKL_DEGTORAD,
937 _uy * HKL_DEGTORAD,
938 uz * HKL_DEGTORAD)){
939 _uz = uz;
940 this->update_ub();
941 }else
942 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this Uz value",
943 "Set a correct value");
947 void TangoHKLAdapter::set_sample_AFit(bool fit)
949 HklSample *sample;
951 sample = _diffractometer->samples->current;
952 if (sample)
953 sample->lattice->a->fit = fit;
956 void TangoHKLAdapter::set_sample_BFit(bool fit)
958 HklSample *sample;
960 sample = _diffractometer->samples->current;
961 if (sample)
962 sample->lattice->b->fit = fit;
965 void TangoHKLAdapter::set_sample_CFit(bool fit)
967 HklSample *sample;
969 sample = _diffractometer->samples->current;
970 if (sample)
971 sample->lattice->c->fit = fit;
974 void TangoHKLAdapter::set_sample_AlphaFit(bool fit)
976 HklSample *sample;
978 sample = _diffractometer->samples->current;
979 if (sample)
980 sample->lattice->alpha->fit = fit;
983 void TangoHKLAdapter::set_sample_BetaFit(bool fit)
985 HklSample *sample;
987 sample = _diffractometer->samples->current;
988 if (sample)
989 sample->lattice->beta->fit = fit;
992 void TangoHKLAdapter::set_sample_GammaFit(bool fit)
994 HklSample *sample;
996 sample = _diffractometer->samples->current;
997 if (sample)
998 sample->lattice->gamma->fit = fit;
1001 void TangoHKLAdapter::set_sample_UxFit(bool fit)
1003 HklSample *sample;
1005 sample = _diffractometer->samples->current;
1006 if (sample)
1007 _uxfit = _uyfit = _uzfit = fit;
1010 void TangoHKLAdapter::set_sample_UyFit(bool fit)
1012 HklSample *sample;
1014 sample = _diffractometer->samples->current;
1015 if (sample)
1016 _uxfit = _uyfit = _uzfit = fit;
1019 void TangoHKLAdapter::set_sample_UzFit(bool fit)
1021 HklSample *sample;
1023 sample = _diffractometer->samples->current;
1024 if (sample)
1025 _uxfit = _uyfit = _uzfit = fit;
1028 void TangoHKLAdapter::add_new_sample(std::string const & name)
1030 omni_mutex_lock lock(_lock);
1032 HklSample *sample = hkl_sample_new(name.c_str(), HKL_SAMPLE_MONOCRYSTAL);
1034 if (!hkl_sample_list_append(_diffractometer->samples, sample)){
1035 hkl_sample_free(sample);
1036 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not add a sample with this name",
1037 "A sample with the same name is already present in the sample list");
1041 void TangoHKLAdapter::copy_sample_as(Tango::DevString copy_name)
1043 omni_mutex_lock lock(_lock);
1045 HklSample *sample;
1046 HklSample const *current;
1048 current = _diffractometer->samples->current;
1049 if(!current)
1050 TANGO_EXCEPTION_THROW_WITHOUT_LOG("No current sample set",
1051 "Please set a current sample");
1053 sample = hkl_sample_list_get_by_name(_diffractometer->samples, copy_name);
1054 if (sample)
1055 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not add a sample with this name",
1056 "A sample with the same name is already present in the sample list");
1058 sample = hkl_sample_new_copy(current);
1059 if(sample){
1060 hkl_sample_set_name(sample, copy_name);
1061 hkl_sample_list_append(_diffractometer->samples, sample);
1065 void TangoHKLAdapter::del_sample(void)
1067 omni_mutex_lock lock(_lock);
1069 HklSampleList *samples = _diffractometer->samples;
1070 hkl_sample_list_del(samples, samples->current);
1072 // add a default sample if no more sample in the list
1073 if(hkl_sample_list_len(samples) == 0){
1074 HklSample *sample = hkl_sample_new("default", HKL_SAMPLE_MONOCRYSTAL);
1075 samples->current = hkl_sample_list_append(samples, sample);
1076 }else
1077 samples->current = hkl_sample_list_get_ith(samples, 0);
1078 this->update_ub();
1079 this->update_ux_uy_uz();
1080 this->update_reflections_angles();
1081 this->update_reflections();
1084 void TangoHKLAdapter::set_lattice(const Tango::DevVarDoubleArray *argin)
1086 omni_mutex_lock lock(_lock);
1088 if (argin && argin->length() != 6)
1089 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1090 "Did not receive the exact amount of crystal parameters: A, B, C, alpha, beta, gamma");
1092 HklSample *sample = _diffractometer->samples->current;
1093 if (HKL_FAIL == hkl_sample_set_lattice(sample,
1094 (*argin)[0],(*argin)[1], (*argin)[2],
1095 (*argin)[3] * HKL_DEGTORAD,
1096 (*argin)[4] * HKL_DEGTORAD,
1097 (*argin)[5] * HKL_DEGTORAD))
1099 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this lattice combination.",
1100 "Please set a good combination");
1101 this->update_ub();
1102 this->update_reflections_angles();
1105 void TangoHKLAdapter::add_reflection(const Tango::DevVarDoubleArray *argin)
1107 omni_mutex_lock lock(_lock);
1109 HklSample *sample = _diffractometer->samples->current;
1111 if(sample){
1112 double h, k, l;
1113 HklSampleReflection *ref;
1115 if(argin && argin->length() == 3){
1116 h = (*argin)[0];
1117 k = (*argin)[1];
1118 l = (*argin)[2];
1119 }else{
1120 HklPseudoAxisEngine *engine;
1122 engine = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_r, "hkl");
1124 h = hkl_parameter_get_value_unit((HklParameter *)engine->pseudoAxes[0]);
1125 k = hkl_parameter_get_value_unit((HklParameter *)engine->pseudoAxes[1]);
1126 l = hkl_parameter_get_value_unit((HklParameter *)engine->pseudoAxes[2]);
1129 ref = hkl_sample_add_reflection(sample,
1130 _diffractometer->geometry_r,
1131 _diffractometer->detector,
1132 h, k, l);
1133 if(ref){
1134 this->update_reflections_angles();
1135 this->update_reflections();
1140 void TangoHKLAdapter::del_reflection(Tango::DevShort argin)
1142 omni_mutex_lock lock(_lock);
1144 if (HKL_FAIL == hkl_sample_del_reflection(_diffractometer->samples->current, argin))
1145 TANGO_EXCEPTION_THROW_WITHOUT_LOG("index out of range",
1146 "change the reflection index");
1147 this->update_reflections_angles();
1148 this->update_reflections();
1151 void TangoHKLAdapter::set_reflections(Matrix<double> const & img)
1153 omni_mutex_lock lock(_lock);
1155 HklSample *sample = _diffractometer->samples->current;
1156 if (sample
1157 && img.xdim == _reflections.xdim
1158 && img.ydim == _reflections.ydim) {
1160 size_t i = 0;
1161 size_t j = 0;
1162 for(i=0; i<HKL_LIST_LEN(sample->reflections); ++i) {
1163 HklSampleReflection *r;
1165 r = hkl_sample_get_ith_reflection(sample, i);
1166 if (r) {
1167 hkl_sample_reflection_set_hkl(r, img.data[j+1], img.data[j+2], img.data[j+3]);
1168 hkl_sample_reflection_set_flag(r, (int)img.data[j+5]);
1169 if(!_device->protectReflectionAxes){
1170 HklAxis *axes;
1171 size_t len;
1172 size_t k;
1174 len = HKL_LIST_LEN(r->geometry->axes);
1175 axes = &r->geometry->axes[0];
1177 for(k=6; k<6+len; ++k)
1178 hkl_axis_set_value_unit(axes++, img.data[j+k]);
1180 hkl_geometry_update(r->geometry);
1181 hkl_sample_reflection_set_geometry(r, r->geometry);
1184 j += _reflections.xdim;
1186 this->update_reflections();
1187 this->update_reflections_angles();
1191 double TangoHKLAdapter::affine_sample(std::string name)
1193 omni_mutex_lock lock(_lock);
1195 HklSample *sample;
1196 double res = 0.;
1198 sample = hkl_sample_list_get_by_name(_diffractometer->samples, name.c_str());
1199 if(sample){
1200 HklSample *tmp;
1202 // check if the affine sample is already in the HklSampleList
1203 std::string name = sample->name;
1204 name += "(affine)";
1205 tmp = hkl_sample_list_get_by_name(_diffractometer->samples, name.c_str());
1206 hkl_sample_list_del(_diffractometer->samples, tmp);
1208 tmp = hkl_sample_new_copy(sample);
1209 hkl_sample_set_name(tmp, name.c_str());
1210 res = hkl_sample_affine(tmp);
1212 hkl_sample_list_append(_diffractometer->samples, tmp);
1213 _diffractometer->samples->current = tmp;
1215 this->update_ub();
1216 this->update_ux_uy_uz();
1217 this->update_reflections_angles();
1220 return res;
1224 std::vector<std::string> TangoHKLAdapter::get_samples_names(void)
1226 omni_mutex_lock lock(_lock);
1228 std::vector<std::string> names;
1229 size_t i, len;
1230 HklSampleList *samples = _diffractometer->samples;
1232 len = hkl_sample_list_len(samples);
1233 for(i=0; i<len; ++i)
1234 names.push_back(hkl_sample_list_get_ith(samples, i)->name);
1236 return names;
1239 // DEPRECATED
1240 void TangoHKLAdapter::get_sample_parameter_values(Tango::DevVarDoubleStringArray *argout)
1242 omni_mutex_lock lock(_lock);
1244 HklSample *sample;
1245 HklParameter *parameter = NULL;
1246 std::string name;
1248 //check parameters
1249 if (argout->svalue.length() != 1)
1250 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1251 "only one string = parameter name");
1253 sample = _diffractometer->samples->current;
1254 if(sample){
1255 //parameters OK
1256 name = argout->svalue[0];
1257 if(name == "a")
1258 parameter = sample->lattice->a;
1259 else if(name == "b")
1260 parameter = sample->lattice->b;
1261 else if(name == "c")
1262 parameter = sample->lattice->c;
1263 else if(name == "alpha")
1264 parameter = sample->lattice->alpha;
1265 else if(name == "beta")
1266 parameter = sample->lattice->beta;
1267 else if(name == "gamma")
1268 parameter = sample->lattice->gamma;
1270 if (parameter){
1271 argout->dvalue[0] = parameter->range.min;
1272 argout->dvalue[1] = parameter->range.max;
1273 argout->dvalue[2] = parameter->fit;
1274 }else
1275 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Wrong parameter name",
1276 "Select: a, b, c, alpha, beta, gamma");
1280 //DEPRECATED
1281 void TangoHKLAdapter::set_sample_parameter_values(Tango::DevVarDoubleStringArray const *argin)
1283 omni_mutex_lock lock(_lock);
1285 HklSample *sample;
1286 HklParameter *parameter = NULL;
1287 std::string name;
1289 // check parameters
1290 if(argin->dvalue.length() != 3)
1291 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1292 "set_crystal_parameter_values did not receive the right amount of scalar parameters: min, max, flag");
1293 if((argin->svalue.length() ) != 1)
1294 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1295 "set_crystal_parameter_values did not receive the right amount of string parameters: parameter name");
1297 // parameters OK
1298 sample = _diffractometer->samples->current;
1299 if(!sample)
1300 TANGO_EXCEPTION_THROW_WITHOUT_LOG("No current sample set",
1301 "Please set a current sample");
1303 name = argin->svalue[0];
1304 if(name == "a")
1305 parameter = sample->lattice->a;
1306 else if(name == "b")
1307 parameter = sample->lattice->b;
1308 else if(name == "c")
1309 parameter = sample->lattice->c;
1310 else if(name == "alpha")
1311 parameter = sample->lattice->alpha;
1312 else if(name == "beta")
1313 parameter = sample->lattice->beta;
1314 else if(name == "gamma")
1315 parameter = sample->lattice->gamma;
1317 if (parameter){
1318 parameter->range.min = argin->dvalue[0];
1319 parameter->range.max = argin->dvalue[1];
1320 parameter->fit = argin->dvalue[2] != 0.;
1321 }else
1322 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Wrong parameter name",
1323 "Select: a, b, c, alpha, beta, gamma");
1324 this->update_ub();
1325 this->update_ux_uy_uz();
1326 this->update_reflections_angles();
1329 void TangoHKLAdapter::compute_u(const Tango::DevVarLongArray *argin)
1331 omni_mutex_lock lock(_lock);
1333 HklSample *sample;
1335 // is parameter ok ?
1336 if (argin->length() != 2)
1337 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Need exactly two reflections indexes",
1338 "use the right number of parameters");
1340 sample = _diffractometer->samples->current;
1341 if (!sample)
1342 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not compute the U matrix without current sample set.",
1343 "Set a current sample");
1345 if (hkl_sample_compute_UB_busing_levy(sample, (*argin)[0], (*argin)[1]))
1346 TANGO_EXCEPTION_THROW_WITHOUT_LOG("can not compute the UB matrix using thoses reflections index",
1347 "Use other reflections");
1348 this->update_ub();
1349 this->update_ux_uy_uz();
1352 /*************/
1353 /* Axis part */
1354 /*************/
1356 void TangoHKLAdapter::read_axis(int idx, double & read, double & write)
1358 omni_mutex_lock lock(_lock);
1360 AxisAdapter & axis = _axes[idx];
1361 read = axis.get_read();
1362 write = axis.get_write();
1365 void TangoHKLAdapter::stop_all_axis(void)
1367 #ifdef WRITE_TO_PROXY_ALLOWED
1368 size_t i;
1369 for(i=0; i<_axes.size(); ++i)
1370 _axes[i].stop();
1371 #endif
1374 void TangoHKLAdapter::write_axis(AxisAdapter & axis, double value)
1376 omni_mutex_lock lock(_lock);
1378 this->write_axis_i(axis, value);
1381 void TangoHKLAdapter::write_axis_i(AxisAdapter & axis, double value)
1383 axis._read = axis._write = value;
1384 hkl_axis_set_value_unit(axis._axis_r, value);
1385 hkl_axis_set_value_unit(axis._axis_w, value);
1388 /*******************/
1389 /* pseudoAxis part */
1390 /*******************/
1392 std::vector<std::string> TangoHKLAdapter::pseudo_axis_get_names(void)
1394 omni_mutex_lock lock(_lock);
1396 std::vector<std::string> names;
1397 size_t i, j;
1399 for(i=0; i<HKL_LIST_LEN(_diffractometer->engines_r_real->engines); ++i){
1400 HklPseudoAxisEngine *engine;
1402 engine = _diffractometer->engines_r_real->engines[i];
1403 for(j=0; j<HKL_LIST_LEN(engine->pseudoAxes); ++j)
1404 names.push_back(((HklParameter *)(&engine->pseudoAxes[j]))->name);
1407 return names;
1410 PseudoAxisAdapter *TangoHKLAdapter::pseudo_axis_buffer_new(char const *name)
1412 omni_mutex_lock lock(_lock);
1414 PseudoAxisAdapter * buffer = NULL;
1415 HklPseudoAxis *pseudo_r;
1416 HklPseudoAxis *pseudo_w;
1418 pseudo_r = hkl_pseudo_axis_engine_list_get_pseudo_axis_by_name(
1419 _diffractometer->engines_r_real, name);
1420 pseudo_w = hkl_pseudo_axis_engine_list_get_pseudo_axis_by_name(
1421 _diffractometer->engines_w_real, name);
1423 if(pseudo_r && pseudo_w) {
1426 buffer = new PseudoAxisAdapter(*this, pseudo_r, pseudo_w);
1427 _pseudoAxisAdapters.push_back(buffer);
1429 catch (Tango::DevFailed)
1431 delete buffer;
1432 buffer = NULL;
1435 return buffer;
1438 void TangoHKLAdapter::pseudo_axis_set_initialized(PseudoAxisAdapter *buffer,
1439 Tango::DevBoolean initialized)
1441 if(initialized){
1442 this->update();
1444 omni_mutex_lock lock(_lock);
1446 hkl_pseudo_axis_engine_initialize(buffer->_pseudo_r->engine);
1447 hkl_pseudo_axis_engine_initialize(buffer->_pseudo_w->engine);
1451 void TangoHKLAdapter::pseudo_axis_set_position(PseudoAxisAdapter *buffer,
1452 const Tango::DevDouble & position)
1454 omni_mutex_lock lock(_lock);
1456 double value = position - buffer->_config.offset;
1457 int res = HKL_FAIL;
1459 HklPseudoAxisEngineList *engines_w_real = _diffractometer->engines_w_real;
1460 HklPseudoAxisEngine *engine = buffer->_pseudo_w->engine;
1461 HklGeometry *geometry_w_real = _diffractometer->geometry_w_real;
1463 hkl_parameter_set_value_unit((HklParameter *)buffer->_pseudo_w, value);
1464 res = hkl_pseudo_axis_engine_set(buffer->_pseudo_w->engine);
1465 if (HKL_SUCCESS == res){
1466 hkl_geometry_init_geometry(geometry_w_real, engine->engines->geometries->geometries[0]);
1467 hkl_pseudo_axis_engine_list_get(engines_w_real);
1469 _angles_idx = 0;
1470 this->update_angles();
1471 buffer->to_proxies();
1472 this->update_axis_adapters();
1473 this->update_pseudo_axis_adapters_from_hkl();
1474 this->update_pseudo_axes_adapters_from_hkl();
1475 }else
1476 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not write on this pseudo axis",
1477 "Check the sample");
1481 PseudoAxisConfig TangoHKLAdapter::pseudo_axis_get_config(PseudoAxisAdapter *buffer)
1483 this->update();
1485 omni_mutex_lock lock(_lock);
1487 return buffer->_config;
1490 void TangoHKLAdapter::pseudo_axis_set_mode(PseudoAxisAdapter *buffer, Tango::DevString const & mode)
1492 omni_mutex_lock lock(_lock);
1494 size_t i, len;
1496 len = HKL_LIST_LEN(buffer->_pseudo_r->engine->modes);
1497 for(i=0; i<len; ++i)
1498 if(!strcasecmp(mode, buffer->_pseudo_r->engine->modes[i]->name))
1499 break;
1500 if(i<len){
1501 hkl_pseudo_axis_engine_select_mode(buffer->_pseudo_r->engine, i);
1502 hkl_pseudo_axis_engine_select_mode(buffer->_pseudo_w->engine, i);
1506 void TangoHKLAdapter::pseudo_axis_get_mode_parameters(PseudoAxisAdapter *buffer, Tango::DevVarDoubleStringArray *argout)
1508 omni_mutex_lock lock(_lock);
1510 HklPseudoAxisEngine *engine = buffer->_pseudo_r->engine;
1511 if (engine && engine->mode){
1512 size_t i;
1513 size_t len = HKL_LIST_LEN(engine->mode->parameters);
1515 argout->svalue.length(len);
1516 argout->dvalue.length(len);
1517 for(i=0; i<len; ++i){
1518 argout->svalue[i] = CORBA::string_dup(engine->mode->parameters[i].name);
1519 argout->dvalue[i] = hkl_parameter_get_value_unit(&engine->mode->parameters[i]);
1521 }else
1522 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not get the current Mode parameters values without a current mode set.",
1523 "");
1526 void TangoHKLAdapter::pseudo_axis_set_mode_parameters(PseudoAxisAdapter *buffer, const Tango::DevVarDoubleStringArray *argin)
1528 omni_mutex_lock lock(_lock);
1530 if(argin->svalue.length() != argin->dvalue.length())
1531 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1532 "set_mode_parameters_values did not receive the same amount between string and double values");
1534 HklPseudoAxisEngine *engine_r = buffer->_pseudo_r->engine;
1535 HklPseudoAxisEngine *engine_w = buffer->_pseudo_w->engine;
1536 if (engine_r && engine_w){
1537 size_t i;
1538 size_t len;
1540 len = argin->svalue.length();
1541 if (HKL_LIST_LEN(engine_r->mode->parameters) != len)
1542 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Not the right number of parameter",
1543 "gives the right number of parameters");
1545 for(i=0; i<len; ++i){
1546 double value = argin->dvalue[i];
1547 char const *name = argin->svalue[i];
1548 if(!strcmp(name, engine_r->mode->parameters[i].name)){
1549 hkl_parameter_set_value_unit(&engine_r->mode->parameters[i], value);
1550 hkl_parameter_set_value_unit(&engine_w->mode->parameters[i], value);
1553 }else
1554 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set the current Mode parameters values without a current mode set.",
1555 "");
1558 void TangoHKLAdapter::pseudo_axis_on(PseudoAxisAdapter *buffer)
1560 omni_mutex_lock lock(_lock);
1562 for(size_t i=0; i<buffer->_axes.size(); ++i)
1563 buffer->_axes[i]->on();
1566 /*******************/
1567 /* pseudoAxes part */
1568 /*******************/
1570 PseudoAxesAdapter *TangoHKLAdapter::pseudo_axes_adapter_get_by_name(std::string const & name)
1572 //omni_mutex_lock lock(_lock);
1574 unsigned int i;
1575 PseudoAxesAdapter *adapter = NULL;
1577 for(i=0; i<_pseudoAxesAdapters.size(); ++i)
1578 if(_pseudoAxesAdapters[i]->get_name() == name){
1579 adapter = _pseudoAxesAdapters[i];
1580 break;
1582 return adapter;
1585 PseudoAxesConfig TangoHKLAdapter::pseudo_axes_get_config(size_t idx)
1587 this->update();
1589 omni_mutex_lock lock(_lock);
1591 return _pseudoAxesAdapters[idx]->_config;
1595 void TangoHKLAdapter::pseudo_axes_write(size_t idx, Matrix<double> const & write) throw (Tango::DevFailed)
1597 omni_mutex_lock lock(_lock);
1599 size_t i, len;
1600 int res = HKL_FAIL;
1601 HklPseudoAxisEngineList *engines_r, *engines_w;
1602 HklGeometry *geometry_r, *geometry_w;
1604 engines_r = _diffractometer->engines_r;
1605 engines_w = _diffractometer->engines_w;
1606 len = HKL_LIST_LEN(engines_w->engines[idx]->pseudoAxes);
1608 geometry_r = _diffractometer->geometry_r;
1609 geometry_w = _diffractometer->geometry_w;
1611 for(i=0; i<len; ++i)
1612 hkl_parameter_set_value_unit((HklParameter *)(engines_w->engines[idx]->pseudoAxes[i]), write.data[i]);
1614 res = hkl_pseudo_axis_engine_set(engines_w->engines[idx]);
1616 if (HKL_SUCCESS == res){
1617 // force auto update OFF when we write on a PseudoAxes.
1618 _auto_update_from_proxies = false;
1620 hkl_geometry_init_geometry(geometry_w, engines_w->geometries->geometries[0]);
1621 hkl_pseudo_axis_engine_list_get(engines_w);
1622 hkl_geometry_init_geometry(geometry_r, engines_w->geometries->geometries[0]);
1623 hkl_pseudo_axis_engine_list_get(engines_r);
1625 _angles_idx = 0;
1626 this->update_angles();
1627 this->update_axis_adapters();
1628 this->update_pseudo_axis_adapters_from_hkl();
1629 this->update_pseudo_axes_adapters_from_hkl();
1630 }else
1631 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not write on this pseudo axis",
1632 "Check the sample");
1636 Tango::DevString *TangoHKLAdapter::pseudo_axes_get_mode(size_t idx)
1638 omni_mutex_lock lock(_lock);
1640 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1641 if(engine->mode)
1642 return const_cast<Tango::DevString *>(&engine->mode->name);
1643 else
1644 return NULL;
1647 void TangoHKLAdapter::pseudo_axes_set_mode(size_t idx, const Tango::DevString name)
1649 omni_mutex_lock lock(_lock);
1651 size_t i;
1652 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1654 // check if we try to set the same mode than the current one
1655 if (engine->mode)
1656 if(!strcasecmp(name, engine->mode->name))
1657 return;
1659 // no so set the mode if possible
1660 size_t len = HKL_LIST_LEN(engine->modes);
1661 for(i=0; i<len; ++i)
1662 if(!strcasecmp(name, engine->modes[i]->name))
1663 break;
1664 if(i<len){
1665 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_r->engines[idx], i);
1666 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_w->engines[idx], i);
1667 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_r_real->engines[idx], i);
1668 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_w_real->engines[idx], i);
1669 _pseudoAxesAdapters[idx]->update_axes_i(engine);
1670 _pseudoAxesAdapters[idx]->update();
1674 Matrix<char *> & TangoHKLAdapter::pseudo_axes_get_mode_parameters_names(size_t idx)
1676 omni_mutex_lock lock(_lock);
1678 size_t i;
1679 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1680 size_t len = HKL_LIST_LEN(engine->mode->parameters);
1681 PseudoAxesAdapter *adapter = _pseudoAxesAdapters[idx];
1682 adapter->_mode_parameters_names.resize(len, 1);
1683 for(i=0; i<len; ++i)
1684 adapter->_mode_parameters_names.data[i] = const_cast<char *>(engine->mode->parameters[i].name);
1685 return adapter->_mode_parameters_names;
1688 Matrix<double> const & TangoHKLAdapter::pseudo_axes_get_mode_parameters(size_t idx)
1690 omni_mutex_lock lock(_lock);
1692 size_t i;
1693 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1694 size_t len = HKL_LIST_LEN(engine->mode->parameters);
1695 PseudoAxesAdapter *adapter = _pseudoAxesAdapters[idx];
1696 adapter->_mode_parameters.resize(len, 1);
1697 for(i=0; i<len; ++i)
1698 adapter->_mode_parameters.data[i] = hkl_parameter_get_value_unit(&engine->mode->parameters[i]);
1699 return adapter->_mode_parameters;
1702 void TangoHKLAdapter::pseudo_axes_set_mode_parameters(size_t idx, Matrix<double> const & values)
1704 omni_mutex_lock lock(_lock);
1706 size_t i;
1707 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1708 size_t len = HKL_LIST_LEN(engine->mode->parameters);
1709 if(len == values.xdim)
1710 for(i=0; i<len; ++i){
1711 double & value = values.data[i];
1713 hkl_parameter_set_value_unit(&_diffractometer->engines_r->engines[idx]->mode->parameters[i],
1714 value);
1715 hkl_parameter_set_value_unit(&_diffractometer->engines_w->engines[idx]->mode->parameters[i],
1716 value);
1717 hkl_parameter_set_value_unit(&_diffractometer->engines_r_real->engines[idx]->mode->parameters[i],
1718 value);
1719 hkl_parameter_set_value_unit(&_diffractometer->engines_w_real->engines[idx]->mode->parameters[i],
1720 value);
1724 void TangoHKLAdapter::pseudo_axes_init(size_t idx)
1726 omni_mutex_lock lock(_lock);
1728 HklPseudoAxisEngine *engine_r = _diffractometer->engines_r->engines[idx];
1729 HklPseudoAxisEngine *engine_w = _diffractometer->engines_w->engines[idx];
1730 HklPseudoAxisEngine *engine_r_real = _diffractometer->engines_r_real->engines[idx];
1731 HklPseudoAxisEngine *engine_w_real = _diffractometer->engines_w_real->engines[idx];
1733 hkl_pseudo_axis_engine_initialize(engine_r);
1734 hkl_pseudo_axis_engine_initialize(engine_w);
1735 hkl_pseudo_axis_engine_initialize(engine_r_real);
1736 hkl_pseudo_axis_engine_initialize(engine_w_real);
1739 void TangoHKLAdapter::pseudo_axes_add_dynamic_attributes(size_t idx)
1741 //omni_mutex_lock lock(_lock);
1743 size_t i, j;
1745 // check if all the PseudoAxes were instantiated
1746 for(i=0; i<_pseudoAxesAdapters.size(); ++i)
1747 if(!_pseudoAxesAdapters[i]->_device)
1748 return;
1751 * we need to attach the dynamic attributes after all instance of
1752 * the PseudoAxes devices were started. otherwise it cause problem.
1753 * only add the attributs if they were not already added.
1755 for(i=0; i<_pseudoAxesAdapters.size(); ++i){
1756 PseudoAxesAdapter *adapter = _pseudoAxesAdapters[i];
1757 Tango::MultiAttribute *multiattribute = adapter->_device->get_device_attr();
1759 for(j=0; j<adapter->_dynamic_attribute_pseudo_axes_axis.size(); ++j){
1760 try{
1761 multiattribute->get_attr_by_name(adapter->get_pseudo_axis_names().data[j]);
1762 }catch (Tango::DevFailed){
1763 adapter->_device->add_attribute(adapter->_dynamic_attribute_pseudo_axes_axis[j]);
1769 void TangoHKLAdapter::pseudo_axes_remove_dynamic_attributes(size_t idx)
1771 size_t i;
1772 PseudoAxesAdapter *adapter;
1774 adapter = _pseudoAxesAdapters[idx];
1775 if(adapter->_device){
1776 for(i=0; i<adapter->_dynamic_attribute_pseudo_axes_axis.size(); ++i)
1777 adapter->_device->remove_attribute(adapter->_dynamic_attribute_pseudo_axes_axis[i], false);
1778 adapter->_device = NULL;
1782 void TangoHKLAdapter::pseudo_axes_create_and_start_devices(void)
1784 omni_mutex_lock lock(_lock);
1786 unsigned int i, j;
1788 Tango::Util *tg = Tango::Util::instance();
1789 Tango::Database *db = tg->get_database();
1790 for(i=0; i<_pseudoAxesAdapters.size(); ++i){
1791 std::string dev_name = _pseudoAxesAdapters[i]->get_proxy_name();
1793 // first check if the device is already defined in the database
1794 try{
1795 Tango::DbDevImportInfo my_device_import_info;
1797 my_device_import_info = db->import_device(dev_name);
1798 } catch (Tango::DevFailed &) {
1799 Tango::DbDevInfo my_device_info;
1801 // add the device to the database
1802 my_device_info.name = dev_name.c_str();
1803 my_device_info._class = "PseudoAxes";
1804 my_device_info.server = tg->get_ds_name().c_str();
1806 db->add_device(my_device_info);
1808 // add the right properties to that device
1809 Tango::DbDatum DiffractometerProxy("DiffractometerProxy"), EngineName("EngineName");
1810 Tango::DbData properties;
1811 DiffractometerProxy << _device->name();
1812 EngineName << _pseudoAxesAdapters[i]->get_name();
1813 properties.push_back(DiffractometerProxy);
1814 properties.push_back(EngineName);
1815 db->put_device_property(dev_name,properties);
1818 // now start the device
1819 const std::vector<Tango::DeviceClass *> *cl_list = tg->get_class_list();
1820 for(j=0; j<cl_list->size(); ++j){
1821 if((*cl_list)[j]->get_name() == "PseudoAxes"){
1822 try{
1823 Tango::DevVarStringArray na;
1824 na.length(1);
1825 na[0] = dev_name.c_str();
1826 (*cl_list)[j]->device_factory(&na);
1827 std::cout << "Started " << dev_name << std::endl;
1828 break;
1830 catch (Tango::DevFailed &e)
1839 Tango::DevBoolean TangoHKLAdapter::pseudo_axes_get_initialized(size_t idx)
1841 omni_mutex_lock lock(_lock);
1843 if(!_diffractometer->engines_r->engines[idx]->mode->initialize)
1844 return true;
1847 void TangoHKLAdapter::pseudo_axes_set_initialized(size_t idx, bool initialized)
1849 if(initialized){
1850 this->update();
1852 omni_mutex_lock lock(_lock);
1854 HklPseudoAxisEngine *engine_r = _diffractometer->engines_r->engines[idx];
1855 HklPseudoAxisEngine *engine_w = _diffractometer->engines_w->engines[idx];
1856 HklPseudoAxisEngine *engine_r_real = _diffractometer->engines_r_real->engines[idx];
1857 HklPseudoAxisEngine *engine_w_real = _diffractometer->engines_w_real->engines[idx];
1859 hkl_pseudo_axis_engine_initialize(engine_r);
1860 hkl_pseudo_axis_engine_initialize(engine_w);
1861 hkl_pseudo_axis_engine_initialize(engine_r_real);
1862 hkl_pseudo_axis_engine_initialize(engine_w_real);
1866 /**********************/
1867 /* Dynamic attributes */
1868 /**********************/
1870 void TangoHKLAdapter::create_axes_dynamic_attributes(void)
1872 size_t i;
1873 size_t len = _axes.size();
1874 _dynamic_attribute_axes_names.resize(len, 1);
1875 for(i=0; i<len; ++i){
1876 std::string name;
1877 AxisAttrib *att;
1878 size_t l;
1880 // compute the diffractometer axis names
1881 name = "Axis";
1882 l = name.size();
1883 name += _axes[i].get_name();
1884 name[l] = toupper(name[l]);
1886 // create the AxisAttrib to deal with the proxy connection.
1887 att = new AxisAttrib(name.c_str(), _axes[i]);
1888 _dynamic_attribute_axes.push_back(att);
1889 _dynamic_attribute_axes_names.data[i] = const_cast<char *>(att->get_name().c_str());
1893 void TangoHKLAdapter::destroy_axes_dynamic_attributes(void)
1895 size_t i;
1896 size_t len = _dynamic_attribute_axes.size();
1898 for(i=0; i<len; ++i)
1899 delete _dynamic_attribute_axes[i];
1902 void TangoHKLAdapter::attach_dynamic_attributes_to_device(void)
1904 size_t i;
1906 for(i=0; i<_dynamic_attribute_axes.size(); ++i)
1907 _device->add_attribute(_dynamic_attribute_axes[i]);
1911 void TangoHKLAdapter::detach_dynamic_attributes_from_device(void)
1913 size_t i;
1915 for(i=0; i<_dynamic_attribute_axes.size(); ++i)
1916 _device->remove_attribute(_dynamic_attribute_axes[i], false);
1920 bool TangoHKLAdapter::get_auto_update_from_proxies(void)
1922 omni_mutex_lock lock(_lock);
1924 return _auto_update_from_proxies;
1927 void TangoHKLAdapter::set_auto_update_from_proxies(bool update)
1929 bool old = _auto_update_from_proxies;
1930 _auto_update_from_proxies = update;
1931 if(old = false && update == true)
1932 this->update();
1935 } // namespace
1937 std::string hkl_axes_consign_as_string(HklAxis const **axes, size_t axes_len)
1939 size_t i;
1940 std::string out;
1942 std::ostringstream line, tmp;
1943 for(i=0; i<axes_len; ++i) {
1944 HklParameter const *axis = (HklParameter const *)axes[i];
1945 double value = hkl_parameter_get_value_unit(axis);
1947 out += " \"";
1948 out += axis->name;
1949 out + "\" ";
1950 std::ostringstream tmp;
1951 tmp << showpos;
1952 tmp << value << "°";
1953 out += tmp.str();
1956 return out;