/* * 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 #include #include #include #include #include "NumorMessages.pb.h" #include "D22AutoConfig.h" #include #include 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::Start(this), m_countSpy(nullptr) { setFamily(family::ACQUISITION, family::SETTING); serverEndpoint.init(this, SAVE, "cameo_server"); initialized.init(this, NOSAVE, "initialized"); distance.init(this, NOSAVE, "distance"); wavelength.init(this, NOSAVE, "wavelength"); collimation.init(this, NOSAVE, "collimation"); scatterModelType.init(this, NOSAVE, "scatter_model_type"); type.init(this, NOSAVE, "type"); sampleRadius.init(this, NOSAVE, "sample_radius"); m_d22settings.init(this, "settings"); m_driver.init(this, "driver"); } AutoConfig::AutoConfig(const AutoConfig& controller) : ExperimentController(controller), controller::Start(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() { 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(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; } // Application initialized initialized = true; return true; } void AutoConfig::start() { if (!initApplication()) { return; } // Create the requester unique_ptr requester = application::Requester::create(*m_remoteApplication, RESPONDER); if (requester.get() == nullptr) { cout << "requester error" << endl; return; } // Start date. Date begin; // Prepare the request. lssautoconfig::NumorRequest request; // Set the request parameters. request.set_instrumentname("D22"); request.mutable_parameters()->set_distance(m_d22settings->detPosition()); request.mutable_parameters()->set_wavelength(m_d22settings->wavelengthPosition()); request.mutable_parameters()->set_collimation(m_d22settings->colSetupPosition()); request.set_type(lssautoconfig::NumorRequest_Type::NumorRequest_Type_Background); // Get the data from the active count controller. acquisition::Count* count = nullptr; try { count = dynamic_cast(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(data), sizeof(int32) * xSize * ySize)); // Send the request. requester->sendBinary(request.SerializeAsString()); // Wait for the response from the server. string response; requester->receiveBinary(response); // Print the duration. Date end; double ms = (end - begin).getMilliseconds(); cout << "Request processed in " << ms << " ms" << endl; lssautoconfig::Response autoConfigResponse; autoConfigResponse.ParseFromString(response); distance = autoConfigResponse.mutable_parameters()->distance(); wavelength = autoConfigResponse.mutable_parameters()->wavelength(); collimation = autoConfigResponse.mutable_parameters()->collimation(); scatterModelType = autoConfigResponse.scattermodeltype(); type = autoConfigResponse.type(); sampleRadius = autoConfigResponse.sampleradius(); } }