Skip to content
Snippets Groups Projects
experimentstate.cpp 5.74 KiB
/**
 * @file experimentstate.cpp
 *
 * @author Tobias Triffterer
 *
 * @brief Data Struct to keep Key Parameters of the Experimental Setup
 *
 * Rutherford Experiment Lab Course Online
 * Copyright © 2021 Ruhr-Universität Bochum, Institut für Experimentalphysik I
 * https://www.ep1.ruhr-uni-bochum.de/
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 **/

#include <stdexcept>

#include "experimentstate.h"

using namespace Fp311Online;

ExperimentState::ExperimentState(const uint64_t experimentId)
    : id(experimentId)
{}

ExperimentState::PressureTorr ExperimentState::convertHectoPascalToTorr(const PressureHectoPascal& pressure)
{
    return pressure * 76000.0 / 101325.0;
}

Protocol::Command ExperimentState::getStateCommand() const
{
    const QString adcstate = (adcState == AdcState::Running) ? QStringLiteral("running") : QStringLiteral("stopped");
    const QString beamhole = [this]() -> QString {
        switch (beamHoleState) {
            case BeamHoleState::Closed:
            default:
                return QStringLiteral("closed");
            case BeamHoleState::Open:
                return QStringLiteral("open");
            case BeamHoleState::GoldFoil:
                return QStringLiteral("goldfoil"); }
        }();

    return Protocol::Command(
               Protocol::Action::updateExperimentState,
               Protocol::Command::Arguments {
                    std::make_pair(QStringLiteral("adcstate"), adcstate),
                    std::make_pair(QStringLiteral("beamhole"), beamhole),
                    std::make_pair(QStringLiteral("pressurehPa"), QString::number(pressure)),
                    std::make_pair(QStringLiteral("targetposition"), QString::number(targetPosition)),
                    std::make_pair(QStringLiteral("adcthreshold"), QString::number(adcThreshold)),
                    std::make_pair(QStringLiteral("vacuumvalve"), QString::number(vacuumValve))
               },
               QString() // Token will be added by class that requested the Command object
           );
}

void ExperimentState::updateFromCommand(const Protocol::Command& command)
{
    if (command.action != Protocol::Action::updateExperimentState)
    {
        logError(QStringLiteral("Command instance passed to ExperimentState::updateFromCommand is not of type updateExperimentState."));
        return;
    }

    if (command.arguments[QStringLiteral("adcstate")] == QStringLiteral("running"))
        adcState = AdcState::Running;
    else if (command.arguments[QStringLiteral("adcstate")] == QStringLiteral("stopped"))
        adcState = AdcState::Stopped;
    else
        logError(QStringLiteral("Invalid value for argument \"adcstate\" of updateExperimentState command."));

    if (command.arguments[QStringLiteral("beamhole")] == QStringLiteral("closed"))
        beamHoleState = BeamHoleState::Closed;
    else if (command.arguments[QStringLiteral("beamhole")] == QStringLiteral("open"))
        beamHoleState = BeamHoleState::Open;
    else if (command.arguments[QStringLiteral("beamhole")] == QStringLiteral("goldfoil"))
        beamHoleState = BeamHoleState::GoldFoil;
    else
        logError(QStringLiteral("Invalid value for argument \"beamhole\" of updateExperimentState command."));

    try {
        bool ok = false;
        pressure = command.arguments[QStringLiteral("pressurehPa")].toDouble(&ok);
        if (!ok)
            logError(QStringLiteral("Error converting the \"pressure\" string in the updateExperimentState command into a numeral."));
    }
    catch(PressureHectoPascal::BoundaryExceeded& e) {
        logError(QStringLiteral("\"pressure\" value in the updateExperimentState command out of range: ") + QString::fromUtf8(e.what()));
    }

    try {
        bool ok = false;
        targetPosition = command.arguments[QStringLiteral("targetposition")].toDouble(&ok);
        if (!ok)
            logError(QStringLiteral("Error converting the \"targetposition\" string in the updateExperimentState command into a numeral."));
    }
    catch(TargetPositionMilliMeter::BoundaryExceeded& e) {
        logError(QStringLiteral("\"targetposition\" value in the updateExperimentState command out of range: ") + QString::fromUtf8(e.what()));
    }

    try {
        bool ok = false;
        adcThreshold = static_cast<AdcConversion::valueType>(command.arguments[QStringLiteral("adcthreshold")].toUInt(&ok));
        if (!ok)
            logError(QStringLiteral("Error converting the \"adcthreshold\" string in the updateExperimentState command into a numeral."));
    }
    catch(AdcConversion::BoundaryExceeded& e) {
        logError(QStringLiteral("\"adcthreshold\" value in the updateExperimentState command out of range: ") + QString::fromUtf8(e.what()));
    }

    try {
        bool ok = false;
        vacuumValve = static_cast<VacuumValveOpening::valueType>(command.arguments[QStringLiteral("vacuumvalve")].toUInt(&ok));
        if (!ok)
            logError(QStringLiteral("Error converting the \"vacuumvalve\" string in the updateExperimentState command into a numeral."));
    }
    catch(VacuumValveOpening::BoundaryExceeded& e) {
        logError(QStringLiteral("\"vacuumvalve\" value in the updateExperimentState command out of range: ") + QString::fromUtf8(e.what()));
    }
}