Code indexing in gitaly is broken and leads to code not being visible to the user. We work on the issue with highest priority.

Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
SumErrSqRadialPeak.h 3.73 KiB
//
// Struct SumErrSqRadialPeak
//   A simple expression computing the sum of all peak errors (given as
//   first and second argument) for a range of peaks (third argument and fourth argument)
//   according to
//
//   \f[
//     result = \frac{1}{n} * \sqrt{\sum_{i=start}^end (measurement_i - value_i)^2}
//   \f]
//
// Copyright (c) 2017 - 2018, Matthias Frey, Paul Scherrer Institut, Villigen PSI, Switzerland
// All rights reserved
//
// Implemented as part of the PhD thesis
// "Precise Simulations of Multibunches in High Intensity Cyclotrons"
// and the paper
// "Matching of turn pattern measurements for cyclotrons using multiobjective optimization"
// (https://doi.org/10.1103/PhysRevAccelBeams.22.064602)
//
// This file is part of OPAL.
//
// OPAL 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.
//
// You should have received a copy of the GNU General Public License
// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
//
#ifndef __SUMERRSQRADIALPEAK_H__
#define __SUMERRSQRADIALPEAK_H__

#include <string>

#include "boost/type_traits/remove_cv.hpp"
#include "boost/variant/get.hpp"
#include "boost/variant/variant.hpp"

#include "Util/Types.h"
#include "Util/PeakReader.h"
#include "Expression/Parser/function.hpp"

struct SumErrSqRadialPeak {

    static const std::string name;

    Expressions::Result_t operator()(client::function::arguments_t args) {
        if (args.size() != 4) {
            throw OptPilotException("SumErrSqRadialPeak::operator()",
                                    "sumErrSqRadialPeak expects 4 arguments, " + std::to_string(args.size()) + " given");
        }

        meas_filename_ = boost::get<std::string>(args[0]);
        sim_filename_  = boost::get<std::string>(args[1]);
        begin_         = boost::get<double>(args[2]);
        end_           = boost::get<double>(args[3]);

        bool is_valid = true;

        const std::unique_ptr<PeakReader> meas_peaks(new PeakReader(meas_filename_));
        const std::unique_ptr<PeakReader> sim_peaks(new PeakReader(sim_filename_));
        try {
            sim_peaks->parseFile();
            meas_peaks->parseFile();

            if ( end_ < begin_ || end_ < 0 || begin_ < 0 )
                throw OptPilotException("SumErrSqRadialPeak::operator()",
                                        "Error check turn number range");

        } catch (OptPilotException &ex) {
            std::cout << "Caught exception: " << ex.what() << std::endl;
            is_valid = false;
        }

        double sum = 0;
        int nPeaks = end_ - begin_ + 1;

        for (int turn = begin_; turn < end_ + 1; ++turn) {
            double sim_value = 0.0, meas_value = 0.0;
            try {
                sim_peaks->getPeak(turn, sim_value);
                meas_peaks->getPeak(turn, meas_value);
            } catch(OptPilotException &e) {
                std::cout << "Exception while getting value "
                          << "from peak file: " << e.what()
                          << std::endl;
                is_valid = false;
            }
            double val = meas_value - sim_value;
            sum += val * val;
        }

        return boost::make_tuple(std::sqrt(sum) / (double)nPeaks, is_valid);
    }

private:
    std::string meas_filename_;
    std::string sim_filename_;
    int begin_;
    int end_;

    // define a mapping to arguments in argument vector
    boost::tuple<std::string, std::string, int, int> argument_types;
    // :FIXME: remove unused enum
#if 0
    enum {
          meas_filename
        , sim_filename
        , begin
        , end
    } argument_type_id;
#endif
};

#endif