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
),
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);
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);
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
);
60 PseudoAxesAdapter::~PseudoAxesAdapter(void)
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)
137 void PseudoAxesAdapter::update_axes_i(HklPseudoAxisEngine
*engine
)
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
;
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
);
158 void PseudoAxesAdapter::add_dynamic_attributes_i(void)
162 Tango::MultiAttribute
*multiattribute
= _device
->get_device_attr();
164 for(i
=0; i
<_dynamic_attribute_pseudo_axes_axis
.size(); ++i
){
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)
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
]);
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
;
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;
210 if(_config
.mode
!= _engine_r
->mode
->name
){
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
);
227 void PseudoAxesAdapter::save(void)
229 Tango::DbData mode_prop
;
230 Tango::DbData data_put
;
231 HklPseudoAxisEngine
*engine
;
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
;
256 mode
= engine
->modes
[i
];
257 for(j
=0; j
<HKL_LIST_LEN(mode
->parameters
); ++j
){
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
269 Tango::DbDatum
property(mode
->name
);
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) {
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
;
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
))
310 if(idx_m
>=len
) // did not find the right mode name
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
++) {
320 char *line
= strdup(lines
[j
].c_str());
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
))
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
);
338 }// End for each property