* remove unneeded group code
[diffractometer.git] / src / TangoHKLAdapter.cpp
blob872c101a86558a160355550778d727d91e13fb7c
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;
111 adapter = new PseudoAxesAdapter(this, i);
112 _pseudoAxesAdapters.push_back(adapter);
113 _pseudo_axes_proxies.data[i] = const_cast<char *>(adapter->_proxy_name.c_str());
117 // create the dynamic attributes
118 this->create_axes_dynamic_attributes();
120 // set the default lambda
121 this->set_lambda(1.54);
124 TangoHKLAdapter::~TangoHKLAdapter(void)
126 unsigned int i;
128 this->destroy_axes_dynamic_attributes();
130 // remove all pseudo axis adapters
131 for(i=0;i<_pseudoAxisAdapters.size();i++)
132 delete _pseudoAxisAdapters[i];
134 // remove all pseudo axes adapters;
135 for(i=0; i<_pseudoAxesAdapters.size(); ++i)
136 delete _pseudoAxesAdapters[i];
138 // remove all axisAdapter
139 _axes.clear();
141 if (_lambdaAttributeProxy)
142 delete _lambdaAttributeProxy;
144 // remove the hkl part
145 hkl_geometry_free(_diffractometer->geometry_r);
146 hkl_geometry_free(_diffractometer->geometry_w);
147 hkl_geometry_free(_diffractometer->geometry_r_real);
148 hkl_geometry_free(_diffractometer->geometry_w_real);
149 hkl_detector_free(_diffractometer->detector);
150 hkl_detector_free(_diffractometer->detector_real);
151 hkl_sample_list_free(_diffractometer->samples);
152 hkl_pseudo_axis_engine_list_free(_diffractometer->engines_r);
153 hkl_pseudo_axis_engine_list_free(_diffractometer->engines_w);
154 hkl_pseudo_axis_engine_list_free(_diffractometer->engines_r_real);
155 hkl_pseudo_axis_engine_list_free(_diffractometer->engines_w_real);
157 if(_diffractometer) {
158 delete _diffractometer;
159 _diffractometer = NULL;
163 void TangoHKLAdapter::connect_all_proxies(void)
165 omni_mutex_lock lock(_lock);
167 // connect the lambda proxy
168 if ((!_lambdaAttributeProxy && _auto_update_from_proxies)
169 && _device->lambdaAttributeProxy != "") {
172 _lambdaAttributeProxy = new Tango::AttributeProxy(_device->lambdaAttributeProxy);
174 catch(...) {
178 // connect the axes proxies
179 if (!this->ready && _auto_update_from_proxies) {
180 unsigned int nb;
182 nb = _device->realAxisProxies.size();
183 if (nb != _axes.size()) {
184 _wrong_nb_of_axis_proxies = true;
185 return;
186 } else {
187 unsigned int i, j;
188 bool ready = true;
190 for(i=0; i<nb; ++i) {
191 AxisAdapter & axis = _axes[i];
192 if (!axis.is_ready()){
193 // Find axis in the proxy list
194 for(j=0; j<nb; ++j) {
195 char *line = strdup(_device->realAxisProxies[j].c_str());
196 char *last;
197 char *axis_name = strtok_r(line, ":", &last);
198 char *proxy_name = strtok_r(NULL, ":", &last);
199 if (axis.get_name() == axis_name)
200 axis.connect(proxy_name);
201 free(line);
203 if (!axis.is_ready())
204 ready = false;
207 this->ready = ready;
212 void TangoHKLAdapter::set_lambda(double lambda)
214 omni_mutex_lock lock(_lock);
216 if ((!_auto_update_from_proxies || _device->lambdaAttributeProxy == "")
217 && lambda > 0){
218 _lambda = lambda;
219 _diffractometer->geometry_r->source.wave_length = lambda;
220 _diffractometer->geometry_w->source.wave_length = lambda;
221 _diffractometer->geometry_r_real->source.wave_length = lambda;
222 _diffractometer->geometry_w_real->source.wave_length = lambda;
226 // this method connect engines to the right geometry, detector and sample
227 void TangoHKLAdapter::update_pseudo_axis_engines(void)
229 hkl_pseudo_axis_engine_list_init(_diffractometer->engines_r,
230 _diffractometer->geometry_r,
231 _diffractometer->detector,
232 _diffractometer->samples->current);
234 hkl_pseudo_axis_engine_list_init(_diffractometer->engines_w,
235 _diffractometer->geometry_w,
236 _diffractometer->detector,
237 _diffractometer->samples->current);
239 hkl_pseudo_axis_engine_list_init(_diffractometer->engines_r_real,
240 _diffractometer->geometry_r_real,
241 _diffractometer->detector,
242 _diffractometer->samples->current);
244 hkl_pseudo_axis_engine_list_init(_diffractometer->engines_w_real,
245 _diffractometer->geometry_w_real,
246 _diffractometer->detector,
247 _diffractometer->samples->current);
250 void TangoHKLAdapter::update_lambda(void)
252 if (_lambdaAttributeProxy && _auto_update_from_proxies){
253 try{
254 _lambdaAttributeProxy->read() >> _lambda;
255 _diffractometer->geometry_r->source.wave_length = _lambda;
256 _diffractometer->geometry_w->source.wave_length = _lambda;
257 _diffractometer->geometry_r_real->source.wave_length = _lambda;
258 _diffractometer->geometry_w_real->source.wave_length = _lambda;
260 catch (Tango::DevFailed &){
262 }else
263 _lambda = _diffractometer->geometry_r->source.wave_length;
267 * this method update the angles attribut from the engines->geometry list
269 void TangoHKLAdapter::update_angles(void)
271 size_t i, j;
272 size_t xdim;
273 size_t ydim;
274 HklPseudoAxisEngine *engine;
275 double *data;
276 HklGeometry **geometries;
278 if(!_auto_update_from_proxies)
279 engine = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_w, "hkl");
280 else
281 engine = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_w_real, "hkl");
283 // update the computed_angles part
284 xdim = 1 + HKL_LIST_LEN(_diffractometer->geometry_r->axes);
285 ydim = HKL_LIST_LEN(engine->engines->geometries->geometries);
287 _angles.resize(xdim, ydim);
288 _angles.clear();
290 //fill the array
291 data = _angles.data;
292 geometries = engine->engines->geometries->geometries;
293 for(j=0; j<ydim; ++j){
294 HklGeometry *geom = geometries[j];
296 data[0] = j;
297 for(i=1; i<xdim; ++i)
298 data[i] = hkl_axis_get_value_unit(&geom->axes[i-1]);
299 data += xdim;
304 * this method update the reflections_angles when we change a sample parameter
306 void TangoHKLAdapter::update_reflections_angles(void)
308 HklSample *sample = _diffractometer->samples->current;
309 if (sample) {
310 unsigned int i, j;
311 size_t rdim;
312 double *data;
314 // the reflection Angles
315 rdim = HKL_LIST_LEN(sample->reflections);
316 _reflections_angles.resize(rdim, rdim);
317 _reflections_angles.clear();
319 data = _reflections_angles.data;
320 for(i=0; i<rdim; ++i) {
321 for(j=0; j<rdim; ++j) {
322 double angle = 0.;
323 if (j < i)
324 angle = hkl_sample_get_reflection_theoretical_angle(sample, i, j);
325 else if (j > i)
326 angle = hkl_sample_get_reflection_mesured_angle(sample, i, j);
328 *data = angle * HKL_RADTODEG;
329 data++;
335 void TangoHKLAdapter::update_reflections(void)
337 HklSample *sample = _diffractometer->samples->current;
338 if (sample) {
340 // Allocation of the image
341 unsigned int xdim = 6 + HKL_LIST_LEN(_diffractometer->geometry_r->axes);
342 unsigned int ydim = HKL_LIST_LEN(sample->reflections);
343 _reflections.resize(xdim, ydim);
345 size_t i = 0;
346 double *data = _reflections.data;
347 for(i=0; i<ydim; ++i) {
348 HklSampleReflection *r;
350 r = hkl_sample_get_ith_reflection(sample, i);
351 if (r) {
352 size_t k;
353 HklAxis *axes = r->geometry->axes;
355 data[0] = i;
356 data[1] = r->hkl.data[0];
357 data[2] = r->hkl.data[1];
358 data[3] = r->hkl.data[2];
359 data[4] = 0;
360 data[5] = (double)r->flag;
362 for(k=0; k<HKL_LIST_LEN(r->geometry->axes); ++k)
363 data[6 + k] = hkl_axis_get_value_unit(&axes[k]);
365 data += xdim;
370 void TangoHKLAdapter::update_ub(void)
372 HklSample const *sample = _diffractometer->samples->current;
373 if(sample){
374 size_t dim = 3;
375 _ub.resize(dim, dim);
376 _ub.set_data_from_buffer(&(sample->UB.data[0][0]), dim, dim);
380 void TangoHKLAdapter::update_ux_uy_uz(void)
382 HklSample *sample = _diffractometer->samples->current;
384 if(sample){
385 hkl_matrix_to_euler(&sample->U, &_ux, &_uy, &_uz);
386 _ux *= HKL_RADTODEG;
387 _uy *= HKL_RADTODEG;
388 _uz *= HKL_RADTODEG;
393 * this method update all the AxisAdapter from the proxy every 200 ms.
394 * this from_proxy get the real part from the proxy and the "sim" part
395 * from the HklAxis in simulated mode or from the proxy in real mode
396 * else it updates them from the HklAxis.
398 * every 200 ms
399 * simulated:
400 * real <- proxy
401 * sim <- HklAxis
402 * non simulated:
403 * real <- proxy
404 * sim <- proxy
405 * rest of the time
406 * real <- HklAxis
407 * simulated -> HklAxis
409 void TangoHKLAdapter::update_axis_adapters(void)
411 size_t i;
413 // first read from the proxy.
414 duration.Stop();
415 if(duration.GetDurationInMs() >= 200) {
416 for(size_t i=0; i<_axes.size(); ++i)
417 _axes[i].from_proxy(!_auto_update_from_proxies);
418 duration.Start();
419 }else
420 for(i=0; i<_axes.size(); ++i)
421 _axes[i].from_HklAxis();
424 void TangoHKLAdapter::update_hkl_from_axis_adapters(void)
426 size_t i;
428 // set the axis
429 for(i=0; i<_axes.size(); ++i)
430 _axes[i].to_HklAxis();
432 // update the pseudo axes
433 if(_diffractometer && _diffractometer->samples){
434 hkl_pseudo_axis_engine_list_get(_diffractometer->engines_r);
435 hkl_pseudo_axis_engine_list_get(_diffractometer->engines_w);
436 hkl_pseudo_axis_engine_list_get(_diffractometer->engines_r_real);
437 hkl_pseudo_axis_engine_list_get(_diffractometer->engines_w_real);
441 void TangoHKLAdapter::update_pseudo_axis_adapters_from_hkl(void)
443 for(size_t i=0;i<_pseudoAxisAdapters.size();++i)
444 _pseudoAxisAdapters[i]->update();
447 void TangoHKLAdapter::update_proxies_from_axis_adapters(void)
449 size_t i;
451 // first stop motion of all axes.
452 for(i=0; i<_axes.size(); ++i)
453 _axes[i].stop();
455 // then send write values to the proxies
456 for(i=0; i<_axes.size(); ++i)
457 _axes[i].to_proxy();
460 void TangoHKLAdapter::update_proxies_from_pseudo_axis_adapters(PseudoAxisAdapter *adapter)
462 adapter->to_proxies();
465 void TangoHKLAdapter::update_pseudo_axes_adapters_from_hkl(void)
467 size_t i, j, len;
468 HklPseudoAxisEngine *engine_r, *engine_w;
470 for(i=0; i<_pseudoAxesAdapters.size(); ++i){
471 PseudoAxesAdapter *adapter;
473 adapter = _pseudoAxesAdapters[i];
474 engine_r = _diffractometer->engines_r->engines[i];
475 engine_w = _diffractometer->engines_w->engines[i];
476 len = HKL_LIST_LEN(engine_r->pseudoAxes);
477 for(j=0; j<len; ++j){
478 adapter->_read.data[j] = hkl_parameter_get_value_unit((HklParameter *)engine_r->pseudoAxes[j]);
479 adapter->_write.data[j] = hkl_parameter_get_value_unit((HklParameter *)engine_w->pseudoAxes[j]);
482 adapter->update();
486 void TangoHKLAdapter::update_state_and_status(void)
488 Tango::DevState state;
489 std::string status;
490 std::string extra_status;
492 state = Tango::STANDBY;
493 if (!_auto_update_from_proxies)
494 status = "AutoUpdateFromProxies OFF";
495 else {
496 status = "AutoUpdateFromProxies ON";
498 if (!this->ready) {
499 state = Tango::FAULT;
500 extra_status += "\nCan not connect to axes proxies";
501 // update the monochromator proxy status.
502 if (!_lambdaAttributeProxy && _auto_update_from_proxies) {
503 extra_status += "\nCan not connect to the lambdaAttributeProxy";
504 extra_status += "\nCheck also the lambdaAttributeProxy property";
506 } else {
507 try {
508 for(unsigned int i=0; i<_axes.size(); ++i) {
509 AxisAdapter const & axis = _axes[i];
510 std::string proxy_name = axis.get_proxy_name();
511 Tango::DevState tmpState = axis.get_state();
513 ::compose_state(state, tmpState);
514 if (tmpState != Tango::STANDBY)
515 extra_status += "\n" + proxy_name + " is in " + Tango::DevStateName[tmpState];
517 } catch(...)
519 state = Tango::FAULT;
520 extra_status += "\nCan not connect to axes proxies";
526 if (_diffractometer){
527 status += "\nSample: ";
528 if(!_diffractometer->samples->current){
529 status += "Not yet Set";
530 state = Tango::FAULT;
531 } else
532 status += _diffractometer->samples->current->name;
533 if (state == Tango::STANDBY)
534 extra_status += "\nready to compute hkl";
535 }else{
536 state = Tango::FAULT;
537 extra_status += "\nhkl core not yet initialized !!!";
539 status += "\nDiffractometer status: ";
540 status += Tango::DevStateName[state];
541 status += extra_status;
543 _diffractometerConfig.state = state;
544 _diffractometerConfig.status = status;
547 void TangoHKLAdapter::update(void)
549 /**********************************************
550 * CRITICAL SECTION
551 **********************************************/
552 omni_mutex_lock lock(_lock);
554 this->update_lambda();
555 this->update_axis_adapters();
556 this->update_hkl_from_axis_adapters();
557 this->update_pseudo_axis_adapters_from_hkl();
558 this->update_pseudo_axes_adapters_from_hkl();
559 this->update_state_and_status();
560 /**********************************************
561 * END OF CRITICAL SECTION
562 **********************************************/
565 /********************/
566 /* State and status */
567 /********************/
568 void TangoHKLAdapter::get_diffractometer_config(DiffractometerConfig & config)
570 omni_mutex_lock lock(_lock);
572 config = _diffractometerConfig;
575 /************/
576 /* hkl part */
577 /************/
579 short & TangoHKLAdapter::get_angles_idx(void)
581 omni_mutex_lock lock(_lock);
583 return _angles_idx;
586 void TangoHKLAdapter::set_angles_idx(short idx)
588 omni_mutex_lock lock(_lock);
590 // A REVOIR
591 if(idx >= 0 && idx < (int)_angles.ydim){
592 size_t i;
593 double *values;
595 _angles_idx = idx;
596 values = &_angles.data[1 + idx * _angles.xdim];
597 for(i=0; i<_axes.size(); ++i)
598 this->write_axis_i(_axes[i], values[i]);
602 void TangoHKLAdapter::load(void)
604 this->load_1();
607 void TangoHKLAdapter::load_1(void)
609 unsigned long nb_properties;
611 // Get the Crystal Attributes properties.
612 Tango::DbData properties;
613 properties.push_back(Tango::DbDatum("Crystal"));
614 _device->get_db_device()->get_attribute_property(properties);
616 // the first one is the number of properties
617 properties[0] >> nb_properties;
619 if (nb_properties > 1) {
620 unsigned long i, j;
621 HklGeometry *geometry;
622 HklDetector *detector;
624 geometry = hkl_geometry_new_copy(_diffractometer->geometry_r);
625 detector = hkl_detector_new_copy(_diffractometer->detector);
627 hkl_sample_list_clear(_diffractometer->samples);
628 for(i=1; i<=nb_properties; ++i) {
629 // skip the _ver property
630 if(!strcasecmp("_ver", properties[i].name.c_str()))
631 continue;
633 HklSample * sample;
635 // The name of the property name is the name of a crystal.
636 sample = hkl_sample_new(properties[i].name.c_str(), HKL_SAMPLE_MONOCRYSTAL);
638 // Extract the lines store in the property
639 std::vector<std::string> lines;
640 properties[i] >> lines;
642 for(j=0; j<lines.size(); j++) {
643 char *line = strdup(lines[j].c_str());
644 char *last;
645 char *key = strtok_r(line, "=", &last);
647 if (!strcmp(key,"lattice")) {
648 double a = atof(strtok_r(NULL, ";", &last));
649 double b = atof(strtok_r(NULL, ";", &last));
650 double c = atof(strtok_r(NULL, ";", &last));
651 double alpha = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
652 double beta = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
653 double gamma = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
654 hkl_sample_set_lattice(sample, a, b, c, alpha, beta, gamma);
656 sample->lattice->a->fit = atoi(strtok_r(NULL, ";", &last));
657 sample->lattice->b->fit = atoi(strtok_r(NULL, ";", &last));
658 sample->lattice->c->fit = atoi(strtok_r(NULL, ";", &last));
659 sample->lattice->alpha->fit = atoi(strtok_r(NULL, ";", &last));
660 sample->lattice->beta->fit = atoi(strtok_r(NULL, ";", &last));
661 sample->lattice->gamma->fit = atoi(strtok_r(NULL, ";", &last));
662 } else if (!strcmp(key, "uxuyuz")){
663 double ux = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
664 double uy = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
665 double uz = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
666 hkl_sample_set_U_from_euler(sample, ux, uy, uz);
667 } else if (!strcmp(key,"reflection")) {
668 unsigned int idx = 0;
669 HklSampleReflection *reflection;
671 double wavelength = atof(strtok_r(NULL, ";", &last));
672 double h = atof(strtok_r(NULL, ";", &last));
673 double k = atof(strtok_r(NULL, ";", &last));
674 double l = atof(strtok_r(NULL, ";", &last));
675 int flag = atoi(strtok_r(NULL, ";", &last));
677 // first set the geometry axes
678 while(key = strtok_r(NULL, ";", &last))
679 hkl_axis_set_value_unit(&geometry->axes[idx++], atof(key));
680 geometry->source.wave_length = wavelength;
682 reflection = hkl_sample_add_reflection(sample, geometry, detector, h, k, l);
683 reflection->flag = flag;
685 free(line);
686 // End of key research
687 }// End for each parameters
688 hkl_sample_list_append(_diffractometer->samples, sample);
689 }// End for each property
691 hkl_detector_free(detector);
692 hkl_geometry_free(geometry);
694 //_device->refresh_crystal_parameters();
698 void TangoHKLAdapter::save(void)
700 omni_mutex_lock lock(_lock);
702 size_t i, j, k;
703 size_t len;
704 Tango::DbData crystal_prop;
705 Tango::DbData data_put;
707 // Step 1 : clean all properties
708 // FP Le mieux serait sans doute de ne pas effacer les propriétés d'attribut
709 // avant d'avoir crée correctement un data_put.
710 crystal_prop.push_back(Tango::DbDatum("Crystal"));
711 _device->get_db_device()->get_attribute_property(crystal_prop);
712 long number_of_prop = 0;
713 crystal_prop[0] >> number_of_prop ;
714 if( number_of_prop > 0)
715 _device->get_db_device()->delete_attribute_property(crystal_prop);
717 // Step 2 : create the Crystal properties
718 Tango::DbDatum properties("Crystal");
719 // Put number of properties (= nb of samples + 1)
720 len = hkl_sample_list_len(_diffractometer->samples);
721 properties << (long)(len + 1);
722 data_put.push_back(properties);
724 // first property is the format version
725 Tango::DbDatum version("_ver");
726 version << (long)FORMAT_VERSION;
727 data_put.push_back(version);
729 // now each sample
730 for(k=0; k<len; ++k){
731 HklSample *sample;
732 std::vector<std::string> lines;
733 char line[256];
735 // the lattices values
736 sample = hkl_sample_list_get_ith(_diffractometer->samples, k);
737 double a = hkl_parameter_get_value_unit(sample->lattice->a);
738 double b = hkl_parameter_get_value_unit(sample->lattice->b);
739 double c = hkl_parameter_get_value_unit(sample->lattice->c);
740 double alpha = hkl_parameter_get_value_unit(sample->lattice->alpha);
741 double beta = hkl_parameter_get_value_unit(sample->lattice->beta);
742 double gamma = hkl_parameter_get_value_unit(sample->lattice->gamma);
743 // the fit flag
744 int a_fit = sample->lattice->a->fit;
745 int b_fit = sample->lattice->b->fit;
746 int c_fit = sample->lattice->c->fit;
747 int alpha_fit = sample->lattice->alpha->fit;
748 int beta_fit = sample->lattice->beta->fit;
749 int gamma_fit = sample->lattice->gamma->fit;
751 snprintf(line, 255, "lattice=%f;%f;%f;%f;%f;%f;%d;%d;%d;%d;%d;%d",
752 a, b, c, alpha, beta, gamma,
753 a_fit, b_fit, c_fit, alpha_fit, beta_fit, gamma_fit);
754 lines.push_back(line);
756 // the UxUyUz parameters
757 double ux, uy, uz;
758 hkl_matrix_to_euler(&sample->U, &ux, &uy, &uz);
759 ux *= HKL_RADTODEG;
760 uy *= HKL_RADTODEG;
761 uz *= HKL_RADTODEG;
763 snprintf(line, 255, "uxuyuz=%f;%f;%f", ux, uy, uz);
764 lines.push_back(line);
766 // the reflections
767 for(i=0; i<HKL_LIST_LEN(sample->reflections); ++i) {
768 HklSampleReflection *reflection;
770 reflection = hkl_sample_get_ith_reflection(sample, i);
771 double wavelength = reflection->geometry->source.wave_length;
772 double h = reflection->hkl.data[0];
773 double k = reflection->hkl.data[1];
774 double l = reflection->hkl.data[2];
775 int flag = reflection->flag;
777 snprintf(line, 255, "reflection=%f;%f;%f;%f;%d",
778 wavelength, h, k, l, flag);
779 // Extract values of each axes
780 for(j=0; j<HKL_LIST_LEN(reflection->geometry->axes); ++j) {
781 char pos[256];
782 double rad = hkl_axis_get_value_unit(&reflection->geometry->axes[j]);
783 snprintf(pos, 255, ";%f", rad);
784 strncat(line, pos, 255);
786 lines.push_back(line);
789 // Try to create property
790 // Get crystal name
791 Tango::DbDatum property(sample->name);
792 property << lines;
793 data_put.push_back(property);
796 //update database for this property
797 _device->get_db_device()->put_attribute_property(data_put);
800 /***************/
801 /* sample part */
802 /***************/
804 char const *TangoHKLAdapter::get_sample_name(void)
806 omni_mutex_lock lock(_lock);
808 HklSample *sample = _diffractometer->samples->current;
809 if(sample)
810 return sample->name;
811 else
812 return "";
815 void TangoHKLAdapter::set_current_sample(char const * name)
817 omni_mutex_lock lock(_lock);
819 HklSample *last;
821 last = _diffractometer->samples->current;
822 if (HKL_SUCCESS == hkl_sample_list_select_current(_diffractometer->samples, name))
823 if (last != _diffractometer->samples->current){
824 this->update_pseudo_axis_engines();
825 this->update_ub();
826 this->update_ux_uy_uz();
827 this->update_reflections_angles();
828 this->update_reflections();
829 this->update_state_and_status();
833 void TangoHKLAdapter::get_sample_lattices(double *a, double *b, double *c,
834 double *alpha, double *beta, double *gamma,
835 double *a_star, double *b_star, double *c_star,
836 double *alpha_star, double *beta_star, double *gamma_star)
838 omni_mutex_lock lock(_lock);
840 HklSample * sample = _diffractometer->samples->current;
841 if (!sample)
842 return;
844 HklLattice const *lattice = sample->lattice;
845 HklLattice *reciprocal = hkl_lattice_new_copy(lattice);
847 hkl_lattice_reciprocal(lattice, reciprocal);
849 // direct space
850 *a = hkl_parameter_get_value_unit(lattice->a);
851 *b = hkl_parameter_get_value_unit(lattice->b);
852 *c = hkl_parameter_get_value_unit(lattice->c);
853 *alpha = hkl_parameter_get_value_unit(lattice->alpha);
854 *beta = hkl_parameter_get_value_unit(lattice->beta);
855 *gamma = hkl_parameter_get_value_unit(lattice->gamma);
857 // reciprocal space
858 *a_star = hkl_parameter_get_value_unit(reciprocal->a);
859 *b_star = hkl_parameter_get_value_unit(reciprocal->b);
860 *c_star = hkl_parameter_get_value_unit(reciprocal->c);
861 *alpha_star = hkl_parameter_get_value_unit(reciprocal->alpha);
862 *beta_star = hkl_parameter_get_value_unit(reciprocal->beta);
863 *gamma_star = hkl_parameter_get_value_unit(reciprocal->gamma);
865 hkl_lattice_free(reciprocal);
868 void TangoHKLAdapter::get_sample_fit(bool *afit, bool *bfit, bool *cfit,
869 bool *alphafit, bool *betafit, bool *gammafit,
870 bool *uxfit, bool *uyfit, bool *uzfit)
872 omni_mutex_lock lock(_lock);
874 HklSample * sample = _diffractometer->samples->current;
875 if (!sample)
876 return;
878 HklLattice const *lattice = sample->lattice;
880 *afit = lattice->a->fit;
881 *bfit = lattice->b->fit;
882 *cfit = lattice->c->fit;
883 *alphafit = lattice->alpha->fit;
884 *betafit = lattice->beta->fit;
885 *gammafit = lattice->gamma->fit;
886 *uxfit = _uxfit;
887 *uyfit = _uyfit;
888 *uzfit = _uzfit;
892 void TangoHKLAdapter::set_sample_Ux(double ux)
894 HklSample *sample;
896 sample = _diffractometer->samples->current;
897 if (sample){
898 if (HKL_SUCCESS == hkl_sample_set_U_from_euler(sample,
899 ux * HKL_DEGTORAD,
900 _uy * HKL_DEGTORAD,
901 _uz * HKL_DEGTORAD)){
902 _ux = ux;
903 this->update_ub();
904 }else
905 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this Ux value",
906 "Set a correct value");
910 void TangoHKLAdapter::set_sample_Uy(double uy)
912 HklSample *sample;
914 sample = _diffractometer->samples->current;
915 if (sample){
916 if (HKL_SUCCESS == hkl_sample_set_U_from_euler(sample,
917 _ux * HKL_DEGTORAD,
918 uy * HKL_DEGTORAD,
919 _uz * HKL_DEGTORAD)){
920 _uy = uy;
921 this->update_ub();
922 }else
923 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this Uy value",
924 "Set a correct value");
928 void TangoHKLAdapter::set_sample_Uz(double uz)
930 HklSample *sample;
932 sample = _diffractometer->samples->current;
933 if (sample){
934 if (HKL_SUCCESS == hkl_sample_set_U_from_euler(sample,
935 _ux * HKL_DEGTORAD,
936 _uy * HKL_DEGTORAD,
937 uz * HKL_DEGTORAD)){
938 _uz = uz;
939 this->update_ub();
940 }else
941 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this Uz value",
942 "Set a correct value");
946 void TangoHKLAdapter::set_sample_AFit(bool fit)
948 HklSample *sample;
950 sample = _diffractometer->samples->current;
951 if (sample)
952 sample->lattice->a->fit = fit;
955 void TangoHKLAdapter::set_sample_BFit(bool fit)
957 HklSample *sample;
959 sample = _diffractometer->samples->current;
960 if (sample)
961 sample->lattice->b->fit = fit;
964 void TangoHKLAdapter::set_sample_CFit(bool fit)
966 HklSample *sample;
968 sample = _diffractometer->samples->current;
969 if (sample)
970 sample->lattice->c->fit = fit;
973 void TangoHKLAdapter::set_sample_AlphaFit(bool fit)
975 HklSample *sample;
977 sample = _diffractometer->samples->current;
978 if (sample)
979 sample->lattice->alpha->fit = fit;
982 void TangoHKLAdapter::set_sample_BetaFit(bool fit)
984 HklSample *sample;
986 sample = _diffractometer->samples->current;
987 if (sample)
988 sample->lattice->beta->fit = fit;
991 void TangoHKLAdapter::set_sample_GammaFit(bool fit)
993 HklSample *sample;
995 sample = _diffractometer->samples->current;
996 if (sample)
997 sample->lattice->gamma->fit = fit;
1000 void TangoHKLAdapter::set_sample_UxFit(bool fit)
1002 HklSample *sample;
1004 sample = _diffractometer->samples->current;
1005 if (sample)
1006 _uxfit = _uyfit = _uzfit = fit;
1009 void TangoHKLAdapter::set_sample_UyFit(bool fit)
1011 HklSample *sample;
1013 sample = _diffractometer->samples->current;
1014 if (sample)
1015 _uxfit = _uyfit = _uzfit = fit;
1018 void TangoHKLAdapter::set_sample_UzFit(bool fit)
1020 HklSample *sample;
1022 sample = _diffractometer->samples->current;
1023 if (sample)
1024 _uxfit = _uyfit = _uzfit = fit;
1027 void TangoHKLAdapter::add_new_sample(std::string const & name)
1029 omni_mutex_lock lock(_lock);
1031 HklSample *sample = hkl_sample_new(name.c_str(), HKL_SAMPLE_MONOCRYSTAL);
1033 if (!hkl_sample_list_append(_diffractometer->samples, sample)){
1034 hkl_sample_free(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");
1040 void TangoHKLAdapter::copy_sample_as(Tango::DevString copy_name)
1042 omni_mutex_lock lock(_lock);
1044 HklSample *sample;
1045 HklSample const *current;
1047 current = _diffractometer->samples->current;
1048 if(!current)
1049 TANGO_EXCEPTION_THROW_WITHOUT_LOG("No current sample set",
1050 "Please set a current sample");
1052 sample = hkl_sample_list_get_by_name(_diffractometer->samples, copy_name);
1053 if (sample)
1054 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not add a sample with this name",
1055 "A sample with the same name is already present in the sample list");
1057 sample = hkl_sample_new_copy(current);
1058 if(sample){
1059 hkl_sample_set_name(sample, copy_name);
1060 hkl_sample_list_append(_diffractometer->samples, sample);
1064 void TangoHKLAdapter::del_sample(void)
1066 omni_mutex_lock lock(_lock);
1068 HklSampleList *samples = _diffractometer->samples;
1069 hkl_sample_list_del(samples, samples->current);
1071 // add a default sample if no more sample in the list
1072 if(hkl_sample_list_len(samples) == 0){
1073 HklSample *sample = hkl_sample_new("default", HKL_SAMPLE_MONOCRYSTAL);
1074 samples->current = hkl_sample_list_append(samples, sample);
1075 }else
1076 samples->current = hkl_sample_list_get_ith(samples, 0);
1077 this->update_ub();
1078 this->update_ux_uy_uz();
1079 this->update_reflections_angles();
1080 this->update_reflections();
1083 void TangoHKLAdapter::set_lattice(const Tango::DevVarDoubleArray *argin)
1085 omni_mutex_lock lock(_lock);
1087 if (argin && argin->length() != 6)
1088 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1089 "Did not receive the exact amount of crystal parameters: A, B, C, alpha, beta, gamma");
1091 HklSample *sample = _diffractometer->samples->current;
1092 if (HKL_FAIL == hkl_sample_set_lattice(sample,
1093 (*argin)[0],(*argin)[1], (*argin)[2],
1094 (*argin)[3] * HKL_DEGTORAD,
1095 (*argin)[4] * HKL_DEGTORAD,
1096 (*argin)[5] * HKL_DEGTORAD))
1098 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this lattice combination.",
1099 "Please set a good combination");
1100 this->update_ub();
1101 this->update_reflections_angles();
1104 void TangoHKLAdapter::add_reflection(const Tango::DevVarDoubleArray *argin)
1106 omni_mutex_lock lock(_lock);
1108 HklSample *sample = _diffractometer->samples->current;
1110 if(sample){
1111 double h, k, l;
1112 HklSampleReflection *ref;
1114 if(argin && argin->length() == 3){
1115 h = (*argin)[0];
1116 k = (*argin)[1];
1117 l = (*argin)[2];
1118 }else{
1119 HklPseudoAxisEngine *engine;
1121 engine = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_r, "hkl");
1123 h = hkl_parameter_get_value_unit((HklParameter *)engine->pseudoAxes[0]);
1124 k = hkl_parameter_get_value_unit((HklParameter *)engine->pseudoAxes[1]);
1125 l = hkl_parameter_get_value_unit((HklParameter *)engine->pseudoAxes[2]);
1128 ref = hkl_sample_add_reflection(sample,
1129 _diffractometer->geometry_r,
1130 _diffractometer->detector,
1131 h, k, l);
1132 if(ref){
1133 this->update_reflections_angles();
1134 this->update_reflections();
1139 void TangoHKLAdapter::del_reflection(Tango::DevShort argin)
1141 omni_mutex_lock lock(_lock);
1143 if (HKL_FAIL == hkl_sample_del_reflection(_diffractometer->samples->current, argin))
1144 TANGO_EXCEPTION_THROW_WITHOUT_LOG("index out of range",
1145 "change the reflection index");
1146 this->update_reflections_angles();
1147 this->update_reflections();
1150 void TangoHKLAdapter::set_reflections(Matrix<double> const & img)
1152 omni_mutex_lock lock(_lock);
1154 HklSample *sample = _diffractometer->samples->current;
1155 if (sample
1156 && img.xdim == _reflections.xdim
1157 && img.ydim == _reflections.ydim) {
1159 size_t i = 0;
1160 size_t j = 0;
1161 for(i=0; i<HKL_LIST_LEN(sample->reflections); ++i) {
1162 HklSampleReflection *r;
1164 r = hkl_sample_get_ith_reflection(sample, i);
1165 if (r) {
1166 hkl_sample_reflection_set_hkl(r, img.data[j+1], img.data[j+2], img.data[j+3]);
1167 hkl_sample_reflection_set_flag(r, (int)img.data[j+5]);
1168 if(!_device->protectReflectionAxes){
1169 HklAxis *axes;
1170 size_t len;
1171 size_t k;
1173 len = HKL_LIST_LEN(r->geometry->axes);
1174 axes = &r->geometry->axes[0];
1176 for(k=6; k<6+len; ++k)
1177 hkl_axis_set_value_unit(axes++, img.data[j+k]);
1179 hkl_geometry_update(r->geometry);
1180 hkl_sample_reflection_set_geometry(r, r->geometry);
1183 j += _reflections.xdim;
1185 this->update_reflections();
1186 this->update_reflections_angles();
1190 double TangoHKLAdapter::affine_sample(std::string name)
1192 omni_mutex_lock lock(_lock);
1194 HklSample *sample;
1195 double res = 0.;
1197 sample = hkl_sample_list_get_by_name(_diffractometer->samples, name.c_str());
1198 if(sample){
1199 HklSample *tmp;
1201 // check if the affine sample is already in the HklSampleList
1202 std::string name = sample->name;
1203 name += "(affine)";
1204 tmp = hkl_sample_list_get_by_name(_diffractometer->samples, name.c_str());
1205 hkl_sample_list_del(_diffractometer->samples, tmp);
1207 tmp = hkl_sample_new_copy(sample);
1208 hkl_sample_set_name(tmp, name.c_str());
1209 res = hkl_sample_affine(tmp);
1211 hkl_sample_list_append(_diffractometer->samples, tmp);
1212 _diffractometer->samples->current = tmp;
1214 this->update_ub();
1215 this->update_ux_uy_uz();
1216 this->update_reflections_angles();
1219 return res;
1223 std::vector<std::string> TangoHKLAdapter::get_samples_names(void)
1225 omni_mutex_lock lock(_lock);
1227 std::vector<std::string> names;
1228 size_t i, len;
1229 HklSampleList *samples = _diffractometer->samples;
1231 len = hkl_sample_list_len(samples);
1232 for(i=0; i<len; ++i)
1233 names.push_back(hkl_sample_list_get_ith(samples, i)->name);
1235 return names;
1238 // DEPRECATED
1239 void TangoHKLAdapter::get_sample_parameter_values(Tango::DevVarDoubleStringArray *argout)
1241 omni_mutex_lock lock(_lock);
1243 HklSample *sample;
1244 HklParameter *parameter = NULL;
1245 std::string name;
1247 //check parameters
1248 if (argout->svalue.length() != 1)
1249 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1250 "only one string = parameter name");
1252 sample = _diffractometer->samples->current;
1253 if(sample){
1254 //parameters OK
1255 name = argout->svalue[0];
1256 if(name == "a")
1257 parameter = sample->lattice->a;
1258 else if(name == "b")
1259 parameter = sample->lattice->b;
1260 else if(name == "c")
1261 parameter = sample->lattice->c;
1262 else if(name == "alpha")
1263 parameter = sample->lattice->alpha;
1264 else if(name == "beta")
1265 parameter = sample->lattice->beta;
1266 else if(name == "gamma")
1267 parameter = sample->lattice->gamma;
1269 if (parameter){
1270 argout->dvalue[0] = parameter->range.min;
1271 argout->dvalue[1] = parameter->range.max;
1272 argout->dvalue[2] = parameter->fit;
1273 }else
1274 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Wrong parameter name",
1275 "Select: a, b, c, alpha, beta, gamma");
1279 //DEPRECATED
1280 void TangoHKLAdapter::set_sample_parameter_values(Tango::DevVarDoubleStringArray const *argin)
1282 omni_mutex_lock lock(_lock);
1284 HklSample *sample;
1285 HklParameter *parameter = NULL;
1286 std::string name;
1288 // check parameters
1289 if(argin->dvalue.length() != 3)
1290 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1291 "set_crystal_parameter_values did not receive the right amount of scalar parameters: min, max, flag");
1292 if((argin->svalue.length() ) != 1)
1293 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1294 "set_crystal_parameter_values did not receive the right amount of string parameters: parameter name");
1296 // parameters OK
1297 sample = _diffractometer->samples->current;
1298 if(!sample)
1299 TANGO_EXCEPTION_THROW_WITHOUT_LOG("No current sample set",
1300 "Please set a current sample");
1302 name = argin->svalue[0];
1303 if(name == "a")
1304 parameter = sample->lattice->a;
1305 else if(name == "b")
1306 parameter = sample->lattice->b;
1307 else if(name == "c")
1308 parameter = sample->lattice->c;
1309 else if(name == "alpha")
1310 parameter = sample->lattice->alpha;
1311 else if(name == "beta")
1312 parameter = sample->lattice->beta;
1313 else if(name == "gamma")
1314 parameter = sample->lattice->gamma;
1316 if (parameter){
1317 parameter->range.min = argin->dvalue[0];
1318 parameter->range.max = argin->dvalue[1];
1319 parameter->fit = argin->dvalue[2] != 0.;
1320 }else
1321 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Wrong parameter name",
1322 "Select: a, b, c, alpha, beta, gamma");
1323 this->update_ub();
1324 this->update_ux_uy_uz();
1325 this->update_reflections_angles();
1328 void TangoHKLAdapter::compute_u(const Tango::DevVarLongArray *argin)
1330 omni_mutex_lock lock(_lock);
1332 HklSample *sample;
1334 // is parameter ok ?
1335 if (argin->length() != 2)
1336 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Need exactly two reflections indexes",
1337 "use the right number of parameters");
1339 sample = _diffractometer->samples->current;
1340 if (!sample)
1341 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not compute the U matrix without current sample set.",
1342 "Set a current sample");
1344 if (hkl_sample_compute_UB_busing_levy(sample, (*argin)[0], (*argin)[1]))
1345 TANGO_EXCEPTION_THROW_WITHOUT_LOG("can not compute the UB matrix using thoses reflections index",
1346 "Use other reflections");
1347 this->update_ub();
1348 this->update_ux_uy_uz();
1351 /*************/
1352 /* Axis part */
1353 /*************/
1355 void TangoHKLAdapter::read_axis(int idx, double & read, double & write)
1357 omni_mutex_lock lock(_lock);
1359 AxisAdapter & axis = _axes[idx];
1360 read = axis.get_read();
1361 write = axis.get_write();
1364 void TangoHKLAdapter::stop_all_axis(void)
1366 #ifdef WRITE_TO_PROXY_ALLOWED
1367 size_t i;
1368 for(i=0; i<_axes.size(); ++i)
1369 _axes[i].stop();
1370 #endif
1373 void TangoHKLAdapter::write_axis(AxisAdapter & axis, double value)
1375 omni_mutex_lock lock(_lock);
1377 this->write_axis_i(axis, value);
1380 void TangoHKLAdapter::write_axis_i(AxisAdapter & axis, double value)
1382 axis._read = axis._write = value;
1383 hkl_axis_set_value_unit(axis._axis_r, value);
1384 hkl_axis_set_value_unit(axis._axis_w, value);
1387 /*******************/
1388 /* pseudoAxis part */
1389 /*******************/
1391 std::vector<std::string> TangoHKLAdapter::pseudo_axis_get_names(void)
1393 omni_mutex_lock lock(_lock);
1395 std::vector<std::string> names;
1396 size_t i, j;
1398 for(i=0; i<HKL_LIST_LEN(_diffractometer->engines_r_real->engines); ++i){
1399 HklPseudoAxisEngine *engine;
1401 engine = _diffractometer->engines_r_real->engines[i];
1402 for(j=0; j<HKL_LIST_LEN(engine->pseudoAxes); ++j)
1403 names.push_back(((HklParameter *)(&engine->pseudoAxes[j]))->name);
1406 return names;
1409 PseudoAxisAdapter *TangoHKLAdapter::pseudo_axis_buffer_new(char const *name)
1411 omni_mutex_lock lock(_lock);
1413 PseudoAxisAdapter * buffer = NULL;
1414 HklPseudoAxis *pseudo_r;
1415 HklPseudoAxis *pseudo_w;
1417 pseudo_r = hkl_pseudo_axis_engine_list_get_pseudo_axis_by_name(
1418 _diffractometer->engines_r_real, name);
1419 pseudo_w = hkl_pseudo_axis_engine_list_get_pseudo_axis_by_name(
1420 _diffractometer->engines_w_real, name);
1422 if(pseudo_r && pseudo_w) {
1425 buffer = new PseudoAxisAdapter(*this, pseudo_r, pseudo_w);
1426 _pseudoAxisAdapters.push_back(buffer);
1428 catch (Tango::DevFailed)
1430 delete buffer;
1431 buffer = NULL;
1434 return buffer;
1437 void TangoHKLAdapter::pseudo_axis_set_initialized(PseudoAxisAdapter *buffer,
1438 Tango::DevBoolean initialized)
1440 if(initialized){
1441 this->update();
1443 omni_mutex_lock lock(_lock);
1445 hkl_pseudo_axis_engine_initialize(buffer->_pseudo_r->engine);
1446 hkl_pseudo_axis_engine_initialize(buffer->_pseudo_w->engine);
1450 void TangoHKLAdapter::pseudo_axis_set_position(PseudoAxisAdapter *buffer,
1451 const Tango::DevDouble & position)
1453 omni_mutex_lock lock(_lock);
1455 double value = position - buffer->_config.offset;
1456 int res = HKL_FAIL;
1458 HklPseudoAxisEngineList *engines_w_real = _diffractometer->engines_w_real;
1459 HklPseudoAxisEngine *engine = buffer->_pseudo_w->engine;
1460 HklGeometry *geometry_w_real = _diffractometer->geometry_w_real;
1462 hkl_parameter_set_value_unit((HklParameter *)buffer->_pseudo_w, value);
1463 res = hkl_pseudo_axis_engine_set(buffer->_pseudo_w->engine);
1464 if (HKL_SUCCESS == res){
1465 hkl_geometry_init_geometry(geometry_w_real, engine->engines->geometries->geometries[0]);
1466 hkl_pseudo_axis_engine_list_get(engines_w_real);
1468 _angles_idx = 0;
1469 this->update_angles();
1470 buffer->to_proxies();
1471 this->update_axis_adapters();
1472 this->update_pseudo_axis_adapters_from_hkl();
1473 this->update_pseudo_axes_adapters_from_hkl();
1474 }else
1475 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not write on this pseudo axis",
1476 "Check the sample");
1480 PseudoAxisConfig TangoHKLAdapter::pseudo_axis_get_config(PseudoAxisAdapter *buffer)
1482 this->update();
1484 omni_mutex_lock lock(_lock);
1486 return buffer->_config;
1489 void TangoHKLAdapter::pseudo_axis_set_mode(PseudoAxisAdapter *buffer, Tango::DevString const & mode)
1491 omni_mutex_lock lock(_lock);
1493 size_t i, len;
1495 len = HKL_LIST_LEN(buffer->_pseudo_r->engine->modes);
1496 for(i=0; i<len; ++i)
1497 if(!strcasecmp(mode, buffer->_pseudo_r->engine->modes[i]->name))
1498 break;
1499 if(i<len){
1500 hkl_pseudo_axis_engine_select_mode(buffer->_pseudo_r->engine, i);
1501 hkl_pseudo_axis_engine_select_mode(buffer->_pseudo_w->engine, i);
1505 void TangoHKLAdapter::pseudo_axis_get_mode_parameters(PseudoAxisAdapter *buffer, Tango::DevVarDoubleStringArray *argout)
1507 omni_mutex_lock lock(_lock);
1509 HklPseudoAxisEngine *engine = buffer->_pseudo_r->engine;
1510 if (engine && engine->mode){
1511 size_t i;
1512 size_t len = HKL_LIST_LEN(engine->mode->parameters);
1514 argout->svalue.length(len);
1515 argout->dvalue.length(len);
1516 for(i=0; i<len; ++i){
1517 argout->svalue[i] = CORBA::string_dup(engine->mode->parameters[i].name);
1518 argout->dvalue[i] = hkl_parameter_get_value_unit(&engine->mode->parameters[i]);
1520 }else
1521 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not get the current Mode parameters values without a current mode set.",
1522 "");
1525 void TangoHKLAdapter::pseudo_axis_set_mode_parameters(PseudoAxisAdapter *buffer, const Tango::DevVarDoubleStringArray *argin)
1527 omni_mutex_lock lock(_lock);
1529 if(argin->svalue.length() != argin->dvalue.length())
1530 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1531 "set_mode_parameters_values did not receive the same amount between string and double values");
1533 HklPseudoAxisEngine *engine_r = buffer->_pseudo_r->engine;
1534 HklPseudoAxisEngine *engine_w = buffer->_pseudo_w->engine;
1535 if (engine_r && engine_w){
1536 size_t i;
1537 size_t len;
1539 len = argin->svalue.length();
1540 if (HKL_LIST_LEN(engine_r->mode->parameters) != len)
1541 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Not the right number of parameter",
1542 "gives the right number of parameters");
1544 for(i=0; i<len; ++i){
1545 double value = argin->dvalue[i];
1546 char const *name = argin->svalue[i];
1547 if(!strcmp(name, engine_r->mode->parameters[i].name)){
1548 hkl_parameter_set_value_unit(&engine_r->mode->parameters[i], value);
1549 hkl_parameter_set_value_unit(&engine_w->mode->parameters[i], value);
1552 }else
1553 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set the current Mode parameters values without a current mode set.",
1554 "");
1557 void TangoHKLAdapter::pseudo_axis_on(PseudoAxisAdapter *buffer)
1559 omni_mutex_lock lock(_lock);
1561 for(size_t i=0; i<buffer->_axes.size(); ++i)
1562 buffer->_axes[i]->on();
1565 /*******************/
1566 /* pseudoAxes part */
1567 /*******************/
1569 PseudoAxesAdapter *TangoHKLAdapter::pseudo_axes_adapter_get_by_name(std::string const & name)
1571 //omni_mutex_lock lock(_lock);
1573 unsigned int i;
1574 PseudoAxesAdapter *adapter = NULL;
1576 for(i=0; i<_pseudoAxesAdapters.size(); ++i)
1577 if(_pseudoAxesAdapters[i]->get_name() == name){
1578 adapter = _pseudoAxesAdapters[i];
1579 break;
1581 return adapter;
1584 PseudoAxesConfig TangoHKLAdapter::pseudo_axes_get_config(size_t idx)
1586 this->update();
1588 omni_mutex_lock lock(_lock);
1590 return _pseudoAxesAdapters[idx]->_config;
1594 void TangoHKLAdapter::pseudo_axes_write(size_t idx, Matrix<double> const & write) throw (Tango::DevFailed)
1596 omni_mutex_lock lock(_lock);
1598 size_t i, len;
1599 int res = HKL_FAIL;
1600 HklPseudoAxisEngineList *engines_r, *engines_w;
1601 HklGeometry *geometry_r, *geometry_w;
1603 engines_r = _diffractometer->engines_r;
1604 engines_w = _diffractometer->engines_w;
1605 len = HKL_LIST_LEN(engines_w->engines[idx]->pseudoAxes);
1607 geometry_r = _diffractometer->geometry_r;
1608 geometry_w = _diffractometer->geometry_w;
1610 for(i=0; i<len; ++i)
1611 hkl_parameter_set_value_unit((HklParameter *)(engines_w->engines[idx]->pseudoAxes[i]), write.data[i]);
1613 res = hkl_pseudo_axis_engine_set(engines_w->engines[idx]);
1615 if (HKL_SUCCESS == res){
1616 // force auto update OFF when we write on a PseudoAxes.
1617 _auto_update_from_proxies = false;
1619 hkl_geometry_init_geometry(geometry_w, engines_w->geometries->geometries[0]);
1620 hkl_pseudo_axis_engine_list_get(engines_w);
1621 hkl_geometry_init_geometry(geometry_r, engines_w->geometries->geometries[0]);
1622 hkl_pseudo_axis_engine_list_get(engines_r);
1624 _angles_idx = 0;
1625 this->update_angles();
1626 this->update_axis_adapters();
1627 this->update_pseudo_axis_adapters_from_hkl();
1628 this->update_pseudo_axes_adapters_from_hkl();
1629 }else
1630 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not write on this pseudo axis",
1631 "Check the sample");
1635 Tango::DevString *TangoHKLAdapter::pseudo_axes_get_mode(size_t idx)
1637 omni_mutex_lock lock(_lock);
1639 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1640 if(engine->mode)
1641 return const_cast<Tango::DevString *>(&engine->mode->name);
1642 else
1643 return NULL;
1646 void TangoHKLAdapter::pseudo_axes_set_mode(size_t idx, const Tango::DevString name)
1648 omni_mutex_lock lock(_lock);
1650 size_t i;
1651 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1653 // check if we try to set the same mode than the current one
1654 if (engine->mode)
1655 if(!strcasecmp(name, engine->mode->name))
1656 return;
1658 // no so set the mode if possible
1659 size_t len = HKL_LIST_LEN(engine->modes);
1660 for(i=0; i<len; ++i)
1661 if(!strcasecmp(name, engine->modes[i]->name))
1662 break;
1663 if(i<len){
1664 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_r->engines[idx], i);
1665 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_w->engines[idx], i);
1666 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_r_real->engines[idx], i);
1667 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_w_real->engines[idx], i);
1668 _pseudoAxesAdapters[idx]->update_axes_i(engine);
1669 _pseudoAxesAdapters[idx]->update_state_and_status_i();
1673 Matrix<char *> & TangoHKLAdapter::pseudo_axes_get_mode_parameters_names(size_t idx)
1675 omni_mutex_lock lock(_lock);
1677 size_t i;
1678 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1679 size_t len = HKL_LIST_LEN(engine->mode->parameters);
1680 PseudoAxesAdapter *adapter = _pseudoAxesAdapters[idx];
1681 adapter->_mode_parameters_names.resize(len, 1);
1682 for(i=0; i<len; ++i)
1683 adapter->_mode_parameters_names.data[i] = const_cast<char *>(engine->mode->parameters[i].name);
1684 return adapter->_mode_parameters_names;
1687 Matrix<double> const & TangoHKLAdapter::pseudo_axes_get_mode_parameters(size_t idx)
1689 omni_mutex_lock lock(_lock);
1691 size_t i;
1692 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1693 size_t len = HKL_LIST_LEN(engine->mode->parameters);
1694 PseudoAxesAdapter *adapter = _pseudoAxesAdapters[idx];
1695 adapter->_mode_parameters.resize(len, 1);
1696 for(i=0; i<len; ++i)
1697 adapter->_mode_parameters.data[i] = hkl_parameter_get_value_unit(&engine->mode->parameters[i]);
1698 return adapter->_mode_parameters;
1701 void TangoHKLAdapter::pseudo_axes_set_mode_parameters(size_t idx, Matrix<double> const & values)
1703 omni_mutex_lock lock(_lock);
1705 size_t i;
1706 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1707 size_t len = HKL_LIST_LEN(engine->mode->parameters);
1708 if(len == values.xdim)
1709 for(i=0; i<len; ++i){
1710 double & value = values.data[i];
1712 hkl_parameter_set_value_unit(&_diffractometer->engines_r->engines[idx]->mode->parameters[i],
1713 value);
1714 hkl_parameter_set_value_unit(&_diffractometer->engines_w->engines[idx]->mode->parameters[i],
1715 value);
1716 hkl_parameter_set_value_unit(&_diffractometer->engines_r_real->engines[idx]->mode->parameters[i],
1717 value);
1718 hkl_parameter_set_value_unit(&_diffractometer->engines_w_real->engines[idx]->mode->parameters[i],
1719 value);
1723 void TangoHKLAdapter::pseudo_axes_init(size_t idx)
1725 omni_mutex_lock lock(_lock);
1727 HklPseudoAxisEngine *engine_r = _diffractometer->engines_r->engines[idx];
1728 HklPseudoAxisEngine *engine_w = _diffractometer->engines_w->engines[idx];
1729 HklPseudoAxisEngine *engine_r_real = _diffractometer->engines_r_real->engines[idx];
1730 HklPseudoAxisEngine *engine_w_real = _diffractometer->engines_w_real->engines[idx];
1732 hkl_pseudo_axis_engine_initialize(engine_r);
1733 hkl_pseudo_axis_engine_initialize(engine_w);
1734 hkl_pseudo_axis_engine_initialize(engine_r_real);
1735 hkl_pseudo_axis_engine_initialize(engine_w_real);
1738 void TangoHKLAdapter::pseudo_axes_add_dynamic_attributes(size_t idx)
1740 //omni_mutex_lock lock(_lock);
1742 size_t i, j;
1744 // check if all the PseudoAxes were instantiated
1745 for(i=0; i<_pseudoAxesAdapters.size(); ++i)
1746 if(!_pseudoAxesAdapters[i]->_device)
1747 return;
1750 * we need to attach the dynamic attributes after all instance of
1751 * the PseudoAxes devices were started. otherwise it cause problem.
1752 * only add the attributs if they were not already added.
1754 for(i=0; i<_pseudoAxesAdapters.size(); ++i){
1755 PseudoAxesAdapter *adapter = _pseudoAxesAdapters[i];
1756 Tango::MultiAttribute *multiattribute = adapter->_device->get_device_attr();
1758 for(j=0; j<adapter->_dynamic_attribute_pseudo_axes_axis.size(); ++j){
1759 try{
1760 multiattribute->get_attr_by_name(adapter->get_pseudo_axis_names().data[j]);
1761 }catch (Tango::DevFailed){
1762 adapter->_device->add_attribute(adapter->_dynamic_attribute_pseudo_axes_axis[j]);
1768 void TangoHKLAdapter::pseudo_axes_remove_dynamic_attributes(size_t idx)
1770 size_t i;
1771 PseudoAxesAdapter *adapter;
1773 adapter = _pseudoAxesAdapters[idx];
1774 if(adapter->_device){
1775 for(i=0; i<adapter->_dynamic_attribute_pseudo_axes_axis.size(); ++i)
1776 adapter->_device->remove_attribute(adapter->_dynamic_attribute_pseudo_axes_axis[i], false);
1777 adapter->_device = NULL;
1781 void TangoHKLAdapter::pseudo_axes_create_and_start_devices(void)
1783 omni_mutex_lock lock(_lock);
1785 unsigned int i, j;
1787 Tango::Util *tg = Tango::Util::instance();
1788 Tango::Database *db = tg->get_database();
1789 for(i=0; i<_pseudoAxesAdapters.size(); ++i){
1790 std::string dev_name = _pseudoAxesAdapters[i]->get_proxy_name();
1792 // first check if the device is already defined in the database
1793 try{
1794 Tango::DbDevImportInfo my_device_import_info;
1796 my_device_import_info = db->import_device(dev_name);
1797 } catch (Tango::DevFailed &) {
1798 Tango::DbDevInfo my_device_info;
1800 // add the device to the database
1801 my_device_info.name = dev_name.c_str();
1802 my_device_info._class = "PseudoAxes";
1803 my_device_info.server = tg->get_ds_name().c_str();
1805 db->add_device(my_device_info);
1807 // add the right properties to that device
1808 Tango::DbDatum DiffractometerProxy("DiffractometerProxy"), EngineName("EngineName");
1809 Tango::DbData properties;
1810 DiffractometerProxy << _device->name();
1811 EngineName << _pseudoAxesAdapters[i]->get_name();
1812 properties.push_back(DiffractometerProxy);
1813 properties.push_back(EngineName);
1814 db->put_device_property(dev_name,properties);
1817 // now start the device
1818 const std::vector<Tango::DeviceClass *> *cl_list = tg->get_class_list();
1819 for(j=0; j<cl_list->size(); ++j){
1820 if((*cl_list)[j]->get_name() == "PseudoAxes"){
1821 try{
1822 Tango::DevVarStringArray na;
1823 na.length(1);
1824 na[0] = dev_name.c_str();
1825 (*cl_list)[j]->device_factory(&na);
1826 std::cout << "Started " << dev_name << std::endl;
1827 break;
1829 catch (Tango::DevFailed &e)
1838 Tango::DevBoolean TangoHKLAdapter::pseudo_axes_get_initialized(size_t idx)
1840 omni_mutex_lock lock(_lock);
1842 if(!_diffractometer->engines_r->engines[idx]->mode->initialize)
1843 return true;
1846 void TangoHKLAdapter::pseudo_axes_set_initialized(size_t idx, bool initialized)
1848 if(initialized){
1849 this->update();
1851 omni_mutex_lock lock(_lock);
1853 HklPseudoAxisEngine *engine_r = _diffractometer->engines_r->engines[idx];
1854 HklPseudoAxisEngine *engine_w = _diffractometer->engines_w->engines[idx];
1855 HklPseudoAxisEngine *engine_r_real = _diffractometer->engines_r_real->engines[idx];
1856 HklPseudoAxisEngine *engine_w_real = _diffractometer->engines_w_real->engines[idx];
1858 hkl_pseudo_axis_engine_initialize(engine_r);
1859 hkl_pseudo_axis_engine_initialize(engine_w);
1860 hkl_pseudo_axis_engine_initialize(engine_r_real);
1861 hkl_pseudo_axis_engine_initialize(engine_w_real);
1865 /**********************/
1866 /* Dynamic attributes */
1867 /**********************/
1869 void TangoHKLAdapter::create_axes_dynamic_attributes(void)
1871 size_t i;
1872 size_t len = _axes.size();
1873 _dynamic_attribute_axes_names.resize(len, 1);
1874 for(i=0; i<len; ++i){
1875 std::string name;
1876 AxisAttrib *att;
1877 size_t l;
1879 // compute the diffractometer axis names
1880 name = "Axis";
1881 l = name.size();
1882 name += _axes[i].get_name();
1883 name[l] = toupper(name[l]);
1885 // create the AxisAttrib to deal with the proxy connection.
1886 att = new AxisAttrib(name.c_str(), _axes[i]);
1887 _dynamic_attribute_axes.push_back(att);
1888 _dynamic_attribute_axes_names.data[i] = const_cast<char *>(att->get_name().c_str());
1892 void TangoHKLAdapter::destroy_axes_dynamic_attributes(void)
1894 size_t i;
1895 size_t len = _dynamic_attribute_axes.size();
1897 for(i=0; i<len; ++i)
1898 delete _dynamic_attribute_axes[i];
1901 void TangoHKLAdapter::attach_dynamic_attributes_to_device(void)
1903 size_t i;
1905 for(i=0; i<_dynamic_attribute_axes.size(); ++i)
1906 _device->add_attribute(_dynamic_attribute_axes[i]);
1910 void TangoHKLAdapter::detach_dynamic_attributes_from_device(void)
1912 size_t i;
1914 for(i=0; i<_dynamic_attribute_axes.size(); ++i)
1915 _device->remove_attribute(_dynamic_attribute_axes[i], false);
1919 bool TangoHKLAdapter::get_auto_update_from_proxies(void)
1921 omni_mutex_lock lock(_lock);
1923 return _auto_update_from_proxies;
1926 void TangoHKLAdapter::set_auto_update_from_proxies(bool update)
1928 bool old = _auto_update_from_proxies;
1929 _auto_update_from_proxies = update;
1930 if(old = false && update == true)
1931 this->update();
1934 } // namespace
1936 std::string hkl_axes_consign_as_string(HklAxis const **axes, size_t axes_len)
1938 size_t i;
1939 std::string out;
1941 std::ostringstream line, tmp;
1942 for(i=0; i<axes_len; ++i) {
1943 HklParameter const *axis = (HklParameter const *)axes[i];
1944 double value = hkl_parameter_get_value_unit(axis);
1946 out += " \"";
1947 out += axis->name;
1948 out + "\" ";
1949 std::ostringstream tmp;
1950 tmp << showpos;
1951 tmp << value << "°";
1952 out += tmp.str();
1955 return out;