Skip to content
Snippets Groups Projects
Commit dcc310fb authored by vargheseg's avatar vargheseg
Browse files

Implemnted DoocsIfff::setMacroPulseNumberSource

parent 7bd69cc1
No related branches found
No related tags found
No related merge requests found
......@@ -29,17 +29,23 @@ namespace ChimeraTK {
void set(EqAdr* eqAdr, EqData* data1, EqData* data2, EqFct* eqFct) override;
void auto_init(void) override;
void setMacroPulseNumberSource(boost::shared_ptr<ChimeraTK::NDRegisterAccessor<int64_t>> macroPulseNumberSource);
DataConsistencyGroup _consistencyGroup;
protected:
void updateAppToDoocs(TransferElementID& elementId);
void sendToApplication();
void registerVariable(const ChimeraTK::TransferElementAbstractor& var);
DataConsistencyGroup _consistencyGroup;
boost::shared_ptr<NDRegisterAccessor<int>> _i1Value;
boost::shared_ptr<NDRegisterAccessor<float>> _f1Value;
boost::shared_ptr<NDRegisterAccessor<float>> _f2Value;
boost::shared_ptr<NDRegisterAccessor<float>> _f3Value;
DoocsUpdater& _updater;
EqFct* _eqFct;
bool isWriteable;
boost::shared_ptr<ChimeraTK::NDRegisterAccessor<int64_t>> _macroPulseNumberSource;
};
} // namespace ChimeraTK
......@@ -2,6 +2,8 @@
#include "DoocsUpdater.h"
#include <ChimeraTK/OneDRegisterAccessor.h>
#include <ChimeraTK/ScalarRegisterAccessor.h>
#include <doocs/EventId.h>
namespace ChimeraTK {
DoocsIfff::DoocsIfff(EqFct* eqFct, std::string const& doocsPropertyName,
......@@ -9,13 +11,17 @@ namespace ChimeraTK {
boost::shared_ptr<NDRegisterAccessor<float>> const& f1Value,
boost::shared_ptr<NDRegisterAccessor<float>> const& f2Value,
boost::shared_ptr<NDRegisterAccessor<float>> const& f3Value, DoocsUpdater& updater)
: D_ifff(eqFct, doocsPropertyName), _i1Value(i1Value), _f1Value(f1Value), _f2Value(f2Value), _f3Value(f3Value) {
: D_ifff(eqFct, doocsPropertyName), _i1Value(i1Value), _f1Value(f1Value), _f2Value(f2Value), _f3Value(f3Value),
_updater(updater), _eqFct(eqFct) {
auto registerSource = [&](const ChimeraTK::TransferElementAbstractor& var) {
if(var.isReadable()) {
updater.addVariable(var, eqFct, std::bind(&DoocsIfff::updateAppToDoocs, this, var.getId()));
_consistencyGroup.add(var);
}
};
// FIXME: What if not all 4 are readable? is it still valid to add
// all to a consistency group then?
registerSource(OneDRegisterAccessor<int>(_i1Value));
registerSource(OneDRegisterAccessor<float>(_f1Value));
registerSource(OneDRegisterAccessor<float>(_f2Value));
......@@ -29,40 +35,51 @@ namespace ChimeraTK {
}
void DoocsIfff::updateAppToDoocs(TransferElementID& elementId) {
if(_consistencyGroup.update(elementId)) {
if(_i1Value->dataValidity() != ChimeraTK::DataValidity::ok ||
_f1Value->dataValidity() != ChimeraTK::DataValidity::ok ||
_f2Value->dataValidity() != ChimeraTK::DataValidity::ok ||
_f3Value->dataValidity() != ChimeraTK::DataValidity::ok) {
this->d_error(stale_data);
}
else {
this->d_error(no_error);
}
if(!_consistencyGroup.update(elementId)) {
return;
}
IFFF ifff;
ifff.i1_data = _i1Value->accessData(0);
ifff.f1_data = _f1Value->accessData(0);
ifff.f2_data = _f2Value->accessData(0);
ifff.f3_data = _f3Value->accessData(0);
// we must not call set_and_archive if there is no history (otherwise it
// will be activated), but we have to if it is there. -> Abstraction,
// please!
if(this->get_histPointer()) {
// Set eventId
//doocs::EventId eventId;
//if(_macroPulseNumberSource) eventId = doocs::EventId(_macroPulseNumberSource->accessData(0));
/*FIXME: The archiver also has a status code. Set it correctly.*/
/*FIXME: This set_and_archive does not support the timestamp yet (only sec and msec, and I guess m is milli?)*/
/*FIXME: This set_and_archive does not support eventIDs yet */
this->set_and_archive(&ifff, ArchiveStatus::sts_ok, 0 /*sec*/, 0 /*msec*/);
}
else {
this->set_value(&ifff);
}
if(_i1Value->dataValidity() != ChimeraTK::DataValidity::ok ||
_f1Value->dataValidity() != ChimeraTK::DataValidity::ok ||
_f2Value->dataValidity() != ChimeraTK::DataValidity::ok ||
_f3Value->dataValidity() != ChimeraTK::DataValidity::ok) {
this->d_error(stale_data);
}
else {
this->d_error(no_error);
}
IFFF ifff;
ifff.i1_data = _i1Value->accessData(0);
ifff.f1_data = _f1Value->accessData(0);
ifff.f2_data = _f2Value->accessData(0);
ifff.f3_data = _f3Value->accessData(0);
doocs::Timestamp timestamp(_i1Value->getVersionNumber().getTime());
auto sinceEpoch = timestamp.get_seconds_and_microseconds_since_epoch();
auto seconds = sinceEpoch.seconds;
auto microseconds = sinceEpoch.microseconds;
// update global time stamp of DOOCS, but only if our time stamp is newer
if(get_global_timestamp() < timestamp) {
set_global_timestamp(timestamp);
}
if(this->get_histPointer()) {
/*
doocs::EventId eventId =
(_macroPulseNumberSource) ? doocs::EventId(_macroPulseNumberSource->accessData(0)) : doocs::EventId(0);
*/
/*FIXME: The archiver also has a status code. Set it correctly.*/
/*FIXME: This set_and_archive does not support the timestamp yet (only sec and msec, and I guess m is milli?)*/
/*FIXME: This set_and_archive does not support eventIDs yet */
this->set_and_archive(&ifff, ArchiveStatus::sts_ok, 0, 0 /*msec*/);
}
else {
this->set_value(&ifff);
}
this->set_tmstmp(seconds, microseconds);
if(_macroPulseNumberSource) this->set_mpnum(_macroPulseNumberSource->accessData(0));
}
void DoocsIfff::set(EqAdr* eqAdr, EqData* data1, EqData* data2, EqFct* eqFct) {
......@@ -93,4 +110,26 @@ namespace ChimeraTK {
_f3Value->write(v);
}
void DoocsIfff::setMacroPulseNumberSource(
boost::shared_ptr<ChimeraTK::NDRegisterAccessor<int64_t>> macroPulseNumberSource) {
// FIXME: Assuming macroPulseNumberSource is relavent only when all 4
// components are readable; correct behavior later if this assumption
// does not hold.
bool isIfffReadable =
(_i1Value->isReadable() && _f1Value->isReadable() && _f2Value->isReadable() && _f3Value->isReadable());
if(not isIfffReadable) {
return;
}
_macroPulseNumberSource = macroPulseNumberSource;
if(_consistencyGroup.getMatchingMode() != DataConsistencyGroup::MatchingMode::none) {
registerVariable(ChimeraTK::ScalarRegisterAccessor<int64_t>(_macroPulseNumberSource));
}
}
void DoocsIfff::registerVariable(const ChimeraTK::TransferElementAbstractor& var) {
if(var.isReadable()) {
_updater.addVariable(var, _eqFct, std::bind(&DoocsIfff::updateAppToDoocs, this, var.getId()));
_consistencyGroup.add(var);
}
}
} // namespace ChimeraTK
......@@ -271,6 +271,26 @@ namespace ChimeraTK {
getDecorator<float>(f2ProcessVariable, DecoratorType::C_style_conversion),
getDecorator<float>(f3ProcessVariable, DecoratorType::C_style_conversion), _updater));
// set specified data_matching mode
boost::dynamic_pointer_cast<DoocsIfff>(doocsPV)->_consistencyGroup.setMatchingMode(ifffDescription.dataMatching);
// set macro pulse number source, if configured
if(ifffDescription.macroPulseNumberSource.size() > 0) {
auto mpnSource = _controlSystemPVManager->getProcessVariable(ifffDescription.macroPulseNumberSource);
auto mpnDecorated = getDecorator<int64_t>(mpnSource, DecoratorType::C_style_conversion);
if(mpnDecorated->getNumberOfSamples() != 1) {
throw ChimeraTK::logic_error("The property '" + mpnDecorated->getName() +
"' is used as a macro pulse number source, but it has an array "
"length of " +
std::to_string(mpnDecorated->getNumberOfSamples()) + ". Length must be exactly 1");
}
if(!mpnDecorated->isReadable()) {
throw ChimeraTK::logic_error("The property '" + mpnDecorated->getName() +
"' is used as a macro pulse number source, but it is not readable.");
}
boost::dynamic_pointer_cast<DoocsIfff>(doocsPV)->setMacroPulseNumberSource(mpnDecorated);
}
return doocsPV;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment