* implement the apply command
[diffractometer.git] / src / PseudoAxesAdapter.cpp
bloba2e5525a9fad046aa9f52452277d17fa23b2a094
1 #include "TangoHKLAdapter.h"
2 #include "PseudoAxes.h"
3 #include "PseudoAxesAttrib.h"
4 #include "PseudoAxesAdapter.h"
5 #include "Diffractometer.h"
7 namespace Diffractometer_ns
10 PseudoAxesAdapter::PseudoAxesAdapter(TangoHKLAdapter *hklAdapter, size_t idx,
11 HklPseudoAxisEngine *engine_r,
12 HklPseudoAxisEngine *engine_w):
13 _hklAdapter(hklAdapter),
14 _engine_r(engine_r),
15 _engine_w(engine_w),
16 _idx(idx)
18 size_t i;
19 size_t len;
21 len = HKL_LIST_LEN(_engine_r->pseudoAxes);
22 _config.read.resize(len, 1);
23 _config.write.resize(len, 1);
25 // update the _config.mode_names only once.
26 len = HKL_LIST_LEN(_engine_r->modes);
27 _config.mode_names.resize(len, 1);
28 for(i=0; i<len; ++i)
29 _config.mode_names.data[i] = const_cast<char *>(_engine_r->modes[i]->name);
32 * update the _config.pseudo_axes_names and create the dynamic attributes
33 * only once per PseudoAxesAdapter.
35 len = HKL_LIST_LEN(_engine_r->pseudoAxes);
36 _config.pseudo_axes_names.resize(len , 1);
37 for(i=0; i<len; ++i){
38 Tango::Attr *att;
39 const char *name;
41 name = ((HklParameter *)(_engine_r->pseudoAxes[i]))->name;
42 _config.pseudo_axes_names.data[i] = const_cast<char *>(name);
43 att = new PseudoAxesAxisAttrib(name, *this, i);
44 _dynamic_attribute_pseudo_axes_axis.push_back(att);
47 // compute the proxy name
48 _proxy_name = _hklAdapter->get_device()->get_name();
49 _proxy_name += "-sim-";
50 _proxy_name += _engine_r->name;
52 this->update_axes_i(_engine_r);
54 this->update();
56 _device = NULL;
57 _synchronize = true;
60 PseudoAxesAdapter::~PseudoAxesAdapter(void)
62 size_t i;
64 for(i=0; i<_dynamic_attribute_pseudo_axes_axis.size(); ++i)
65 delete _dynamic_attribute_pseudo_axes_axis[i];
68 PseudoAxesConfig PseudoAxesAdapter::get_config(void)
70 return _hklAdapter->pseudo_axes_get_config(_idx);
73 char const * PseudoAxesAdapter::get_name(void) const
75 return _hklAdapter->diffractometer()->engines_r->engines[_idx]->name;
78 void PseudoAxesAdapter::set_axis_value(size_t idx, double value)
80 _hklAdapter->pseudo_axes_set_axis_value(_idx, idx, value);
83 void PseudoAxesAdapter::apply(void)
85 _hklAdapter->pseudo_axes_apply(_idx, _config.write);
88 void PseudoAxesAdapter::set_mode(const Tango::DevString name)
90 _hklAdapter->pseudo_axes_set_mode(_idx, name);
93 void PseudoAxesAdapter::set_initialized(const Tango::DevBoolean initialized)
95 _hklAdapter->pseudo_axes_set_initialized(_idx, initialized);
98 void PseudoAxesAdapter::set_parameters(const Matrix<double> values)
100 _hklAdapter->pseudo_axes_set_mode_parameters(_idx, values);
103 void PseudoAxesAdapter::init(void)
105 _hklAdapter->pseudo_axes_init(_idx);
108 void PseudoAxesAdapter::add_dynamic_attributes(void)
111 * need to call the _hklAdapter method to add all
112 * the dynamic attributes of all PseudoAxesAdapter in a row.
113 * This is due to the dynamic attribute Tango behaviour.
114 * Once a device was instanciate, the next device contain already
115 * the added dynamic attributes. So you need to add the dynamic attributes
116 * once all devices were instanciate.
118 * add_dynamic_attribute_i do the real job for one PseudoAxesAdapter.
120 _hklAdapter->pseudo_axes_add_dynamic_attributes(_idx);
123 void PseudoAxesAdapter::remove_dynamic_attributes(void)
125 _hklAdapter->pseudo_axes_remove_dynamic_attributes(_idx);
128 void PseudoAxesAdapter::load(void)
130 this->load_1();
133 /******************/
134 /* private method */
135 /******************/
137 void PseudoAxesAdapter::update_axes_i(HklPseudoAxisEngine *engine)
139 size_t i, j;
140 size_t len;
141 char const **names;
143 // fill the _axes with the right AxisAdapters
144 std::vector<AxisAdapter> & axes = _hklAdapter->get_axes();
145 len = HKL_LIST_LEN(engine->mode->axes_names);
146 names = engine->mode->axes_names;
147 _axes.clear();
148 for(i=0; i<len; ++i)
149 for(j=0; j<axes.size(); ++j){
150 AxisAdapter & axis = axes[j];
151 if(axis.get_name() == names[i]) {
152 _axes.push_back(&axis);
153 continue;
158 void PseudoAxesAdapter::add_dynamic_attributes_i(void)
160 if(_device){
161 size_t i;
162 Tango::MultiAttribute *multiattribute = _device->get_device_attr();
164 for(i=0; i<_dynamic_attribute_pseudo_axes_axis.size(); ++i){
165 try{
166 multiattribute->get_attr_by_name(_config.pseudo_axes_names.data[i]);
167 }catch (Tango::DevFailed){
168 _device->add_attribute(_dynamic_attribute_pseudo_axes_axis[i]);
174 void PseudoAxesAdapter::update(void)
176 size_t i, len;
177 std::string status_extra;
179 // update the read/write part.
180 len = HKL_LIST_LEN(_engine_r->pseudoAxes);
181 for(i=0; i<len; ++i){
182 _config.read.data[i] = hkl_parameter_get_value_unit((HklParameter *)_engine_r->pseudoAxes[i]);
183 if(_synchronize)
184 _config.write.data[i] = hkl_parameter_get_value_unit((HklParameter *)_engine_w->pseudoAxes[i]);
187 // update the state and status.
188 _config.status = "PseudoAxes status: ";
190 if(!_hklAdapter->_auto_update_from_proxies)
191 _config.state = Tango::STANDBY;
192 else{
193 _config.state = Tango::STANDBY;
194 for(i=0;i<_axes.size();++i) {
195 AxisAdapter const * axis = _axes[i];
196 ::compose_state(_config.state, axis->get_state());
197 if (axis->get_state() != Tango::STANDBY)
198 status_extra += "\n" + axis->get_proxy_name() + " is in " + Tango::DevStateName[axis->get_state()];
201 _config.status += Tango::DevStateName[_config.state];
202 _config.status += status_extra;
204 // update the initialized
205 if(_engine_r->mode->initialize == NULL)
206 _config.initialized = true;
208 // update the mode
209 if(_engine_r->mode){
210 if(_config.mode != _engine_r->mode->name){
211 size_t i;
212 size_t len;
214 _config.mode = const_cast<Tango::DevString>(_engine_r->mode->name);
215 len = HKL_LIST_LEN(_engine_r->mode->parameters);
216 _config.parameters.resize(len, 1);
217 _config.parameters_names.resize(len, 1);
218 for(i=0; i<len; ++i){
219 _config.parameters.data[i] = hkl_parameter_get_value_unit(&_engine_r->mode->parameters[i]);
220 _config.parameters_names.data[i] = const_cast<char *>(_engine_r->mode->parameters[i].name);
223 }else
224 _config.mode = NULL;
227 void PseudoAxesAdapter::save(void)
229 Tango::DbData mode_prop;
230 Tango::DbData data_put;
231 HklPseudoAxisEngine *engine;
232 size_t i, j, len;
234 // first erase the old mode properties
235 mode_prop.push_back(Tango::DbDatum("Mode"));
236 _device->get_db_device()->get_attribute_property(mode_prop);
237 long number_of_prop = 0;
238 mode_prop[0] >> number_of_prop ;
239 if(number_of_prop > 0)
240 _device->get_db_device()->delete_attribute_property(mode_prop);
242 // Step 2 : create the Mode properties
243 engine = _hklAdapter->diffractometer()->engines_r->engines[_idx];
244 Tango::DbDatum properties("Mode");
245 // Put number of properties (= nb of samples + 1)
246 len = HKL_LIST_LEN(engine->modes);
247 properties << (long)(len);
248 data_put.push_back(properties);
250 for(i=0; i<len; ++i){
251 HklPseudoAxisEngineMode *mode;
252 std::vector<std::string> lines;
253 char line[256];
255 // the mode
256 mode = engine->modes[i];
257 for(j=0; j<HKL_LIST_LEN(mode->parameters); ++j){
258 char const *name;
259 double value;
261 name = mode->parameters[j].name;
262 value = hkl_parameter_get_value_unit(&mode->parameters[j]);
263 snprintf(line, 255, "%s=%f", name, value);
264 lines.push_back(line);
267 // Try to create property
268 // Get crystal name
269 Tango::DbDatum property(mode->name);
270 property << lines;
271 data_put.push_back(property);
274 //update database for this property
275 _device->get_db_device()->put_attribute_property(data_put);
278 void PseudoAxesAdapter::load_1(void)
280 unsigned long nb_properties;
282 // Get the Crystal Attributes properties.
283 Tango::DbData properties;
284 properties.push_back(Tango::DbDatum("Mode"));
285 _device->get_db_device()->get_attribute_property(properties);
287 // the first one is the number of properties
288 properties[0] >> nb_properties;
290 if (nb_properties > 1) {
291 size_t i;
292 HklPseudoAxisEngine *engine_r, *engine_w, *engine_r_real, *engine_w_real;
294 engine_r = _hklAdapter->diffractometer()->engines_r->engines[_idx];
295 engine_w = _hklAdapter->diffractometer()->engines_w->engines[_idx];
296 engine_r_real = _hklAdapter->diffractometer()->engines_r_real->engines[_idx];
297 engine_w_real = _hklAdapter->diffractometer()->engines_w_real->engines[_idx];
299 for(i=1; i<=nb_properties; ++i) {
300 size_t idx_m, j, len;
301 char const *name;
302 std::vector<std::string> lines;
304 // first find the PseudoAxisEngineMode idx from its name
305 name = properties[i].name.c_str();
306 len = HKL_LIST_LEN(engine_r->modes);
307 for(idx_m=0; idx_m<len; ++idx_m)
308 if(!strcmp(name, engine_r->modes[idx_m]->name))
309 break;
310 if(idx_m>=len) // did not find the right mode name
311 continue;
313 // Extract the mode parameters from the properties
314 properties[i] >> lines;
316 // extract the parameters values
317 for(j=0; j<lines.size(); j++) {
318 size_t idx_p;
320 char *line = strdup(lines[j].c_str());
321 char *last;
322 char *key = strtok_r(line, "=", &last);
324 for(idx_p=0; idx_p<len; ++idx_p)
325 if(!strcmp(key, engine_r->modes[idx_m]->parameters[idx_p].name))
326 break;
327 if(idx_p < len){
328 double value;
330 value = atof(strtok_r(NULL,";", &last));
331 hkl_parameter_set_value_unit(&engine_r->modes[idx_m]->parameters[idx_p], value);
332 hkl_parameter_set_value_unit(&engine_w->modes[idx_m]->parameters[idx_p], value);
333 hkl_parameter_set_value_unit(&engine_r_real->modes[idx_m]->parameters[idx_p], value);
334 hkl_parameter_set_value_unit(&engine_w_real->modes[idx_m]->parameters[idx_p], value);
336 free(line);
338 }// End for each property