Skip to content
Snippets Groups Projects
rssm.cpp 20.3 KiB
Newer Older
  • Learn to ignore specific revisions
  • //**************************************************************************************************
    
    //*  FRIDA: fast reliable interactive data analysis
    //*  (C) Joachim Wuttke 1990-, v2(C++) 2001-
    //*  http://apps.jcns.fz-juelich.de/frida
    
    //**************************************************************************************************
    
    Wuttke, Joachim's avatar
    ..  
    Wuttke, Joachim committed
    
    //! \file  rssm.cpp
    //! \brief NRSSM: directly read SPHERES raw data
    
    #include <yaml-cpp/yaml.h>
    
    
    #include "../readplus/ask.hpp"
    
    #include "../trivia/file_ops.hpp"
    #include "../trivia/string_ops.hpp"
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
    #include "mem.hpp"
    
    #include "obj.hpp"
    #include "olf.hpp"
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
    #include "rssm.hpp"
    
    //! All relevant information extracted from one raw-data file from SPHERES.
    
    
    class CRawfileSpheres
    {
    public:
        void RdRawYam(std::ifstream& F_in);
    
        double daq_time_step;
        time_t measured_from;
        time_t measured_until;
    
        double measured_during;
    
        vector<double> rawdata[6];
    
        int maj_syntax, min_syntax, maj_outform, min_outform;
    
    //! Read raw data file, store contents as class variables
    
    void CRawfileSpheres::RdRawYam(std::ifstream& F_in)
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
        string key, val;
    
        CSpec sout;
    
    Wuttke, Joachim's avatar
    ry  
    Wuttke, Joachim committed
    
    
        maj_outform = 5;
        min_outform = 1;
    
    
        const YAML::Node& doc = YAML::Load(F_in);
    
    
        // read Meta:
    
            throw S("no Meta");
    
            YAML::NodeType::value Metatype = doc["Meta"].Type();
    
            if (Metatype != YAML::NodeType::Map && doc["Meta"].size() > 0)
    
                throw S("DATA BUG: Meta is not a MAP");
    
                throw S("DATA BUG: no format in Meta");
    
            val = doc["Meta"]["format"].as<string>();
            if (strncmp(val.c_str(), "acq5.2 for yaml1", 16))
    
                throw "UNEXPECTED DATA: format: " + val + " instead of acq5.2";
    
            throw "failed to read Meta section: " + string(e.what());
    
        // ignore History.
    
        // read Shortpar:
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
            const YAML::Node& spar = doc["Shortpar"];
    
                throw S("DATA BUG: no Shortpar");
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
                throw S("DATA BUG: no Shortpar 'incremental'");
            string val = spar["incremental"].as<string>();
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
                incremental = true;
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
                incremental = false;
            else
                throw "DATA BUG: invalid value [" + val + "] of 'incremental'";
    
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
                throw S("DATA BUG: no Shortpar 'subs_until'");
            val = spar["subs_until"].as<string>();
            char date_string[24];
    
            sscanf(val.c_str(), "%24c", date_string);
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
            struct tm date_broken;
    
            strptime(date_string, "%F %A %H:%M:%S", &date_broken);
            measured_until = mktime(&date_broken);
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
                throw S("DATA BUG: no Shortpar 'ndet'");
            ndet = spar["ndet"].as<int>();
    
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
                throw S("DATA BUG: no Shortpar 'daq_time_step'");
            val = spar["daq_time_step"].as<string>();
            string numval, unit;
    
            triv::string_extract_word(val, &numval, &unit);
            if (unit != "s")
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
                throw "DATA BUG: daq_time_step has unexpected unit '" + unit + "'";
    
            triv::any2dbl(numval, &daq_time_step);
    
            throw "DATA BUG: failed to read Shortpar section: " + string(e.what());
    
        // read EnergyHistograms:
    
                throw S("DATA BUG: no EnergyHistograms");
    
            if (doc["EnergyHistograms"].Type() != YAML::NodeType::Sequence)
    
                throw S("DATA BUG: EnergyHistograms is not a SEQUENCE");
    
            int nEne = doc["EnergyHistograms"].size();
    
            for (int iEne = 0; iEne < nEne; iEne++) {
                if (doc["EnergyHistograms"][iEne].Type() != YAML::NodeType::Sequence)
    
                    throw "DATA BUG: EnergyHistogram[" + S(iEne) + "] is not a SEQUENCE";
    
                val = doc["EnergyHistograms"][iEne][0].as<string>();
                if (!triv::any2dbl(val, &num))
    
                    throw "E-Hist: invalid x-value " + val;
    
                for (int i = 0; i < 4; ++i)
                    rawdata[i].push_back(num);
                for (int i = 0; i < 4; ++i) { // counts
                    // inline Node& Node::operator=(const T& rhs);
    
                    const YAML::Node arr = doc["EnergyHistograms"][iEne][i + 1];
                    if (arr.Type() != YAML::NodeType::Sequence)
                        throw "DATA BUG: EnergyHistogram[" + S(iEne) + "][" + S(i + 1)
                            + "] is not a SEQUENCE";
                    for (int j = 0; j < ndet; ++j) {
                        val = (arr)[j].as<string>();
    
                        //(*arr)[j] >> val;
    
                            throw "E-Hist: invalid count " + val;
    
                for (int i = 0; i < 4; ++i) { // tsteps
                    const YAML::Node arr = (doc["EnergyHistograms"][iEne][i + 1 + 4]);
                    if (arr.Type() != YAML::NodeType::Sequence)
                        throw "DATA BUG: EnergyHistogram[" + S(iEne) + "][" + S(i + 1 + 4)
                            + "] is not a SEQUENCE";
                    for (int j = 0; j < ndet; ++j) {
    
                        val = (arr)[j].as<string>();
                        if (!triv::any2dbl(val, &num))
    
                            throw "E-Hist: invalid tstep " + val;
    
    Wuttke, Joachim's avatar
    ry  
    Wuttke, Joachim committed
            }
    
            throw "BAD BUG: failed to read EnergyHistograms section: " + string(e.what());
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
        }
    
        // read ChopperHistograms:
    
                throw S("no ChopperHistograms");
    
            if (doc["ChopperHistograms"].Type() != YAML::NodeType::Sequence)
    
                throw S("DATA BUG: ChopperHistograms is not a SEQUENCE");
    
            int nCho = doc["ChopperHistograms"].size();
            for (int iCho = 0; iCho < nCho; iCho++) {
                if (doc["ChopperHistograms"][iCho].Type() != YAML::NodeType::Sequence)
    
                    throw "DATA BUG: ChopperHistograms " + S(iCho) + " is not a SEQUENCE";
    
                val = doc["ChopperHistograms"][iCho][0].as<string>();
                if (!triv::any2dbl(val, &num))
    
                    throw "DATA BUG: C-Hist: invalid x-value " + val;
    
                for (int i = 4; i < 6; ++i)
                    rawdata[i].push_back(num);
                for (int i = 4; i < 6; ++i) { // 2 cnts lines
                    const YAML::Node arr = (doc["ChopperHistograms"][iCho][i - 4 + 1]);
                    if (arr.Type() != YAML::NodeType::Sequence)
                        throw "DATA BUG: ChopperHistogram[" + S(iCho) + "][" + S(i - 4 + 1)
                            + "] is not a SEQUENCE";
                    for (int j = 0; j < ndet; ++j) {
                        val = (arr)[j].as<string>();
                        if (!triv::any2dbl(val, &num))
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
                            throw "E-Hist: invalid count " + val;
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
                    }
    
                for (int i = 4; i < 6; ++i) { // 2 time lines
                    const YAML::Node arr = (doc["ChopperHistograms"][iCho][i - 4 + 1 + 2]);
                    if (arr.Type() != YAML::NodeType::Sequence)
                        throw "DATA BUG: ChopperHistogram[" + S(iCho) + "][" + S(i - 4 + 1 + 2)
                            + "] is not a SEQUENCE";
                    for (int j = 0; j < ndet; ++j) {
                        val = (arr)[j].as<string>();
                        if (!triv::any2dbl(val, &num))
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
                            throw "E-Hist: invalid count " + val;
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
                    }
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
            }
    
            throw "DATA BUG: failed to read ChopperHistograms section: " + string(e.what());
    
    //! Read one raw data file.
    
    
    void NRSSM::read_spec(int flag)
    
    
    // flag values (to be OR'ed):
    //    1 save also open
    //    2 save also chop histo
    //    4 save spectra also separately for both directions
    //    8 do not save regular spectrum
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
        file_f = wask("Read SPHERES data from file");
    
        CRawfileSpheres R;
    
        F_in.open(file_f.c_str(), std::fstream::in);
        if (!(F_in.is_open()))
    
            throw "Cannot read " + file_f;
    
    
        double tstep = R.daq_time_step;
    
        vector<double>* raw = R.rawdata;
    
        int ndet = R.ndet;
    
        for (iolf = 0; iolf < 8; ++iolf) {
            olf[iolf] = POld(new COld);
            olf[iolf]->xco = iolf < 4 || iolf > 5 ? CCoord("E", "ueV") : CCoord("phase", "deg");
            olf[iolf]->yco = CCoord("cts", "sec-1");
            olf[iolf]->ZCo.push_back(CCoord("det", ""));
    
        triv::fname_divide(file_f, 0, &name, 0);
        olf[0]->name = name + "left";
        olf[1]->name = name + "right";
        olf[2]->name = name + "open_left";
        olf[3]->name = name + "open_right";
        olf[4]->name = name + "chop_elast";
        olf[5]->name = name + "chop_inela";
    
        olf[6]->name = name;
    
        olf[7]->name = name + "open";
        string doc = "ry" + (flag == 0 ? "" : S(flag + 1)) + " " + file_f;
        olf[0]->log_action(doc + " # refl, left halfspace");
        olf[1]->log_action(doc + " # refl, right halfspace");
        olf[2]->log_action(doc + " # open, left halfspace");
        olf[3]->log_action(doc + " # open, right halfspace");
        olf[4]->log_action(doc + " # elastic");
        olf[5]->log_action(doc + " # inelastic");
        olf[6]->log_action(doc + " # refl");
        olf[7]->log_action(doc + " # open");
    
        for (iolf = 0; iolf < 8; ++iolf) {
            for (int j = 0; j < ndet; ++j) {
                PSpec s(new CSpec);
                s->z.resize(1);
                s->z[0] = PObjInt(new CObjInt(j));
                olf[iolf]->V.push_back(move(s));
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
            }
    
        if (R.maj_outform <= 2) { // old data format
    
            double x, tmeas, count;
            // transfer data from raw arrays:
    
            for (iolf = 0; iolf < 6; ++iolf) {
                for (int iraw = 0; iraw < raw[iolf].size(); iraw += (ndet + 2)) {
    
                    tmeas = raw[iolf][iraw + ndet + 1];
                    if (tmeas < 1)
                        continue;
                    for (int j = 0; j < ndet; ++j) {
                        count = raw[iolf][iraw + 1 + j];
                        olf[iolf]->VS(j)->push_xy(x, count / tmeas / tstep);
    
            for (int ichop = 0; ichop < 2; ++ichop) {
                int iolf0 = ichop * 2;
                int iolf1 = ichop * 2 + 1;
    
                int nline = raw[iolf0].size();
    
                if (raw[iolf1].size() != nline)
    
                    throw S("inconsistent raw array sizes");
    
                for (int iraw = 0; iraw < nline; iraw += (ndet + 2)) {
    
                    tmeas = raw[iolf0][iraw + ndet + 1] + raw[iolf1][iraw + ndet + 1];
                    if (tmeas < 1)
                        continue;
                    for (int j = 0; j < ndet; ++j) {
                        count = raw[iolf0][iraw + 1 + j] + raw[iolf1][iraw + 1 + j];
                        olf[6 + ichop]->VS(j)->push_xy(x, count / tmeas / tstep);
    
                    }
                }
            }
    
        } else { // as of 2008-03-03
            double x, tmeas, count;
            // transfer data from raw arrays:
    
            for (iolf = 0; iolf < 6; ++iolf) {
                for (int iraw = 0; iraw < raw[iolf].size(); iraw += (1 + ndet * 2)) {
    
                    for (int j = 0; j < ndet; ++j) {
                        count = raw[iolf][iraw + 1 + j];
                        if (!(flag & 16)) {
                            tmeas = raw[iolf][iraw + 1 + ndet + j];
                            if (tmeas < 1)
                                continue;
                            count /= (tmeas * tstep);
    
                        olf[iolf]->VS(j)->push_xy(x, count);
    
            for (int ichop = 0; ichop < 2; ++ichop) {
                int iolf0 = ichop * 2;
                int iolf1 = ichop * 2 + 1;
    
                int nline = raw[iolf0].size();
    
                if (raw[iolf1].size() != nline)
    
                    throw S("inconsistent raw array sizes");
    
                for (int iraw = 0; iraw < nline; iraw += (1 + ndet * 2)) {
    
                    for (int j = 0; j < ndet; ++j) {
                        count = raw[iolf0][iraw + 1 + j] + raw[iolf1][iraw + 1 + j];
                        if (!(flag & 16)) {
                            tmeas = raw[iolf0][iraw + 1 + ndet + j] + raw[iolf1][iraw + 1 + ndet + j];
                            if (tmeas < 1)
                                continue;
                            count /= (tmeas * tstep);
    
                        olf[6 + ichop]->VS(j)->push_xy(x, count);
    
        if (flag & 2) {
            SMem::instance()->mem_store(move(olf[4]));
            SMem::instance()->mem_store(move(olf[5]));
    
        if (flag & 2 && flag & 4) {
            SMem::instance()->mem_store(move(olf[2]));
            SMem::instance()->mem_store(move(olf[3]));
    
        if (flag & 4) {
            SMem::instance()->mem_store(move(olf[0]));
            SMem::instance()->mem_store(move(olf[1]));
    
        if (flag & 1) {
            SMem::instance()->mem_store(move(olf[7]));
    
        if (!(flag & 8)) {
            SMem::instance()->mem_store(move(olf[6]));
    
    //! Read a series of raw data files.
    
    void NRSSM::read_series(int flag)
    
    
    // flag values (to be OR'ed):
    //    1 save also open
    
    {
        char tstrg[30];
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
        string fser, fnam, name;
    
        int isub;
        vector<CRawfileSpheres> RR;
    
    
        // Read consolidated files:
        fser = wask("Read SPHERES data from series");
    
        for (isub = 0;; ++isub) {
            fnam = fser + "a" + S(isub);
    
            F_in.open(fnam.c_str(), std::fstream::in);
            if (!(F_in.is_open()))
    
                break;
            // cout << "successfully opened "<<fnam<<"\n";
    
            rf.RdRawYam(F_in);
            RR.push_back(rf);
    
        int nsub = RR.size();
    
            throw "could not open file " + fnam;
    
            throw S("series contains just one spectrum -> use a simpler method");
    
        printf("successfully read %i files\n", nsub);
    
        double mean_time = (RR[nsub - 1].measured_until - RR[0].measured_until) / nsub;
        printf("mean measuring time %g seconds per file\n", mean_time);
        t = (time_t)(RR[0].measured_until - mean_time);
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
        struct tm tlocal;
    
        strftime(tstrg, 30, "%F %b %H:%M:%S", localtime_r(&t, &tlocal));
        printf("measurement times relative to start time %s\n", tstrg);
        for (isub = 0; isub < nsub; ++isub)
            RR[isub].measured_at =
                RR[isub].measured_until - RR[0].measured_until + (int)(mean_time / 2);
    
    
        // Get parameters, check consistency:
    
        int ndet = RR[0].ndet;
    
        printf("used %i detectors\n", ndet);
    
        double tstep = RR[0].daq_time_step;
        bool incremental_in = RR[0].incremental;
    
    
        for (isub = 1; isub < nsub; ++isub) {
            if (RR[isub].ndet != ndet)
                throw "inconsistent no of det: file " + S(isub) + " has " + S(RR[isub].ndet)
                    + " instead of " + S(ndet);
            if (RR[isub].daq_time_step != tstep)
    
                throw S("inconsistent time step");
    
            if (RR[isub].incremental != incremental_in)
    
                throw S("inconsistent increment status");
    
        POld olf[2];
        int iolf;
    
        for (int iolf = 0; iolf < 2; ++iolf)
            olf[iolf] = POld(new COld);
    
        for (iolf = 0; iolf < 2; ++iolf) {
            olf[iolf]->log_action("acquire data from series" + fser);
            olf[iolf]->xco = CCoord("E", "ueV");
            olf[iolf]->yco = CCoord("cts", "sec-1");
            olf[iolf]->ZCo.push_back(CCoord("#sub", ""));
            olf[iolf]->ZCo.push_back(CCoord("det", ""));
    
        triv::fname_divide(fser, 0, &name, 0);
    
        olf[0]->name = name;
    
        olf[1]->name = name + "open";
        olf[0]->log_action("refl, average over both halfspaces");
        olf[1]->log_action("open, average over both halfspaces");
    
        for (isub = 0; isub < nsub; ++isub) {
    
            // ? = (double)RR[isub].measured_at/3600;
    
            for (j = 0; j < ndet; ++j) {
                PSpec s(new CSpec);
                s->z.resize(2);
                s->z[0] = PObjInt(new CObjInt(isub));
                s->z[1] = PObjInt(new CObjInt(j));
                for (iolf = 0; iolf < 2; ++iolf)
                    olf[iolf]->V.push_back(move(s));
    
        if (RR[0].maj_outform >= 3) {
            printf("new format\n");
            nE = RR[0].rawdata[0].size() / (1 + ndet * 2);
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
            // Reverse incrementation?
    
            if (incremental_in) {
                printf("reversing incrementation\n");
                for (isub = nsub - 1; isub >= 1; --isub) {
                    for (int iarr = 0; iarr < 4; ++iarr) {
                        for (int iE = 0; iE < nE; ++iE) {
                            for (j = 1; j < 1 + ndet * 2; ++j) {
                                RR[isub].rawdata[iarr][iE * (1 + ndet * 2) + j] -=
                                    RR[isub - 1].rawdata[iarr][iE * (1 + ndet * 2) + j];
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
            // Transfer data from raw arrays, sum over halfspaces:
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
            double x, tmeas, count;
            int iraw;
    
            for (isub = 0; isub < nsub; ++isub) {
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
                raw = RR[isub].rawdata;
    
                for (int ichop = 0; ichop < 2; ++ichop) {
                    int iolf0 = ichop * 2;
                    int iolf1 = ichop * 2 + 1;
                    if (raw[iolf1].size() / (1 + ndet * 2) != nE) {
                        printf(
                            "inconsistent raw array sizes:\n  chop %i raw1 %i nE %i\n", ichop,
                            (int)raw[iolf1].size(), nE);
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
                        return;
                    }
    
                    for (int iE = 0; iE < nE; ++iE) {
                        iraw = iE * (1 + ndet * 2);
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
                        x = raw[iolf0][iraw];
    
                        for (j = 0; j < ndet; ++j) {
                            tmeas = raw[iolf0][iraw + ndet + 1 + j] + raw[iolf1][iraw + ndet + 1 + j];
                            if (tmeas < 1)
                                continue;
                            count = raw[iolf0][iraw + 1 + j] + raw[iolf1][iraw + 1 + j];
                            olf[ichop]->VS(isub * ndet + j)->push_xy(x, count / tmeas / tstep);
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
        } else {
    
            printf("old format\n");
            nE = RR[0].rawdata[0].size() / (ndet + 2);
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
            // Reverse incrementation?
    
            if (incremental_in) {
                printf("reversing incrementation\n");
                for (isub = nsub - 1; isub >= 1; --isub) {
                    for (int iarr = 0; iarr < 4; ++iarr) {
                        for (int iE = 0; iE < nE; ++iE) {
                            for (j = 1; j < ndet + 2; ++j) {
                                RR[isub].rawdata[iarr][iE * (ndet + 2) + j] -=
                                    RR[isub - 1].rawdata[iarr][iE * (ndet + 2) + j];
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
                            }
                        }
                    }
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
            }
    
            // Transfer data from raw arrays, sum over halfspaces:
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
            double x, tmeas, count;
            int iraw;
    
            for (isub = 0; isub < nsub; ++isub) {
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
                raw = RR[isub].rawdata;
    
                for (int ichop = 0; ichop < 2; ++ichop) {
                    int iolf0 = ichop * 2;
                    int iolf1 = ichop * 2 + 1;
                    if (raw[iolf1].size() / (ndet + 2) != nE) {
                        printf("inconsistent raw array sizes\n");
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
                        return;
                    }
    
                    for (int iE = 0; iE < nE; ++iE) {
                        iraw = iE * (ndet + 2);
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
                        x = raw[iolf0][iraw];
    
                        tmeas = raw[iolf0][iraw + ndet + 1] + raw[iolf1][iraw + ndet + 1];
                        if (tmeas < 1)
                            continue;
                        for (j = 0; j < ndet; ++j) {
                            count = raw[iolf0][iraw + 1 + j] + raw[iolf1][iraw + 1 + j];
                            olf[ichop]->VS(isub * ndet + j)->push_xy(x, count / tmeas / tstep);
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
                        }
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
    
    
        if (flag & 1) {
            SMem::instance()->mem_store(move(olf[1]));
    
        if (1) {
            SMem::instance()->mem_store(move(olf[0]));