Commit e844ad94 authored by Locatelli's avatar Locatelli
Browse files

Merge V3.2_191

parent aa844469
This diff is collapsed.
/NumorMessages.pb.cc
/NumorMessages.pb.h
/*
* Nomad Instrument Control Software
*
* Copyright 2011 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#include "controllers/common/family/Families.h"
#include <boost/lexical_cast.hpp>
#include <common/base/Date.h>
#include <InstrumentManager/InstrumentManager.h>
#include <controllers/common/acquisition/Count.h>
#include <controllers/common/acquisition/detector/DetectorElement.h>
#include "NumorMessages.pb.h"
#include "D22AutoConfig.h"
#include <fstream>
#include <iostream>
namespace d22 {
using namespace std;
using namespace common;
using namespace boost;
using namespace cameo;
const std::string AutoConfig::TYPE = "d22_auto_config";
const std::string AutoConfig::REMOTE_APPLICATION = "autoconfig";
const std::string AutoConfig::RESPONDER = "responder";
AutoConfig::AutoConfig(const std::string& name) :
ExperimentController(name), controller::Stoppable(this),
m_countSpy(nullptr) {
setFamily(family::ACQUISITION, family::SETTING);
serverEndpoint.init(this, SAVE, "cameo_server");
initialized.init(this, NOSAVE, "initialized");
scatterModelType.init(this, NOSAVE, "scatter_model_type");
scatterModel.init(this, NOSAVE | SPY, "scatter_model", "Model");
scatterModelAccuracy.init(this, NOSAVE | SPY, "scatter_model_accuracy", "Accuracy");
sampleParameters.init(this, NOSAVE | SPY, "sample_parameters", "Sample");
calcTypeSize.init(this, NOSAVE, "calc_type_size");
calcType.init(this, NOSAVE, "calc_type");
resultSize.init(this, NOSAVE, "result_size");
type.init(this, NOSAVE, "type");
distance.init(this, NOSAVE, "distance");
wavelength.init(this, NOSAVE, "wavelength");
collimation.init(this, NOSAVE, "collimation");
wantedType.init(this, SAVE | SPY, "wanted_type", "Type");
wantedDistance.init(this, SAVE | SPY, "wanted_distance", "Distance");
wantedWavelength.init(this, SAVE | SPY, "wanted_wavelength", "Wavelength");
wantedCollimation.init(this, SAVE | SPY, "wanted_collimation", "Collimation");
wantedType.setEnumeratedValues(calcType);
wantedType.setEnumeratedLabels(calcType);
m_d22settings.init(this, "settings");
m_simulation.init(this, "simulation");
m_driver.init(this, "driver");
}
AutoConfig::AutoConfig(const AutoConfig& controller) :
ExperimentController(controller), controller::Stoppable(this),
m_countSpy(nullptr) {
}
AutoConfig::~AutoConfig() {
if (m_remoteApplication.get() != NULL) {
// Stop the remote application.
m_remoteApplication->stop();
// Wait for the termination
application::State state = m_remoteApplication->waitFor();
cout << "Remote application " << m_remoteApplication->getName() << " terminated with state " << application::toString(state) << endl;
}
}
void AutoConfig::postConfiguration() {
registerProgression(m_d22settings, &AutoConfig::updateProgression, this);
if (m_server.get() == nullptr) {
// Create a new server if it is not already created.
// In case of a simulated server, avoid the real remote endpoint.
if (serverEndpoint() == "" || m_driver->state() != REAL_DEVICE_CONTAINER) {
m_server.reset(new Server(application::This::getServer().getEndpoint()));
} else {
m_server.reset(new Server(serverEndpoint()));
}
}
// Get the count spy.
m_countSpy = dynamic_cast<utilities::CountSpy*>(InstrumentManager::getInstance()->getFirstExperimentControllerByType(utilities::CountSpy::TYPE));
if (m_countSpy != nullptr) {
m_countSpy->attach(this);
}
initialized = initApplication();
}
bool AutoConfig::initApplication() {
// Do not initialize if it is already done
if (initialized()) {
return true;
}
// Start the remote server
if (!m_server->isAvailable(1000)) {
cout << "Remote server is not available" << endl;
return false;
}
cout << "Remote server is connected" << endl;
m_remoteApplication = m_server->connect(REMOTE_APPLICATION);
if (m_remoteApplication->exists()) {
// The application exists from a previous server session
m_remoteApplication->kill();
application::State state = m_remoteApplication->waitFor();
cout << "Terminated remote application with state " << application::toString(state) << endl;
}
m_remoteApplication = m_server->start(REMOTE_APPLICATION);
if (!m_remoteApplication->exists()) {
cout << "No remote application" << endl;
return false;
}
// Create the requester
m_requester = application::Requester::create(*m_remoteApplication, RESPONDER);
if (m_requester.get() == nullptr) {
cout << "requester error" << endl;
return false;
}
// Initialize the list of types.
// Define the type of request.
lssautoconfig::Request requestType;
requestType.set_type(lssautoconfig::Request::Init);
// Send the request.
m_requester->sendBinary(requestType.SerializeAsString());
// Wait for the response from the server.
string response;
m_requester->receiveBinary(response);
lssautoconfig::InitResponse autoConfigResponse;
autoConfigResponse.ParseFromString(response);
int size = autoConfigResponse.types_size();
calcTypeSize = size;
calcType.resize(size);
for (int i = 0; i < size; ++i) {
calcType.set(i, autoConfigResponse.types(i));
}
// Set default value.
if (size > 0) {
wantedType = calcType.get(0);
}
type.resize(1);
distance.resize(1);
wavelength.resize(1);
collimation.resize(1);
// Application initialized
initialized = true;
return true;
}
float64 AutoConfig::getSampleBackground() {
// model_name
string modelName = m_simulation->displaySampleModelName();
int modelNameSize = m_simulation->model_name.getSize();
int i = 0;
while (i < modelNameSize) {
if (modelName == m_simulation->model_name.get(i)) {
break;
}
++i;
}
cout << "Model " << modelName << " found at index " << i << endl;
if (m_simulation->pnames.getSize() <= i) {
cout << "Background not found" << endl;
return 0;
}
int pnamesSize = m_simulation->pnames.getSize(i);
int j = 0;
while (j < pnamesSize) {
string pname = m_simulation->pnames.get(i, j);
if (pname.find("background") != string::npos || pname.find("Background") != string::npos) {
cout << "Background found at index " << j << " with " << pname << endl;
return m_simulation->parameters.get(i, j);
}
++j;
}
cout << "Background not found" << endl;
return 0;
}
void AutoConfig::start() {
// Start progression.
commandProgression = 0;
commandStatus.setRunning();
if (!initApplication()) {
commandProgression = 100;
commandStatus.setError();
return;
}
commandProgression = 10;
// Start date.
Date begin;
// Define the type of request.
lssautoconfig::Request requestType;
requestType.set_type(lssautoconfig::Request::Numor);
// Prepare the request.
lssautoconfig::NumorRequest request;
// Set the request parameters.
request.set_instrumentname("D22");
// Change to real values in the future?
request.mutable_parameters()->set_distance(m_d22settings->detPosition.setpoint());
request.mutable_parameters()->set_wavelength(m_d22settings->wavelengthPosition.setpoint());
request.mutable_parameters()->set_collimation(m_d22settings->colSetupPosition.setpoint());
request.set_type(wantedType());
request.set_samplemodel(m_simulation->displaySampleModelName());
request.set_backgroundmodel(m_simulation->displayBackgroundModelName());
request.set_samplebackground(getSampleBackground());
// Get the data from the active count controller.
acquisition::Count* count = nullptr;
try {
count = dynamic_cast<acquisition::Count*>(InstrumentManager::getInstance()->getExperimentController(m_countSpy->countControllerName()));
}
catch (InstrumentManager::ControllerNotFound& e) {
log(Level::s_Error) << name << " missing controller " << m_countSpy->countControllerName() << endlog;
commandStatus.setError();
commandProgression = 100;
return;
}
int32 xSize = count->masterDetector->xSize();
int32 ySize = count->masterDetector->ySize();
request.set_xsize(xSize);
request.set_ysize(ySize);
cout << "Data size " << xSize << " x " << ySize << endl;
int32* data = count->masterDetector->data();
request.set_data(string(reinterpret_cast<const char *>(data), sizeof(int32) * xSize * ySize));
log(Level::s_Debug) << "Calculate" << endlog;
// Send the request.
m_requester->sendTwoBinaryParts(requestType.SerializeAsString(), request.SerializeAsString());
// Wait for the response from the server.
string response;
m_requester->receiveBinary(response);
// Print the duration.
Date end;
double ms = (end - begin).getMilliseconds();
cout << "Request processed in " << ms << " ms" << endl;
lssautoconfig::NumorResponse autoConfigResponse;
autoConfigResponse.ParseFromString(response);
scatterModelType = autoConfigResponse.scattermodeltype();
scatterModel = autoConfigResponse.scattermodel();
scatterModelAccuracy = autoConfigResponse.scattermodelaccuracy();
string status = autoConfigResponse.status();
int size = autoConfigResponse.results_size();
resultSize = size;
type.resize(size);
distance.resize(size);
wavelength.resize(size);
collimation.resize(size);
for (int i = 0; i < size; ++i) {
type.set(i, autoConfigResponse.results(i).type());
distance.set(i, autoConfigResponse.results(i).parameters().distance());
wavelength.set(i, autoConfigResponse.results(i).parameters().wavelength());
collimation.set(i, autoConfigResponse.results(i).parameters().collimation());
}
string sampleParametersString;
for (int i = 0; i < autoConfigResponse.sampleparameters_size() - 1; ++i) {
sampleParametersString += autoConfigResponse.sampleparameters(i).type() + " " + to_string(autoConfigResponse.sampleparameters(i).value()) + ", ";
}
int i = autoConfigResponse.sampleparameters_size() - 1;
sampleParametersString += autoConfigResponse.sampleparameters(i).type() + " " + to_string(autoConfigResponse.sampleparameters(i).value());
sampleParameters = sampleParametersString;
// Intermediate progression.
commandProgression = 50;
if (status == "ERROR") {
log(Level::s_Error) << "No prediction" << endlog;
wantedDistance = distance.get(0);
wantedWavelength = wavelength.get(0);
wantedCollimation = collimation.get(0);
commandStatus.setError();
}
else {
log(Level::s_Debug) << "Apply" << endlog;
apply();
commandStatus.setIdle();
}
// End progression.
commandProgression = 100;
log(Level::s_Info) << "Finished auto settings" << endlog;
}
void AutoConfig::apply() {
// Set D22Settings.
int32 size = resultSize();
for (int i = 0; i < size; ++i) {
if (type.get(i) == wantedType()) {
wantedDistance = distance.get(i);
wantedWavelength = wavelength.get(i);
wantedCollimation = collimation.get(i);
m_d22settings->detPosition.setpoint = distance.get(i);
m_d22settings->wavelengthPosition.setpoint = wavelength.get(i);
// Check with tolerance.
for (float64 value : m_collimationValues) {
if (abs(value - collimation.get(i)) < 0.1) {
m_d22settings->colSetupPosition.setpoint = value;
break;
}
}
}
}
// Start D22Settings.
m_d22settings->startCommand(true);
}
void AutoConfig::stop() {
m_d22settings->stopCommand();
}
void AutoConfig::updateProgression() {
if (commandStatus.isRunning()) {
if (commandProgression() >= 50) {
commandProgression = 50 + m_d22settings->commandProgression() / 2;
}
}
}
}
/*
* Nomad Instrument Control Software
*
* Copyright 2011 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#ifndef D22_AUTOCONFIG_H
#define D22_AUTOCONFIG_H
#include <Controller.h>
#include <cameo/cameo.h>
#include <controllers/lss/d22/D22Settings.h>
#include <controllers/common/utilities/CountSpy.h>
#include <controllers/lss/remotelsssimulation/RemoteLSSSimulation.h>
#include <drivers/utilities/null/NullDriver.h>
namespace d22 {
class AutoConfig : public ExperimentController,
public controller::Stoppable {
public:
//! Type of controller
static const std::string TYPE;
AutoConfig(const std::string& name);
AutoConfig(const AutoConfig& controller);
virtual ~AutoConfig();
virtual void postConfiguration();
void apply();
virtual void start();
virtual void stop();
void updateProgression();
Property<std::string> serverEndpoint;
Property<bool> initialized;
Property<std::string> scatterModelType;
Property<std::string> scatterModel;
Property<std::string> scatterModelAccuracy;
Property<std::string> sampleParameters;
Property<int32> calcTypeSize;
DynamicProperty<std::string> calcType;
Property<int32> resultSize;
DynamicProperty<std::string> type;
DynamicProperty<float64> distance;
DynamicProperty<float64> wavelength;
DynamicProperty<float64> collimation;
Property<std::string> wantedType;
Property<float64> wantedDistance;
Property<float64> wantedWavelength;
Property<float64> wantedCollimation;
private:
bool initApplication();
float64 getSampleBackground();
static const std::string REMOTE_APPLICATION;
static const std::string RESPONDER;
std::unique_ptr<cameo::Server> m_server;
std::unique_ptr<cameo::application::Instance> m_remoteApplication;
std::unique_ptr<cameo::application::Requester> m_requester;
ControllerPtr<D22Settings> m_d22settings;
ControllerPtr<remotelsssimulation::RemoteLSSSimulation> m_simulation;
DriverPtr<driver::NullDriver> m_driver;
utilities::CountSpy* m_countSpy;
std::vector<float64> m_collimationValues = { 2.0, 2.8, 4.0, 5.6, 8.0, 11.2, 14.4, 17.6 };
};
}
#endif
<module name="d22autoconfig">
<controller class="d22::AutoConfig"/>
<include path="$(NOMAD_HOME)/../NomadModules/src"/>
<script exec="protoc --cpp_out=. NumorMessages.proto"/>
</module>
package lssautoconfig;
option optimize_for = LITE_RUNTIME;
message Request {
enum Type {
Init = 1;
Numor = 2;
}
required Type type = 1;
}
message InstrumentParameters {
required double distance = 1;
required double wavelength = 2;
required double collimation = 3;
}
message SampleParameters {
required string type = 1;
required double value = 2;
}
message NumorRequest {
required string instrumentName = 1;
required InstrumentParameters parameters = 2;
required string type = 3;
required string sampleModel = 4;
required string backgroundModel = 5;
required double sampleBackground = 6;
required int32 xSize = 7;
required int32 ySize = 8;
required bytes data = 9;
}
message Result {
required InstrumentParameters parameters = 1;
required string type = 2;
}
message InitResponse {
repeated string types = 1;
}
message NumorResponse {
required string scatterModelType = 1;
required string scatterModel = 2;
required string scatterModelAccuracy = 3;
required string status = 4;
repeated SampleParameters sampleParameters = 5;
repeated Result results = 6;
}
d22_auto_config.distancePrefix=Distance
d22_auto_config.wavelengthPrefix=Wavelength
d22_auto_config.collimationPrefix=Collimation
d22_auto_config.scatter_model_typePrefix=Scatter Model Type
d22_auto_config.typePrefix=Type
d22_auto_config.sample_parametersPrefix=Sample Parameters
d22_auto_config.resultsPrefix=Results
d22_auto_config.applyPrefix=Apply
d22_auto_config.wantedTypePrefix=Type
\ No newline at end of file
<plugin>
<controller type="d22_auto_config" role="d22_auto_config1"/>
<number_of_lines nb_lines="1"/>
<property_combo role="d22_auto_config1" property="wanted_type" prefix="d22_auto_config.wantedTypePrefix"/>
</plugin>