Skip to content

File nponline.cxx

File List > src > utility > nponline.cxx

Go to the documentation of this file

#include "NPApplication.h"
#include "NPDetectorManager.h"
#include "NPException.h"
#include "NPFunction.h"
#include "NPProgressDisplay.h"
#include "NPTerminalColor.h"
#include "NPVDataInput.h"
#include "NPVDataOutput.h"
#include <chrono>
#include <iomanip>
#include <iostream>
using namespace nptool;
using namespace std;

int main(int argc, char** argv) {
  auto app = nptool::Application::InitApplication(argc, argv);
  try {
    // instantiate an application
    app->Start();

    // For Progress Display
    long long event_processed = 0;
    long long event_to_process = -1;
    long long size_to_read = -1;

    // Data Input Raw
    std::shared_ptr<nptool::VDataInput> input_raw;
    if (app->HasFlag("--input-raw")) {
      auto input_raw_arg = app->GetVectorArg("--input-raw");
      if (input_raw_arg.size()) {
        input_raw = app->ConstructDataInput(input_raw_arg[0]);
        if (input_raw) {
          input_raw->Init(input_raw_arg);
        }
        else {
          throw(nptool::Error("nponline", "Fail to construct data input raw : " + input_raw_arg[0]));
        }
        if (input_raw->GetEntries() == 0) {
          throw(nptool::Error("nponline", "No entries to analyse"));
        }
        else {
          nptool::message("green", "core", "nponline  ",
                          "Data input raw:  " + nptool::itoa(input_raw->GetEntries()) + " entries loaded ", true);
          event_to_process = input_raw->GetEntries();
          size_to_read = input_raw->GetFileSize();
        }
      }
      else
        throw(nptool::Error("nponline", "--input-raw flag provided with no arguments, at least one needed"));
    }

    // Data Input Phy
    std::shared_ptr<nptool::VDataInput> input_phy;
    if (app->HasFlag("--input-phy")) {
      auto input_phy_arg = app->GetVectorArg("--input-phy");
      if (input_phy_arg.size()) {
        input_phy = app->ConstructDataInput(input_phy_arg[0]);
        if (input_phy) {
          input_phy->Init(input_phy_arg);
        }
        else {
          throw(nptool::Error("nponline", "Fail to construct data input phy : " + input_phy_arg[0]));
        }
        if (input_phy->GetEntries() == 0) {
          throw(nptool::Error("nponline", "No entries to analyse"));
        }
        else {
          nptool::message("green", "core", "nponline  ",
                          "Data input phy:  " + nptool::itoa(input_phy->GetEntries()) + " entries loaded ", true);
          event_to_process = input_phy->GetEntries();
          size_to_read = input_phy->GetFileSize();
        }
      }
      else
        throw(nptool::Error("nponline", "--input-phy flag provided with no arguments, at least one needed"));
    }
    // Detector Configuration
    if (input_raw)
      app->InitializeDataInputRaw(input_raw);
    if (input_phy)
      app->InitializeDataInputPhysics(input_phy);
    if (!input_raw && !input_phy) {
      message("red", "core", "nponline", "No input provided, stopping. Use --input-raw and/or --input-phy flags.");
      app->Stop();
      return 0;
    }
    // Init detector spectra and Canvas
    app->InitSpectra();

    // User analysis
    std::vector<std::shared_ptr<nptool::VUserAnalysis>> user_analysis;
    if (app->HasFlag("--user-analysis")) {
      auto analysis_arg = app->GetVectorArg("--user-analysis");
      // load all analysis plugin
      for (auto analysis : analysis_arg) {
        app->LoadPlugin(analysis);
        user_analysis.push_back(app->ConstructUserAnalysis(analysis));
        nptool::message("green", "core", "nponline", "User analysis: " + analysis + " loaded ", true);
      }

      for (auto analysis : user_analysis) {
        analysis->Init();
        if (input_phy)
          analysis->SetDataInput(input_phy);
      }
    }

    // User interface displaying spectra
    std::shared_ptr<nptool::VUserInterface> interface;
    if (app->HasFlag("--interface")) {
      auto interface_arg = app->GetVectorArg("--interface");
      if (interface_arg.size() > 0) {
        interface = app->ConstructUserInterface(interface_arg[0]);
        if (interface) {
          interface->Init(interface_arg);
        }
        else {
          throw(nptool::Error("nponline", "Fail to construct user interface: " + interface_arg[0]));
        }
      }
      else {
        throw(nptool::Error("nponline",
                            "--interface flag provided with wrong number of arguments, at least one needed."));
      }
    }
    else
      throw(nptool::Error("nponline", "--interface flag required"));

    auto macro_path = app->GetOnlineMacroPath();
    // keep alive at the end
    bool keep_alive = false;
    bool done = false;
    if (app->HasFlag("--keep-alive")) {
      keep_alive = true;
    }
    // write spectra at the end
    bool write_spectra = false;
    std::string spectra_path = "";
    if (app->HasFlag("--write-spectra")) {
      auto ws_arg = app->GetVectorArg("--write-spectra");
      // load all analysis plugin
      if (ws_arg.size() == 1) {
        write_spectra = true;
        spectra_path = ws_arg[0];
        nptool::message("green", "core", "nponline  ", "Spectra will be saved to : " + ws_arg[0], true);
      }
      else
        throw(nptool::Error("nponline", "--write-spectra take one and only one argument"));
    }

    nptool::ProgressDisplay progress(event_to_process, size_to_read);
    // Main loop
    static unsigned int count = 0;
    while (interface->WaitEvent()) {
      count++;
      if (input_raw) {
        if (!input_raw->GetNextEntry()) {
          if (!keep_alive)
            break;
          else
            done = true;
        }
      }
      if (input_phy) {
        if (!input_phy->GetNextEntry()) {
          if (!keep_alive)
            break;
          else
            done = true;
        }
      }
      if (!done) {
        app->FillSpectra();
        for (auto analysis : user_analysis) {
          analysis->TreatEvent();
        }

        // if (count++ % 1000 == 0)
        //   interface->ExecuteMacro(macro_path);
      }
      if (input_raw)
        progress.AttemptDisplay(event_processed++, input_raw->GetReadSize());
      else if (input_phy)
        progress.AttemptDisplay(event_processed++, input_phy->GetReadSize());
    }
    if (input_raw)
      progress.ForceDisplay(event_processed, input_raw->GetReadSize());
    else if (input_phy)
      progress.ForceDisplay(event_processed, input_phy->GetReadSize());

    // call user analysis end
    for (auto analysis : user_analysis) {
      analysis->End();
    }

    // Write spectra
    if (write_spectra)
      interface->WriteSpectra(spectra_path);

    // Stop the app
    app->Stop();
  }
  catch (nptool::Warning& ex) {
    nptool::DisplayException(ex);
  }
  catch (nptool::Error& ex) {
    nptool::DisplayException(ex);
    app->Stop();
    return 1;
  }

  // any other exception
  catch (...) {
    app->Stop();
    return 1;
  }
  return 0;
}