* remove the implementation of the previous command and attribut.
[diffractometer.git] / src / TangoHKLAdapter.cpp
blob038ea81293b3f648a00c152f5831b621a01af471
1 #if ( _MSC_VER && _MSC_VER <= 1200 )
2 // Ce pragma ne devrait pas etre dans ce fichier car le warning ne s'affiche
3 // que si l'on compile une version DEBUG de la librairie.
4 // Il faut utiliser l'option de compilation \wd4786 mais elle n'est presente
5 // qu'à partir de VC++7
6 # pragma warning (disable : 4786)
7 #endif
9 #include <iomanip>
11 #include <hkl/hkl-pseudoaxis.h>
13 #include "macros.h"
14 #include "TangoHKLAdapter.h"
15 #include "Diffractometer.h"
16 #include "PseudoAxes.h"
17 #include "AxisAdapter.h"
18 #include "AxisAttrib.h"
19 #include "PseudoAxesAttrib.h"
21 //#define DEBUG
22 #ifndef NDEBUG
23 # define STDOUT(stream) std::cout << stream
24 #else
25 # define STDOUT(stream) {};
26 #endif
28 namespace Diffractometer_ns
30 //+----------------------------------------------------------------------------
32 // method : TangoHKLAdapter::TangoHKLAdapter(string &s)
34 // description : constructor for the adapter between HKl library and Tango
36 // in : - type : Type of diffractometer to instancate
38 //-----------------------------------------------------------------------------
39 TangoHKLAdapter::TangoHKLAdapter(Diffractometer *device, HklGeometryType type) :
40 _device(device),
41 _type(type)
43 size_t i, len;
44 HklAxis *axes_r;
45 HklAxis *axes_w;
46 HklAxis *axes_r_real;
47 HklAxis *axes_w_real;
49 this->ready = false;
50 this->simulated = true;
51 _lambdaAttributeProxy = NULL;
52 _wrong_nb_of_axis_proxies = false;
53 _ux = 0;
54 _uy = 0;
55 _uz = 0;
56 _angles_idx = 0;
58 duration.Start();
60 // Create the hkl part
61 _diffractometer = new HklDiffractometer;
62 _diffractometer->geometry_r = hkl_geometry_factory_new(type, 50 * HKL_DEGTORAD);
63 _diffractometer->geometry_w = hkl_geometry_factory_new(type, 50 * HKL_DEGTORAD);
64 _diffractometer->geometry_r_real = hkl_geometry_factory_new(type, 50 * HKL_DEGTORAD);
65 _diffractometer->geometry_w_real = hkl_geometry_factory_new(type, 50 * HKL_DEGTORAD);
66 _diffractometer->detector.idx = 1;
67 _diffractometer->detector_real.idx = 1;
68 _diffractometer->samples = hkl_sample_list_new();
69 _diffractometer->engines_r = hkl_pseudo_axis_engine_list_factory(type);
70 _diffractometer->engines_w = hkl_pseudo_axis_engine_list_factory(type);
71 _diffractometer->engines_r_real = hkl_pseudo_axis_engine_list_factory(type);
72 _diffractometer->engines_w_real = hkl_pseudo_axis_engine_list_factory(type);
74 // Build Group
75 Tango::GroupReply::enable_exception(true);
76 _proxies = new Tango::Group("Axis");
78 // fill the axisAdapter.
79 len = HKL_LIST_LEN(_diffractometer->geometry_r->axes);
80 axes_r = _diffractometer->geometry_r->axes;
81 axes_w = _diffractometer->geometry_w->axes;
82 axes_r_real = _diffractometer->geometry_r_real->axes;
83 axes_w_real = _diffractometer->geometry_w_real->axes;
84 for(i=0; i<len; ++i)
85 _axes.push_back(AxisAdapter(this, &axes_r[i], &axes_w[i], &axes_r_real[i], &axes_w_real[i]));
87 // hack to connect all axes the first time
88 this->simulated = false;
89 this->connect_all_proxies();
90 this->simulated = true;
92 // fill the pseudoAxesAdapters
94 omni_mutex_lock lock(_lock);
96 len = HKL_LIST_LEN(_diffractometer->engines_r->engines);
97 _pseudo_axes_proxies.resize(len, 1);
98 for(i=0; i<len; ++i){
99 PseudoAxesAdapter *adapter;
101 adapter = new PseudoAxesAdapter(this, i);
102 _pseudoAxesAdapters.push_back(adapter);
103 _pseudo_axes_proxies.data[i] = const_cast<char *>(adapter->_proxy_name.c_str());
107 // create the dynamic attributes
108 this->create_axes_dynamic_attributes();
110 // set the default lambda
111 this->set_lambda(1.54);
114 TangoHKLAdapter::~TangoHKLAdapter(void)
116 unsigned int i;
118 // remove all pseudo axis adapters
119 for(i=0;i<_pseudoAxisAdapters.size();i++)
120 delete _pseudoAxisAdapters[i];
122 // remove all pseudo axes adapters;
123 for(i=0; i<_pseudoAxesAdapters.size(); ++i)
124 delete _pseudoAxesAdapters[i];
126 // remove all axisAdapter
127 _axes.clear();
129 if(_proxies) {
130 _proxies->remove_all();
131 delete _proxies;
132 _proxies = NULL;
135 if (_lambdaAttributeProxy)
136 delete _lambdaAttributeProxy;
138 // remove the hkl part
139 hkl_geometry_free(_diffractometer->geometry_r);
140 hkl_geometry_free(_diffractometer->geometry_w);
141 hkl_geometry_free(_diffractometer->geometry_r_real);
142 hkl_geometry_free(_diffractometer->geometry_w_real);
143 hkl_sample_list_free(_diffractometer->samples);
144 hkl_pseudo_axis_engine_list_free(_diffractometer->engines_r);
145 hkl_pseudo_axis_engine_list_free(_diffractometer->engines_w);
146 hkl_pseudo_axis_engine_list_free(_diffractometer->engines_r_real);
147 hkl_pseudo_axis_engine_list_free(_diffractometer->engines_w_real);
149 if(_diffractometer) {
150 delete _diffractometer;
151 _diffractometer = NULL;
155 void TangoHKLAdapter::connect_all_proxies(void)
157 omni_mutex_lock lock(_lock);
159 // connect the lambda proxy
160 if ((!_lambdaAttributeProxy && !this->simulated)
161 && _device->lambdaAttributeProxy != "") {
164 _lambdaAttributeProxy = new Tango::AttributeProxy(_device->lambdaAttributeProxy);
166 catch(...) {
170 // connect the axes proxies
171 if (!this->ready && !this->simulated) {
172 unsigned int nb;
174 nb = _device->realAxisProxies.size();
175 if (nb != _axes.size()) {
176 _wrong_nb_of_axis_proxies = true;
177 return;
178 } else {
179 unsigned int i, j;
180 bool ready = true;
182 for(i=0; i<nb; ++i) {
183 AxisAdapter & axis = _axes[i];
184 if (!axis.is_ready()){
185 // Find axis in the proxy list
186 for(j=0; j<nb; ++j) {
187 char *line = strdup(_device->realAxisProxies[j].c_str());
188 char *last;
189 char *axis_name = strtok_r(line, ":", &last);
190 char *proxy_name = strtok_r(NULL, ":", &last);
191 if (axis.get_name() == axis_name){
192 Tango::Group *group = axis.connect(proxy_name);
193 if(group)
194 _proxies->add(group);
196 free(line);
198 if (!axis.is_ready())
199 ready = false;
202 this->ready = ready;
207 void TangoHKLAdapter::set_lambda(double lambda)
209 omni_mutex_lock lock(_lock);
211 if ((this->simulated || _device->lambdaAttributeProxy == "")
212 && lambda > 0){
213 _lambda = lambda;
214 _diffractometer->geometry_r->source.wave_length = lambda;
215 _diffractometer->geometry_w->source.wave_length = lambda;
216 _diffractometer->geometry_r_real->source.wave_length = lambda;
217 _diffractometer->geometry_w_real->source.wave_length = lambda;
221 void TangoHKLAdapter::update_lambda(void)
223 if (_lambdaAttributeProxy && !this->simulated){
224 try{
225 _lambdaAttributeProxy->read() >> _lambda;
226 _diffractometer->geometry_r->source.wave_length = _lambda;
227 _diffractometer->geometry_w->source.wave_length = _lambda;
228 _diffractometer->geometry_r_real->source.wave_length = _lambda;
229 _diffractometer->geometry_w_real->source.wave_length = _lambda;
231 catch (Tango::DevFailed &){
233 }else
234 _lambda = _diffractometer->geometry_r->source.wave_length;
238 * this method update the angles attribut from the engines->geometry list
240 void TangoHKLAdapter::update_angles(void)
242 size_t i, j;
243 size_t xdim;
244 size_t ydim;
245 HklPseudoAxisEngine *engine;
246 double *data;
247 HklGeometry **geometries;
249 if(this->simulated)
250 engine = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_w, "hkl");
251 else
252 engine = hkl_pseudo_axis_engine_list_get_by_name(_diffractometer->engines_w_real, "hkl");
254 // update the computed_angles part
255 xdim = 1 + HKL_LIST_LEN(_diffractometer->geometry_r->axes);
256 ydim = HKL_LIST_LEN(engine->engines->geometries->geometries);
258 _angles.resize(xdim, ydim);
259 _angles.clear();
261 //fill the array
262 data = _angles.data;
263 geometries = engine->engines->geometries->geometries;
264 for(j=0; j<ydim; ++j){
265 HklGeometry *geom = geometries[j];
267 data[0] = j;
268 for(i=1; i<xdim; ++i)
269 data[i] = hkl_axis_get_value_unit(&geom->axes[i-1]);
270 data += xdim;
275 * this method update the reflections_angles when we change a sample parameter
277 void TangoHKLAdapter::update_reflections_angles(void)
279 HklSample *sample = _diffractometer->samples->current;
280 if (sample) {
281 unsigned int i, j;
282 size_t rdim;
283 double *data;
285 // the reflection Angles
286 rdim = HKL_LIST_LEN(sample->reflections);
287 _reflections_angles.resize(rdim, rdim);
288 _reflections_angles.clear();
290 data = _reflections_angles.data;
291 for(i=0; i<rdim; ++i) {
292 for(j=0; j<rdim; ++j) {
293 double angle = 0.;
294 if (j < i)
295 angle = hkl_sample_get_reflection_theoretical_angle(sample, i, j);
296 else if (j > i)
297 angle = hkl_sample_get_reflection_mesured_angle(sample, i, j);
299 *data = angle * HKL_RADTODEG;
300 data++;
306 void TangoHKLAdapter::update_reflections(void)
308 HklSample *sample = _diffractometer->samples->current;
309 if (sample) {
311 // Allocation of the image
312 unsigned int xdim = 6 + HKL_LIST_LEN(_diffractometer->geometry_r->axes);
313 unsigned int ydim = HKL_LIST_LEN(sample->reflections);
314 _reflections.resize(xdim, ydim);
316 size_t i = 0;
317 double *data = _reflections.data;
318 for(i=0; i<ydim; ++i) {
319 HklSampleReflection *r;
321 r = hkl_sample_get_ith_reflection(sample, i);
322 if (r) {
323 size_t k;
324 HklAxis *axes = r->geometry->axes;
326 data[0] = i;
327 data[1] = r->hkl.data[0];
328 data[2] = r->hkl.data[1];
329 data[3] = r->hkl.data[2];
330 data[4] = 0;
331 data[5] = (double)r->flag;
333 for(k=0; k<HKL_LIST_LEN(r->geometry->axes); ++k)
334 data[6 + k] = hkl_axis_get_value_unit(&axes[k]);
336 data += xdim;
341 void TangoHKLAdapter::update_ub(void)
343 HklSample const *sample = _diffractometer->samples->current;
344 if(sample){
345 size_t dim = 3;
346 _ub.resize(dim, dim);
347 _ub.set_data_from_buffer(&(sample->UB.data[0][0]), dim, dim);
351 void TangoHKLAdapter::update_ux_uy_uz(void)
353 HklSample *sample = _diffractometer->samples->current;
355 if(sample){
356 hkl_matrix_to_euler(&sample->U, &_ux, &_uy, &_uz);
357 _ux *= HKL_RADTODEG;
358 _uy *= HKL_RADTODEG;
359 _uz *= HKL_RADTODEG;
364 * this method update all the AxisAdapter from the proxy every 200 ms.
365 * this from_proxy get the real part from the proxy and the "sim" part
366 * from the HklAxis in simulated mode or from the proxy in real mode
367 * else it updates them from the HklAxis.
369 * every 200 ms
370 * simulated:
371 * real <- proxy
372 * sim <- HklAxis
373 * non simulated:
374 * real <- proxy
375 * sim <- proxy
376 * rest of the time
377 * real <- HklAxis
378 * simulated -> HklAxis
380 void TangoHKLAdapter::update_axis_adapters(void)
382 size_t i;
384 // first read from the proxy.
385 duration.Stop();
386 if(duration.GetDurationInMs() >= 200 && _proxies) {
387 for(size_t i=0; i<_axes.size(); ++i)
388 _axes[i].from_proxy(this->simulated);
389 duration.Start();
390 }else
391 for(i=0; i<_axes.size(); ++i)
392 _axes[i].from_HklAxis();
395 void TangoHKLAdapter::update_hkl_from_axis_adapters(void)
397 size_t i;
399 // set the axis
400 for(i=0; i<_axes.size(); ++i)
401 _axes[i].to_HklAxis();
403 // update the pseudo axes
404 if(_diffractometer && _diffractometer->samples){
405 hkl_pseudo_axis_engine_list_getter(_diffractometer->engines_r, _diffractometer->geometry_r,
406 &_diffractometer->detector, _diffractometer->samples->current);
407 hkl_pseudo_axis_engine_list_getter(_diffractometer->engines_w, _diffractometer->geometry_w,
408 &_diffractometer->detector, _diffractometer->samples->current);
409 hkl_pseudo_axis_engine_list_getter(_diffractometer->engines_r_real, _diffractometer->geometry_r_real,
410 &_diffractometer->detector_real, _diffractometer->samples->current);
411 hkl_pseudo_axis_engine_list_getter(_diffractometer->engines_w_real, _diffractometer->geometry_w_real,
412 &_diffractometer->detector_real, _diffractometer->samples->current);
416 void TangoHKLAdapter::update_pseudo_axis_adapters_from_hkl(void)
418 for(size_t i=0;i<_pseudoAxisAdapters.size();++i)
419 _pseudoAxisAdapters[i]->update();
422 void TangoHKLAdapter::update_proxies_from_axis_adapters(void)
424 _proxies->command_inout(AXIS_COMMAND_STOP_NAME);
425 for(size_t i=0; i<_axes.size(); ++i)
426 _axes[i].to_proxy();
429 void TangoHKLAdapter::update_proxies_from_pseudo_axis_adapters(PseudoAxisAdapter *adapter)
431 adapter->to_proxies();
434 void TangoHKLAdapter::update_pseudo_axes_adapters_from_hkl(void)
436 size_t i, j, len;
437 HklPseudoAxisEngine *engine_r, *engine_w;
439 for(i=0; i<_pseudoAxesAdapters.size(); ++i){
440 PseudoAxesAdapter *adapter;
442 adapter = _pseudoAxesAdapters[i];
443 engine_r = _diffractometer->engines_r->engines[i];
444 engine_w = _diffractometer->engines_w->engines[i];
445 len = HKL_LIST_LEN(engine_r->pseudoAxes);
446 for(j=0; j<len; ++j){
447 adapter->_read.data[j] = hkl_parameter_get_value_unit((HklParameter *)engine_r->pseudoAxes[j]);
448 adapter->_write.data[j] = hkl_parameter_get_value_unit((HklParameter *)engine_w->pseudoAxes[j]);
452 adapter->update_state_and_status_i();
456 void TangoHKLAdapter::update_state_and_status(void)
458 Tango::DevState state;
459 std::string status;
460 std::string extra_status;
462 state = Tango::STANDBY;
463 if (this->simulated)
464 status = "Simulated Mode: Motors will NOT move.";
465 else {
466 status = "REAL Mode : Motors will REALLY move.";
468 if (!this->ready) {
469 state = Tango::FAULT;
470 extra_status += "\nCan not connect to axes proxies";
471 // update the monochromator proxy status.
472 if (!_lambdaAttributeProxy && !this->simulated) {
473 extra_status += "\nCan not connect to the lambdaAttributeProxy";
474 extra_status += "\nCheck also the lambdaAttributeProxy property";
476 } else {
477 try {
478 for(unsigned int i=0; i<_axes.size(); ++i) {
479 AxisAdapter const & axis = _axes[i];
480 std::string const & device_name = axis.get_device_name();
481 Tango::DevState tmpState = axis.get_state();
483 ::compose_state(state, tmpState);
484 if (tmpState != Tango::STANDBY)
485 extra_status += "\n" + device_name + " is in " + Tango::DevStateName[tmpState];
487 } catch(...)
489 state = Tango::FAULT;
490 extra_status += "\nCan not connect to axes proxies";
496 if (_diffractometer){
497 status += "\nSample: ";
498 if(!_diffractometer->samples->current){
499 status += "Not yet Set";
500 state = Tango::FAULT;
501 } else
502 status += _diffractometer->samples->current->name;
503 if (state == Tango::STANDBY)
504 extra_status += "\nready to compute hkl";
505 }else{
506 state = Tango::FAULT;
507 extra_status += "\nhkl core not yet initialized !!!";
509 status += "\nDiffractometer status: ";
510 status += Tango::DevStateName[state];
511 status += extra_status;
513 _diffractometerConfig.state = state;
514 _diffractometerConfig.status = status;
517 void TangoHKLAdapter::update(void)
519 /**********************************************
520 * CRITICAL SECTION
521 **********************************************/
522 omni_mutex_lock lock(_lock);
524 this->update_lambda();
525 this->update_axis_adapters();
526 this->update_hkl_from_axis_adapters();
527 this->update_pseudo_axis_adapters_from_hkl();
528 this->update_pseudo_axes_adapters_from_hkl();
529 this->update_state_and_status();
530 /**********************************************
531 * END OF CRITICAL SECTION
532 **********************************************/
535 /********************/
536 /* State and status */
537 /********************/
538 void TangoHKLAdapter::get_diffractometer_config(DiffractometerConfig & config)
540 omni_mutex_lock lock(_lock);
542 config = _diffractometerConfig;
545 /************/
546 /* hkl part */
547 /************/
549 short & TangoHKLAdapter::get_angles_idx(void)
551 omni_mutex_lock lock(_lock);
553 return _angles_idx;
556 void TangoHKLAdapter::set_angles_idx(short idx)
558 omni_mutex_lock lock(_lock);
560 // A REVOIR
561 if(idx >= 0 && idx < (int)_angles.ydim){
562 size_t i;
563 double *values;
565 _angles_idx = idx;
566 values = &_angles.data[1 + idx * _angles.xdim];
567 for(i=0; i<_axes.size(); ++i)
568 this->write_axis_i(_axes[i], values[i]);
572 void TangoHKLAdapter::load(void)
574 this->load_1();
577 void TangoHKLAdapter::load_1(void)
579 unsigned long nb_properties;
581 // Get the Crystal Attributes properties.
582 Tango::DbData properties;
583 properties.push_back(Tango::DbDatum("Crystal"));
584 _device->get_db_device()->get_attribute_property(properties);
586 // the first one is the number of properties
587 properties[0] >> nb_properties;
589 if (nb_properties > 1) {
590 unsigned long i, j;
591 HklGeometry *geometry;
592 HklDetector detector;
594 geometry = hkl_geometry_new_copy(_diffractometer->geometry_r);
596 hkl_sample_list_clear(_diffractometer->samples);
597 for(i=1; i<=nb_properties; ++i) {
598 // skip the _ver property
599 if(!strcasecmp("_ver", properties[i].name.c_str()))
600 continue;
602 HklSample * sample;
604 // The name of the property name is the name of a crystal.
605 sample = hkl_sample_new(properties[i].name.c_str(), HKL_SAMPLE_MONOCRYSTAL);
607 // Extract the lines store in the property
608 std::vector<std::string> lines;
609 properties[i] >> lines;
611 for(j=0; j<lines.size(); j++) {
612 char *line = strdup(lines[j].c_str());
613 char *last;
614 char *key = strtok_r(line, "=", &last);
616 if (!strcmp(key,"lattice")) {
617 double a = atof(strtok_r(NULL, ";", &last));
618 double b = atof(strtok_r(NULL, ";", &last));
619 double c = atof(strtok_r(NULL, ";", &last));
620 double alpha = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
621 double beta = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
622 double gamma = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
623 int a_flag = atoi(strtok_r(NULL, ";", &last));
624 int b_flag = atoi(strtok_r(NULL, ";", &last));
625 int c_flag = atoi(strtok_r(NULL, ";", &last));
626 int alpha_flag = atoi(strtok_r(NULL, ";", &last));
627 int beta_flag = atoi(strtok_r(NULL, ";", &last));
628 int gamma_flag = atoi(strtok_r(NULL, ";", &last));
629 hkl_sample_set_lattice(sample, a, b, c, alpha, beta, gamma);
630 sample->lattice->a->not_to_fit = !a_flag;
631 sample->lattice->b->not_to_fit = !b_flag;
632 sample->lattice->c->not_to_fit = !c_flag;
633 sample->lattice->alpha->not_to_fit = !alpha_flag;
634 sample->lattice->beta->not_to_fit = !beta_flag;
635 sample->lattice->gamma->not_to_fit = !gamma_flag;
636 } else if (!strcmp(key, "uxuyuz")){
637 double ux = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
638 double uy = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
639 double uz = atof(strtok_r(NULL, ";", &last)) * HKL_DEGTORAD;
640 hkl_sample_set_U_from_euler(sample, ux, uy, uz);
641 } else if (!strcmp(key,"reflection")) {
642 unsigned int idx = 0;
643 HklSampleReflection *reflection;
645 double wavelength = atof(strtok_r(NULL, ";", &last));
646 double h = atof(strtok_r(NULL, ";", &last));
647 double k = atof(strtok_r(NULL, ";", &last));
648 double l = atof(strtok_r(NULL, ";", &last));
649 int flag = atoi(strtok_r(NULL, ";", &last));
651 // first set the geometry axes
652 while(key = strtok_r(NULL, ";", &last))
653 hkl_axis_set_value_unit(&geometry->axes[idx++], atof(key));
654 geometry->source.wave_length = wavelength;
655 detector = _diffractometer->detector;
657 reflection = hkl_sample_add_reflection(sample, geometry, &detector, h, k, l);
658 reflection->flag = flag;
660 free(line);
661 // End of key research
662 }// End for each parameters
663 hkl_sample_list_append(_diffractometer->samples, sample);
664 }// End for each property
666 hkl_geometry_free(geometry);
668 //_device->refresh_crystal_parameters();
672 void TangoHKLAdapter::save(void)
674 omni_mutex_lock lock(_lock);
676 size_t i, j, k;
677 size_t len;
678 Tango::DbData crystal_prop;
679 Tango::DbData data_put;
681 // Step 1 : clean all properties
682 // FP Le mieux serait sans doute de ne pas effacer les propriétés d'attribut
683 // avant d'avoir crée correctement un data_put.
684 crystal_prop.push_back(Tango::DbDatum("Crystal"));
685 _device->get_db_device()->get_attribute_property(crystal_prop);
686 long number_of_prop = 0;
687 crystal_prop[0] >> number_of_prop ;
688 if( number_of_prop > 0)
689 _device->get_db_device()->delete_attribute_property(crystal_prop);
691 // Step 2 : create the Crystal properties
692 Tango::DbDatum properties("Crystal");
693 // Put number of properties (= nb of samples + 1)
694 len = hkl_sample_list_len(_diffractometer->samples);
695 properties << (long)(len + 1);
696 data_put.push_back(properties);
698 // first property is the format version
699 Tango::DbDatum version("_ver");
700 version << (long)FORMAT_VERSION;
701 data_put.push_back(version);
703 // now each sample
704 for(k=0; k<len; ++k){
705 HklSample *sample;
706 std::vector<std::string> lines;
707 char line[256];
709 // the lattices values
710 sample = hkl_sample_list_get_ith(_diffractometer->samples, k);
711 double a = hkl_parameter_get_value_unit(sample->lattice->a);
712 double b = hkl_parameter_get_value_unit(sample->lattice->b);
713 double c = hkl_parameter_get_value_unit(sample->lattice->c);
714 double alpha = hkl_parameter_get_value_unit(sample->lattice->alpha);
715 double beta = hkl_parameter_get_value_unit(sample->lattice->beta);
716 double gamma = hkl_parameter_get_value_unit(sample->lattice->gamma);
717 // the fit flag
718 int a_flag = !sample->lattice->a->not_to_fit;
719 int b_flag = !sample->lattice->b->not_to_fit;
720 int c_flag = !sample->lattice->c->not_to_fit;
721 int alpha_flag = !sample->lattice->alpha->not_to_fit;
722 int beta_flag = !sample->lattice->beta->not_to_fit;
723 int gamma_flag = !sample->lattice->gamma->not_to_fit;
725 snprintf(line, 255, "lattice=%f;%f;%f;%f;%f;%f;%d;%d;%d;%d;%d;%d",
726 a, b, c, alpha, beta, gamma,
727 a_flag, b_flag, c_flag, alpha_flag, beta_flag, gamma_flag);
728 lines.push_back(line);
730 // the UxUyUz parameters
731 double ux, uy, uz;
732 hkl_matrix_to_euler(&sample->U, &ux, &uy, &uz);
733 ux *= HKL_RADTODEG;
734 uy *= HKL_RADTODEG;
735 uz *= HKL_RADTODEG;
737 snprintf(line, 255, "uxuyuz=%f;%f;%f", ux, uy, uz);
738 lines.push_back(line);
740 // the reflections
741 for(i=0; i<HKL_LIST_LEN(sample->reflections); ++i) {
742 HklSampleReflection *reflection;
744 reflection = hkl_sample_get_ith_reflection(sample, i);
745 double wavelength = reflection->geometry->source.wave_length;
746 double h = reflection->hkl.data[0];
747 double k = reflection->hkl.data[1];
748 double l = reflection->hkl.data[2];
749 int flag = reflection->flag;
751 snprintf(line, 255, "reflection=%f;%f;%f;%f;%d",
752 wavelength, h, k, l, flag);
753 // Extract values of each axes
754 for(j=0; j<HKL_LIST_LEN(reflection->geometry->axes); ++j) {
755 char pos[256];
756 double rad = hkl_axis_get_value_unit(&reflection->geometry->axes[j]);
757 snprintf(pos, 255, ";%f", rad);
758 strncat(line, pos, 255);
760 lines.push_back(line);
763 // Try to create property
764 // Get crystal name
765 Tango::DbDatum property(sample->name);
766 property << lines;
767 data_put.push_back(property);
770 //update database for this property
771 _device->get_db_device()->put_attribute_property(data_put);
774 /***************/
775 /* sample part */
776 /***************/
778 char const *TangoHKLAdapter::get_sample_name(void)
780 omni_mutex_lock lock(_lock);
782 HklSample *sample = _diffractometer->samples->current;
783 if(sample)
784 return sample->name;
785 else
786 return "";
789 void TangoHKLAdapter::set_current_sample(char const * name)
791 omni_mutex_lock lock(_lock);
793 HklSample *last;
795 last = _diffractometer->samples->current;
796 if (HKL_SUCCESS == hkl_sample_list_select_current(_diffractometer->samples, name))
797 if (last != _diffractometer->samples->current){
798 this->update_ub();
799 this->update_ux_uy_uz();
800 this->update_reflections_angles();
801 this->update_reflections();
802 this->update_state_and_status();
806 void TangoHKLAdapter::get_sample_lattices(double *a, double *b, double *c,
807 double *alpha, double *beta, double *gamma,
808 double *a_star, double *b_star, double *c_star,
809 double *alpha_star, double *beta_star, double *gamma_star)
811 omni_mutex_lock lock(_lock);
813 HklSample * sample = _diffractometer->samples->current;
814 if (!sample)
815 return;
817 HklLattice const *lattice = sample->lattice;
818 HklLattice *reciprocal = hkl_lattice_new_copy(lattice);
820 hkl_lattice_reciprocal(lattice, reciprocal);
822 // direct space
823 *a = hkl_parameter_get_value_unit(lattice->a);
824 *b = hkl_parameter_get_value_unit(lattice->b);
825 *c = hkl_parameter_get_value_unit(lattice->c);
826 *alpha = hkl_parameter_get_value_unit(lattice->alpha);
827 *beta = hkl_parameter_get_value_unit(lattice->beta);
828 *gamma = hkl_parameter_get_value_unit(lattice->gamma);
830 // reciprocal space
831 *a_star = hkl_parameter_get_value_unit(reciprocal->a);
832 *b_star = hkl_parameter_get_value_unit(reciprocal->b);
833 *c_star = hkl_parameter_get_value_unit(reciprocal->c);
834 *alpha_star = hkl_parameter_get_value_unit(reciprocal->alpha);
835 *beta_star = hkl_parameter_get_value_unit(reciprocal->beta);
836 *gamma_star = hkl_parameter_get_value_unit(reciprocal->gamma);
838 hkl_lattice_free(reciprocal);
841 void TangoHKLAdapter::set_sample_Ux(double ux)
843 HklSample *sample;
845 sample = _diffractometer->samples->current;
846 if (sample){
847 if (HKL_SUCCESS == hkl_sample_set_U_from_euler(sample,
848 ux * HKL_DEGTORAD,
849 _uy * HKL_DEGTORAD,
850 _uz * HKL_DEGTORAD)){
851 _ux = ux;
852 this->update_ub();
853 }else
854 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this Ux value",
855 "Set a correct value");
859 void TangoHKLAdapter::set_sample_Uy(double uy)
861 HklSample *sample;
863 sample = _diffractometer->samples->current;
864 if (sample){
865 if (HKL_SUCCESS == hkl_sample_set_U_from_euler(sample,
866 _ux * HKL_DEGTORAD,
867 uy * HKL_DEGTORAD,
868 _uz * HKL_DEGTORAD)){
869 _uy = uy;
870 this->update_ub();
871 }else
872 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this Uy value",
873 "Set a correct value");
877 void TangoHKLAdapter::set_sample_Uz(double uz)
879 HklSample *sample;
881 sample = _diffractometer->samples->current;
882 if (sample){
883 if (HKL_SUCCESS == hkl_sample_set_U_from_euler(sample,
884 _ux * HKL_DEGTORAD,
885 _uy * HKL_DEGTORAD,
886 uz * HKL_DEGTORAD)){
887 _uz = uz;
888 this->update_ub();
889 }else
890 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this Uz value",
891 "Set a correct value");
895 void TangoHKLAdapter::add_new_sample(std::string const & name)
897 omni_mutex_lock lock(_lock);
899 HklSample *sample = hkl_sample_new(name.c_str(), HKL_SAMPLE_MONOCRYSTAL);
901 if (!hkl_sample_list_append(_diffractometer->samples, sample)){
902 hkl_sample_free(sample);
903 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not add a sample with this name",
904 "A sample with the same name is already present in the sample list");
908 void TangoHKLAdapter::copy_sample_as(Tango::DevString copy_name)
910 omni_mutex_lock lock(_lock);
912 HklSample *sample;
913 HklSample const *current;
915 current = _diffractometer->samples->current;
916 if(!current)
917 TANGO_EXCEPTION_THROW_WITHOUT_LOG("No current sample set",
918 "Please set a current sample");
920 sample = hkl_sample_list_get_by_name(_diffractometer->samples, copy_name);
921 if (sample)
922 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not add a sample with this name",
923 "A sample with the same name is already present in the sample list");
925 sample = hkl_sample_new_copy(current);
926 if(sample){
927 hkl_sample_set_name(sample, copy_name);
928 hkl_sample_list_append(_diffractometer->samples, sample);
932 void TangoHKLAdapter::del_sample(void)
934 omni_mutex_lock lock(_lock);
936 HklSampleList *samples = _diffractometer->samples;
937 hkl_sample_list_del(samples, samples->current);
939 // add a default sample if no more sample in the list
940 if(hkl_sample_list_len(samples) == 0){
941 HklSample *sample = hkl_sample_new("default", HKL_SAMPLE_MONOCRYSTAL);
942 samples->current = hkl_sample_list_append(samples, sample);
943 }else
944 samples->current = hkl_sample_list_get_ith(samples, 0);
945 this->update_ub();
946 this->update_ux_uy_uz();
947 this->update_reflections_angles();
948 this->update_reflections();
951 void TangoHKLAdapter::set_lattice(const Tango::DevVarDoubleArray *argin)
953 omni_mutex_lock lock(_lock);
955 if (argin && argin->length() != 6)
956 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
957 "Did not receive the exact amount of crystal parameters: A, B, C, alpha, beta, gamma");
959 HklSample *sample = _diffractometer->samples->current;
960 if (HKL_FAIL == hkl_sample_set_lattice(sample,
961 (*argin)[0],(*argin)[1], (*argin)[2],
962 (*argin)[3] * HKL_DEGTORAD,
963 (*argin)[4] * HKL_DEGTORAD,
964 (*argin)[5] * HKL_DEGTORAD))
966 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set this lattice combination.",
967 "Please set a good combination");
968 this->update_ub();
969 this->update_reflections_angles();
972 void TangoHKLAdapter::add_reflection(void)
974 omni_mutex_lock lock(_lock);
976 HklSample *sample = _diffractometer->samples->current;
978 if(sample){
979 double h, k, l;
980 HklPseudoAxisEngine *engine;
981 HklSampleReflection *ref;
983 engine = hkl_pseudo_axis_engine_list_get_by_name(
984 _diffractometer->engines_r, "hkl");
986 h = hkl_parameter_get_value_unit((HklParameter *)engine->pseudoAxes[0]);
987 k = hkl_parameter_get_value_unit((HklParameter *)engine->pseudoAxes[1]);
988 l = hkl_parameter_get_value_unit((HklParameter *)engine->pseudoAxes[2]);
990 ref = hkl_sample_add_reflection(sample,
991 _diffractometer->geometry_r,
992 &_diffractometer->detector,
993 h, k, l);
994 if(ref){
995 this->update_reflections_angles();
996 this->update_reflections();
1001 void TangoHKLAdapter::del_reflection(Tango::DevShort argin)
1003 omni_mutex_lock lock(_lock);
1005 if (HKL_FAIL == hkl_sample_del_reflection(_diffractometer->samples->current, argin))
1006 TANGO_EXCEPTION_THROW_WITHOUT_LOG("index out of range",
1007 "change the reflection index");
1008 this->update_reflections_angles();
1009 this->update_reflections();
1012 void TangoHKLAdapter::set_reflections(Matrix<double> const & img)
1014 omni_mutex_lock lock(_lock);
1016 HklSample *sample = _diffractometer->samples->current;
1017 if (sample
1018 && img.xdim == _reflections.xdim
1019 && img.ydim == _reflections.ydim) {
1021 size_t i = 0;
1022 size_t j = 0;
1023 for(i=0; i<HKL_LIST_LEN(sample->reflections); ++i) {
1024 HklSampleReflection *r;
1026 r = hkl_sample_get_ith_reflection(sample, i);
1027 if (r) {
1028 hkl_sample_reflection_set_hkl(r, img.data[j+1], img.data[j+2], img.data[j+3]);
1029 hkl_sample_reflection_set_flag(r, (int)img.data[j+5]);
1031 j += _reflections.xdim;
1033 this->update_reflections();
1034 this->update_reflections_angles();
1038 double TangoHKLAdapter::affine_sample(std::string name)
1040 omni_mutex_lock lock(_lock);
1042 HklSample *sample;
1043 double res = 0.;
1045 sample = hkl_sample_list_get_by_name(_diffractometer->samples, name.c_str());
1046 if(sample){
1047 HklSample *tmp;
1049 // check if the affine sample is already in the HklSampleList
1050 std::string name = sample->name;
1051 name += "(affine)";
1052 tmp = hkl_sample_list_get_by_name(_diffractometer->samples, name.c_str());
1053 hkl_sample_list_del(_diffractometer->samples, tmp);
1055 tmp = hkl_sample_new_copy(sample);
1056 hkl_sample_set_name(tmp, name.c_str());
1057 res = hkl_sample_affine(tmp);
1059 hkl_sample_list_append(_diffractometer->samples, tmp);
1060 _diffractometer->samples->current = tmp;
1062 this->update_ub();
1063 this->update_ux_uy_uz();
1064 this->update_reflections_angles();
1067 return res;
1071 std::vector<std::string> TangoHKLAdapter::get_samples_names(void)
1073 omni_mutex_lock lock(_lock);
1075 std::vector<std::string> names;
1076 size_t i, len;
1077 HklSampleList *samples = _diffractometer->samples;
1079 len = hkl_sample_list_len(samples);
1080 for(i=0; i<len; ++i)
1081 names.push_back(hkl_sample_list_get_ith(samples, i)->name);
1083 return names;
1086 void TangoHKLAdapter::get_sample_parameter_values(Tango::DevVarDoubleStringArray *argout)
1088 omni_mutex_lock lock(_lock);
1090 HklSample *sample;
1091 HklParameter *parameter = NULL;
1092 std::string name;
1094 //check parameters
1095 if (argout->svalue.length() != 1)
1096 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1097 "only one string = parameter name");
1099 sample = _diffractometer->samples->current;
1100 if(sample){
1101 //parameters OK
1102 name = argout->svalue[0];
1103 if(name == "a")
1104 parameter = sample->lattice->a;
1105 else if(name == "b")
1106 parameter = sample->lattice->b;
1107 else if(name == "c")
1108 parameter = sample->lattice->c;
1109 else if(name == "alpha")
1110 parameter = sample->lattice->alpha;
1111 else if(name == "beta")
1112 parameter = sample->lattice->beta;
1113 else if(name == "gamma")
1114 parameter = sample->lattice->gamma;
1116 if (parameter){
1117 argout->dvalue[0] = parameter->range.min;
1118 argout->dvalue[1] = parameter->range.max;
1119 argout->dvalue[2] = !parameter->not_to_fit;
1120 }else
1121 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Wrong parameter name",
1122 "Select: a, b, c, alpha, beta, gamma");
1126 void TangoHKLAdapter::set_sample_parameter_values(Tango::DevVarDoubleStringArray const *argin)
1128 omni_mutex_lock lock(_lock);
1130 HklSample *sample;
1131 HklParameter *parameter = NULL;
1132 std::string name;
1134 // check parameters
1135 if(argin->dvalue.length() != 3)
1136 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1137 "set_crystal_parameter_values did not receive the right amount of scalar parameters: min, max, flag");
1138 if((argin->svalue.length() ) != 1)
1139 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1140 "set_crystal_parameter_values did not receive the right amount of string parameters: parameter name");
1142 // parameters OK
1143 sample = _diffractometer->samples->current;
1144 if(!sample)
1145 TANGO_EXCEPTION_THROW_WITHOUT_LOG("No current sample set",
1146 "Please set a current sample");
1148 name = argin->svalue[0];
1149 if(name == "a")
1150 parameter = sample->lattice->a;
1151 else if(name == "b")
1152 parameter = sample->lattice->b;
1153 else if(name == "c")
1154 parameter = sample->lattice->c;
1155 else if(name == "alpha")
1156 parameter = sample->lattice->alpha;
1157 else if(name == "beta")
1158 parameter = sample->lattice->beta;
1159 else if(name == "gamma")
1160 parameter = sample->lattice->gamma;
1162 if (parameter){
1163 parameter->range.min = argin->dvalue[0];
1164 parameter->range.max = argin->dvalue[1];
1165 parameter->not_to_fit = !argin->dvalue[2];
1166 }else
1167 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Wrong parameter name",
1168 "Select: a, b, c, alpha, beta, gamma");
1169 this->update_ub();
1170 this->update_ux_uy_uz();
1171 this->update_reflections_angles();
1174 void TangoHKLAdapter::compute_u(const Tango::DevVarLongArray *argin)
1176 omni_mutex_lock lock(_lock);
1178 HklSample *sample;
1180 // is parameter ok ?
1181 if (argin->length() != 2)
1182 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Need exactly two reflections indexes",
1183 "use the right number of parameters");
1185 sample = _diffractometer->samples->current;
1186 if (!sample)
1187 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not compute the U matrix without current sample set.",
1188 "Set a current sample");
1190 if (hkl_sample_compute_UB_busing_levy(sample, (*argin)[0], (*argin)[1]))
1191 TANGO_EXCEPTION_THROW_WITHOUT_LOG("can not compute the UB matrix using thoses reflections index",
1192 "Use other reflections");
1193 this->update_ub();
1194 this->update_ux_uy_uz();
1197 /*************/
1198 /* Axis part */
1199 /*************/
1201 void TangoHKLAdapter::read_axis(int idx, double & read, double & write)
1203 omni_mutex_lock lock(_lock);
1205 AxisAdapter & axis = _axes[idx];
1206 read = axis.get_read();
1207 write = axis.get_write();
1210 void TangoHKLAdapter::stop_all_axis(void)
1212 #ifdef WRITE_TO_PROXY_ALLOWED
1213 _proxies->command_inout(AXIS_COMMAND_STOP_NAME, true);
1214 #endif
1217 void TangoHKLAdapter::write_axis(AxisAdapter & axis, double value)
1219 omni_mutex_lock lock(_lock);
1221 this->write_axis_i(axis, value);
1224 void TangoHKLAdapter::write_axis_i(AxisAdapter & axis, double value)
1226 axis._read = axis._write = value;
1227 hkl_axis_set_value_unit(axis._axis_r, value);
1228 hkl_axis_set_value_unit(axis._axis_w, value);
1231 /*******************/
1232 /* pseudoAxis part */
1233 /*******************/
1235 std::vector<std::string> TangoHKLAdapter::pseudo_axis_get_names(void)
1237 omni_mutex_lock lock(_lock);
1239 std::vector<std::string> names;
1240 size_t i, j;
1242 for(i=0; i<HKL_LIST_LEN(_diffractometer->engines_r_real->engines); ++i){
1243 HklPseudoAxisEngine *engine;
1245 engine = _diffractometer->engines_r_real->engines[i];
1246 for(j=0; j<HKL_LIST_LEN(engine->pseudoAxes); ++j)
1247 names.push_back(((HklParameter *)(&engine->pseudoAxes[j]))->name);
1250 return names;
1253 PseudoAxisAdapter *TangoHKLAdapter::pseudo_axis_buffer_new(char const *name)
1255 omni_mutex_lock lock(_lock);
1257 PseudoAxisAdapter * buffer = NULL;
1258 HklPseudoAxis *pseudo_r;
1259 HklPseudoAxis *pseudo_w;
1261 pseudo_r = hkl_pseudo_axis_engine_list_get_pseudo_axis_by_name(
1262 _diffractometer->engines_r_real, name);
1263 pseudo_w = hkl_pseudo_axis_engine_list_get_pseudo_axis_by_name(
1264 _diffractometer->engines_w_real, name);
1266 if(pseudo_r && pseudo_w) {
1269 buffer = new PseudoAxisAdapter(*this, pseudo_r, pseudo_w);
1270 _pseudoAxisAdapters.push_back(buffer);
1272 catch (Tango::DevFailed)
1274 delete buffer;
1275 buffer = NULL;
1278 return buffer;
1281 void TangoHKLAdapter::pseudo_axis_init(PseudoAxisAdapter *buffer, bool init)
1283 omni_mutex_lock lock(_lock);
1285 hkl_pseudo_axis_engine_init(buffer->_pseudo_r->engine, _diffractometer->geometry_r_real,
1286 &_diffractometer->detector_real, _diffractometer->samples->current);
1288 hkl_pseudo_axis_engine_init(buffer->_pseudo_w->engine, _diffractometer->geometry_w_real,
1289 &_diffractometer->detector_real, _diffractometer->samples->current);
1293 void TangoHKLAdapter::pseudo_axis_write(PseudoAxisAdapter * buffer, double value)
1295 omni_mutex_lock lock(_lock);
1297 int res = HKL_FAIL;
1299 HklPseudoAxisEngineList *engines_w_real = _diffractometer->engines_w_real;
1300 HklPseudoAxisEngine *engine = buffer->_pseudo_w->engine;
1301 HklGeometry *geometry_w_real = _diffractometer->geometry_w_real;
1302 HklDetector *detector_real = &_diffractometer->detector_real;
1303 HklSample *sample = _diffractometer->samples->current;
1305 hkl_parameter_set_value_unit((HklParameter *)buffer->_pseudo_w, value);
1306 res = hkl_pseudo_axis_engine_setter(buffer->_pseudo_w->engine, geometry_w_real, detector_real, sample);
1307 //hkl_pseudo_axis_engine_fprintf(stdout, buffer->_pseudo_w->engine);
1308 if (HKL_SUCCESS == res){
1309 hkl_geometry_init_geometry(geometry_w_real, engine->engines->geometries->geometries[0]);
1310 hkl_pseudo_axis_engine_list_getter(engines_w_real, geometry_w_real, detector_real, sample);
1312 _angles_idx = 0;
1313 this->update_angles();
1314 buffer->to_proxies();
1315 this->update_axis_adapters();
1316 this->update_pseudo_axis_adapters_from_hkl();
1317 this->update_pseudo_axes_adapters_from_hkl();
1318 }else
1319 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not write on this pseudo axis",
1320 "Check the sample");
1324 Tango::DevString *TangoHKLAdapter::pseudo_axis_get_mode(PseudoAxisAdapter const *buffer)
1326 omni_mutex_lock lock(_lock);
1328 return const_cast<Tango::DevString *>(&buffer->_pseudo_r->engine->mode->name);
1331 void TangoHKLAdapter::pseudo_axis_set_mode(PseudoAxisAdapter *buffer, Tango::DevString const & mode)
1333 omni_mutex_lock lock(_lock);
1335 size_t i, len;
1337 len = HKL_LIST_LEN(buffer->_pseudo_r->engine->modes);
1338 for(i=0; i<len; ++i)
1339 if(!strcasecmp(mode, buffer->_pseudo_r->engine->modes[i]->name))
1340 break;
1341 if(i<len){
1342 hkl_pseudo_axis_engine_select_mode(buffer->_pseudo_r->engine, i);
1343 hkl_pseudo_axis_engine_select_mode(buffer->_pseudo_w->engine, i);
1347 void TangoHKLAdapter::pseudo_axis_get_mode_parameters(PseudoAxisAdapter *buffer, Tango::DevVarDoubleStringArray *argout)
1349 omni_mutex_lock lock(_lock);
1351 HklPseudoAxisEngine *engine = buffer->_pseudo_r->engine;
1352 if (engine && engine->mode){
1353 size_t i;
1354 size_t len = HKL_LIST_LEN(engine->mode->parameters);
1356 argout->svalue.length(len);
1357 argout->dvalue.length(len);
1358 for(i=0; i<len; ++i){
1359 argout->svalue[i] = CORBA::string_dup(engine->mode->parameters[i].name);
1360 argout->dvalue[i] = hkl_parameter_get_value_unit(&engine->mode->parameters[i]);
1362 }else
1363 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not get the current Mode parameters values without a current mode set.",
1364 "");
1367 void TangoHKLAdapter::pseudo_axis_set_mode_parameters(PseudoAxisAdapter *buffer, const Tango::DevVarDoubleStringArray *argin)
1369 omni_mutex_lock lock(_lock);
1371 if(argin->svalue.length() != argin->dvalue.length())
1372 TANGO_EXCEPTION_THROW_WITHOUT_LOG("DATA_OUT_OF_RANGE",
1373 "set_mode_parameters_values did not receive the same amount between string and double values");
1375 HklPseudoAxisEngine *engine_r = buffer->_pseudo_r->engine;
1376 HklPseudoAxisEngine *engine_w = buffer->_pseudo_w->engine;
1377 if (engine_r && engine_w){
1378 size_t i;
1379 size_t len;
1381 len = argin->svalue.length();
1382 if (HKL_LIST_LEN(engine_r->mode->parameters) != len)
1383 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Not the right number of parameter",
1384 "gives the right number of parameters");
1386 for(i=0; i<len; ++i){
1387 double value = argin->dvalue[i];
1388 char const *name = argin->svalue[i];
1389 if(!strcmp(name, engine_r->mode->parameters[i].name)){
1390 hkl_parameter_set_value_unit(&engine_r->mode->parameters[i], value);
1391 hkl_parameter_set_value_unit(&engine_w->mode->parameters[i], value);
1394 }else
1395 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not set the current Mode parameters values without a current mode set.",
1396 "");
1399 /*******************/
1400 /* pseudoAxes part */
1401 /*******************/
1403 PseudoAxesAdapter *TangoHKLAdapter::pseudo_axes_adapter_get_by_name(std::string const & name)
1405 //omni_mutex_lock lock(_lock);
1407 unsigned int i;
1408 PseudoAxesAdapter *adapter = NULL;
1410 for(i=0; i<_pseudoAxesAdapters.size(); ++i)
1411 if(_pseudoAxesAdapters[i]->get_name() == name){
1412 adapter = _pseudoAxesAdapters[i];
1413 break;
1415 return adapter;
1419 void TangoHKLAdapter::pseudo_axes_write(size_t idx, Matrix<double> const & write)
1421 omni_mutex_lock lock(_lock);
1423 size_t i, len;
1424 int res = HKL_FAIL;
1425 HklPseudoAxisEngineList *engines_r, *engines_w;
1426 HklGeometry *geometry_r, *geometry_w;
1427 HklDetector *detector;
1428 HklSample *sample;
1430 engines_r = _diffractometer->engines_r;
1431 engines_w = _diffractometer->engines_w;
1432 len = HKL_LIST_LEN(engines_w->engines[idx]->pseudoAxes);
1434 geometry_r = _diffractometer->geometry_r;
1435 geometry_w = _diffractometer->geometry_w;
1437 detector = &_diffractometer->detector;
1439 sample = _diffractometer->samples->current;
1441 for(i=0; i<len; ++i)
1442 hkl_parameter_set_value_unit((HklParameter *)(engines_w->engines[idx]->pseudoAxes[i]), write.data[i]);
1444 res = hkl_pseudo_axis_engine_setter(engines_w->engines[idx], geometry_w, detector, sample);
1446 if (HKL_SUCCESS == res){
1447 hkl_geometry_init_geometry(geometry_w, engines_w->geometries->geometries[0]);
1448 hkl_pseudo_axis_engine_list_getter(engines_w, geometry_w, detector, sample);
1449 if(this->simulated){
1450 hkl_geometry_init_geometry(geometry_r, engines_w->geometries->geometries[0]);
1451 hkl_pseudo_axis_engine_list_getter(engines_r, geometry_r, detector, sample);
1454 _angles_idx = 0;
1455 this->update_angles();
1456 this->update_axis_adapters();
1457 this->update_pseudo_axis_adapters_from_hkl();
1458 this->update_pseudo_axes_adapters_from_hkl();
1459 }else
1460 TANGO_EXCEPTION_THROW_WITHOUT_LOG("Can not write on this pseudo axis",
1461 "Check the sample");
1465 Tango::DevString *TangoHKLAdapter::pseudo_axes_get_mode(size_t idx)
1467 omni_mutex_lock lock(_lock);
1469 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1470 if(engine->mode)
1471 return const_cast<Tango::DevString *>(&engine->mode->name);
1472 else
1473 return NULL;
1476 void TangoHKLAdapter::pseudo_axes_set_mode(size_t idx, const Tango::DevString name)
1478 omni_mutex_lock lock(_lock);
1480 size_t i;
1481 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1483 // check if we try to set the same mode than the current one
1484 if (engine->mode)
1485 if(!strcasecmp(name, engine->mode->name))
1486 return;
1488 // no so set the mode if possible
1489 size_t len = HKL_LIST_LEN(engine->modes);
1490 for(i=0; i<len; ++i)
1491 if(!strcasecmp(name, engine->modes[i]->name))
1492 break;
1493 if(i<len){
1494 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_r->engines[idx], i);
1495 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_w->engines[idx], i);
1496 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_r_real->engines[idx], i);
1497 hkl_pseudo_axis_engine_select_mode(_diffractometer->engines_w_real->engines[idx], i);
1498 _pseudoAxesAdapters[idx]->update_axes_i(engine);
1499 _pseudoAxesAdapters[idx]->update_state_and_status_i();
1503 Matrix<char *> & TangoHKLAdapter::pseudo_axes_get_mode_parameters_names(size_t idx)
1505 omni_mutex_lock lock(_lock);
1507 size_t i;
1508 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1509 size_t len = HKL_LIST_LEN(engine->mode->parameters);
1510 PseudoAxesAdapter *adapter = _pseudoAxesAdapters[idx];
1511 adapter->_mode_parameters_names.resize(len, 1);
1512 for(i=0; i<len; ++i)
1513 adapter->_mode_parameters_names.data[i] = const_cast<char *>(engine->mode->parameters[i].name);
1514 return adapter->_mode_parameters_names;
1517 Matrix<double> const & TangoHKLAdapter::pseudo_axes_get_mode_parameters(size_t idx)
1519 omni_mutex_lock lock(_lock);
1521 size_t i;
1522 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1523 size_t len = HKL_LIST_LEN(engine->mode->parameters);
1524 PseudoAxesAdapter *adapter = _pseudoAxesAdapters[idx];
1525 adapter->_mode_parameters.resize(len, 1);
1526 for(i=0; i<len; ++i)
1527 adapter->_mode_parameters.data[i] = hkl_parameter_get_value_unit(&engine->mode->parameters[i]);
1528 return adapter->_mode_parameters;
1531 void TangoHKLAdapter::pseudo_axes_set_mode_parameters(size_t idx, Matrix<double> const & values)
1533 omni_mutex_lock lock(_lock);
1535 size_t i;
1536 HklPseudoAxisEngine *engine = _diffractometer->engines_r->engines[idx];
1537 size_t len = HKL_LIST_LEN(engine->mode->parameters);
1538 if(len == values.xdim)
1539 for(i=0; i<len; ++i){
1540 double & value = values.data[i];
1542 hkl_parameter_set_value_unit(&_diffractometer->engines_r->engines[idx]->mode->parameters[i],
1543 value);
1544 hkl_parameter_set_value_unit(&_diffractometer->engines_w->engines[idx]->mode->parameters[i],
1545 value);
1546 hkl_parameter_set_value_unit(&_diffractometer->engines_r_real->engines[idx]->mode->parameters[i],
1547 value);
1548 hkl_parameter_set_value_unit(&_diffractometer->engines_w_real->engines[idx]->mode->parameters[i],
1549 value);
1553 void TangoHKLAdapter::pseudo_axes_init(size_t idx)
1555 omni_mutex_lock lock(_lock);
1557 HklPseudoAxisEngine *engine_r = _diffractometer->engines_r->engines[idx];
1558 HklPseudoAxisEngine *engine_w = _diffractometer->engines_w->engines[idx];
1559 HklPseudoAxisEngine *engine_r_real = _diffractometer->engines_r_real->engines[idx];
1560 HklPseudoAxisEngine *engine_w_real = _diffractometer->engines_w_real->engines[idx];
1562 hkl_pseudo_axis_engine_init(engine_r, _diffractometer->geometry_r,
1563 &_diffractometer->detector, _diffractometer->samples->current);
1564 hkl_pseudo_axis_engine_init(engine_w, _diffractometer->geometry_w,
1565 &_diffractometer->detector, _diffractometer->samples->current);
1566 hkl_pseudo_axis_engine_init(engine_r_real, _diffractometer->geometry_r_real,
1567 &_diffractometer->detector_real, _diffractometer->samples->current);
1568 hkl_pseudo_axis_engine_init(engine_w_real, _diffractometer->geometry_w_real,
1569 &_diffractometer->detector_real, _diffractometer->samples->current);
1572 void TangoHKLAdapter::pseudo_axes_add_dynamic_attributes(size_t idx)
1574 //omni_mutex_lock lock(_lock);
1576 size_t i, j;
1578 // check if all the PseudoAxes were instantiated
1579 for(i=0; i<_pseudoAxesAdapters.size(); ++i)
1580 if(!_pseudoAxesAdapters[i]->_device)
1581 return;
1584 * we need to attach the dynamic attributes after all instance of
1585 * the PseudoAxes devices were started. otherwise it cause problem.
1587 for(i=0; i<_pseudoAxesAdapters.size(); ++i){
1588 PseudoAxesAdapter *adapter = _pseudoAxesAdapters[i];
1590 for(j=0; j<adapter->_dynamic_attribute_pseudo_axes_axis.size(); ++j)
1591 adapter->_device->add_attribute(adapter->_dynamic_attribute_pseudo_axes_axis[j]);
1595 void TangoHKLAdapter::pseudo_axes_remove_dynamic_attributes(size_t idx)
1597 size_t i;
1598 PseudoAxesAdapter *adapter;
1600 adapter = _pseudoAxesAdapters[idx];
1601 for(i=0; i<adapter->_dynamic_attribute_pseudo_axes_axis.size(); ++i)
1602 adapter->_device->remove_attribute(adapter->_dynamic_attribute_pseudo_axes_axis[i]);
1605 void TangoHKLAdapter::pseudo_axes_create_and_start_devices(void)
1607 omni_mutex_lock lock(_lock);
1609 unsigned int i, j;
1611 Tango::Util *tg = Tango::Util::instance();
1612 Tango::Database *db = tg->get_database();
1613 for(i=0; i<_pseudoAxesAdapters.size(); ++i){
1614 std::string dev_name = _pseudoAxesAdapters[i]->get_proxy_name();
1616 // first check if the device is already defined in the database
1617 try{
1618 Tango::DbDevImportInfo my_device_import_info;
1620 my_device_import_info = db->import_device(dev_name);
1621 } catch (Tango::DevFailed &) {
1622 Tango::DbDevInfo my_device_info;
1624 // add the device to the database
1625 my_device_info.name = dev_name.c_str();
1626 my_device_info._class = "PseudoAxes";
1627 my_device_info.server = tg->get_ds_name().c_str();
1629 db->add_device(my_device_info);
1631 // add the right properties to that device
1632 Tango::DbDatum DiffractometerProxy("DiffractometerProxy"), EngineName("EngineName");
1633 Tango::DbData properties;
1634 DiffractometerProxy << _device->name();
1635 EngineName << _pseudoAxesAdapters[i]->get_name();
1636 properties.push_back(DiffractometerProxy);
1637 properties.push_back(EngineName);
1638 db->put_device_property(dev_name,properties);
1641 // now start the device
1642 const std::vector<Tango::DeviceClass *> *cl_list = tg->get_class_list();
1643 for(j=0; j<cl_list->size(); ++j){
1644 if((*cl_list)[j]->get_name() == "PseudoAxes"){
1645 try{
1646 Tango::DevVarStringArray na;
1647 na.length(1);
1648 na[0] = dev_name.c_str();
1649 (*cl_list)[j]->device_factory(&na);
1650 std::cout << "Started " << dev_name << std::endl;
1651 break;
1653 catch (Tango::DevFailed &e)
1662 /**********************/
1663 /* Dynamic attributes */
1664 /**********************/
1666 void TangoHKLAdapter::create_axes_dynamic_attributes(void)
1668 size_t i;
1669 size_t len = _axes.size();
1670 _dynamic_attribute_axes_names.resize(len, 1);
1671 for(i=0; i<len; ++i){
1672 std::string name;
1673 AxisAttrib *att;
1675 // compute the pseudo axis name
1676 name = "axis";
1677 name += _axes[i].get_name();
1678 name[4] = toupper(name[4]);
1680 // create the PseudoAxesAttribut
1681 att = new AxisAttrib(name.c_str(), _axes[i]);
1682 _dynamic_attribute_axes.push_back(att);
1683 _dynamic_attribute_axes_names.data[i] = const_cast<char *>(att->get_name().c_str());
1687 void TangoHKLAdapter::add_dynamic_attributes_to_device(void)
1689 size_t i;
1691 for(i=0; i<_dynamic_attribute_axes.size(); ++i)
1692 _device->add_attribute(_dynamic_attribute_axes[i]);
1696 void TangoHKLAdapter::delete_dynamic_attributes(void)
1698 size_t i;
1700 for(i=0; i<_dynamic_attribute_axes.size(); ++i)
1701 _device->remove_attribute(_dynamic_attribute_axes[i], true);
1705 void TangoHKLAdapter::set_simulated(bool simulated)
1707 bool old = this->simulated;
1708 this->simulated = simulated;
1709 if (old == true && simulated == false)
1710 this->update();
1713 } // namespace
1715 std::string hkl_axes_consign_as_string(HklAxis const **axes, size_t axes_len)
1717 size_t i;
1718 std::string out;
1720 std::ostringstream line, tmp;
1721 for(i=0; i<axes_len; ++i) {
1722 HklParameter const *axis = (HklParameter const *)axes[i];
1723 double value = hkl_parameter_get_value_unit(axis);
1725 out += " \"";
1726 out += axis->name;
1727 out + "\" ";
1728 std::ostringstream tmp;
1729 tmp << showpos;
1730 tmp << value << "°";
1731 out += tmp.str();
1734 return out;