Пример #1
0
/*
 * Write a certain number of log entries (from beginning) to file
 */
void ProcessDasNexusLog::writeLogtoFile(API::MatrixWorkspace_sptr ws,
                                        std::string logname,
                                        size_t numentriesoutput,
                                        std::string outputfilename) {
  // 1. Get log
  Kernel::Property *log = ws->run().getProperty(logname);
  Kernel::TimeSeriesProperty<double> *tslog =
      dynamic_cast<Kernel::TimeSeriesProperty<double> *>(log);
  if (!tslog)
    throw std::runtime_error("Invalid time series log: it could not be cast "
                             "(interpreted) as a time series property");
  std::vector<Kernel::DateAndTime> times = tslog->timesAsVector();
  std::vector<double> values = tslog->valuesAsVector();

  // 2. Write out
  std::ofstream ofs;
  ofs.open(outputfilename.c_str(), std::ios::out);
  ofs << "# Absolute Time (nanosecond)\tPulse Time (nanosecond)\tTOF (ms)\n";

  Kernel::DateAndTime prevtime(0);
  std::vector<double> tofs;

  for (size_t i = 0; i < numentriesoutput; i++) {
    Kernel::DateAndTime tnow = times[i];

    if (tnow > prevtime) {
      // (a) Process previous logs
      std::sort(tofs.begin(), tofs.end());
      for (double tof : tofs) {
        Kernel::DateAndTime temptime =
            prevtime + static_cast<int64_t>(tof * 100);
        ofs << temptime.totalNanoseconds() << "\t" << tnow.totalNanoseconds()
            << "\t" << tof * 0.1 << '\n';
      }
      // (b) Clear
      tofs.clear();
      // (c) Update time
      prevtime = tnow;
    }

    // (d) Push the current value
    tofs.push_back(values[i]);
  } // ENDFOR
  // Clear the last
  if (!tofs.empty()) {
    // (a) Process previous logs: note value is in unit of 100 nano-second
    std::sort(tofs.begin(), tofs.end());
    for (double tof : tofs) {
      Kernel::DateAndTime temptime = prevtime + static_cast<int64_t>(tof * 100);
      ofs << temptime.totalNanoseconds() << "\t" << prevtime.totalNanoseconds()
          << "\t" << tof * 0.1 << '\n';
    }
  } else {
    throw std::runtime_error("Impossible for this to happen!");
  }

  ofs.close();
} // END Function
Пример #2
0
/*
 * Convert DAS log to a vector of absolute time
 * @param  orderedtofs: tofs with abstimevec
 */
void ProcessDasNexusLog::convertToAbsoluteTime(
    API::MatrixWorkspace_sptr ws, std::string logname,
    std::vector<Kernel::DateAndTime> &abstimevec,
    std::vector<double> &orderedtofs) {
  // 1. Get log
  Kernel::Property *log = ws->run().getProperty(logname);
  Kernel::TimeSeriesProperty<double> *tslog =
      dynamic_cast<Kernel::TimeSeriesProperty<double> *>(log);
  if (!tslog)
    throw std::runtime_error("Invalid time series log: it could not be cast "
                             "(interpreted) as a time series property");
  std::vector<Kernel::DateAndTime> times = tslog->timesAsVector();
  std::vector<double> values = tslog->valuesAsVector();

  // 2. Get converted
  size_t numsamepulses = 0;
  std::vector<double> tofs;
  Kernel::DateAndTime prevtime(0);

  for (size_t i = 0; i < times.size(); i++) {
    Kernel::DateAndTime tnow = times[i];
    if (tnow > prevtime) {
      // (a) Process previous logs
      std::sort(tofs.begin(), tofs.end());
      for (size_t j = 0; j < tofs.size(); j++) {
        Kernel::DateAndTime temptime =
            prevtime + static_cast<int64_t>(tofs[j] * 100);
        abstimevec.push_back(temptime);
        orderedtofs.push_back(tofs[j]);
      }
      // (b) Clear
      tofs.clear();
      // (c) Update time
      prevtime = tnow;
    } else {
      numsamepulses++;
    }
    // (d) Push the current value
    tofs.push_back(values[i]);
  } // ENDFOR
  // Clear the last
  if (!tofs.empty()) {
    // (a) Process previous logs: note value is in unit of 100 nano-second
    std::sort(tofs.begin(), tofs.end());
    for (size_t j = 0; j < tofs.size(); j++) {
      Kernel::DateAndTime temptime =
          prevtime + static_cast<int64_t>(tofs[j] * 100);
      abstimevec.push_back(temptime);
      orderedtofs.push_back(tofs[j]);
    }
  } else {
    throw std::runtime_error("Impossible for this to happen!");
  }

  return;
} // END Function
Пример #3
0
void AddSinglePointTimeSeriesProperty(API::LogManager &logManager,
                                      const std::string &time,
                                      const std::string &name,
                                      const TYPE value) {
  // create time series property and add single value
  Kernel::TimeSeriesProperty<TYPE> *p =
      new Kernel::TimeSeriesProperty<TYPE>(name);
  p->addValue(time, value);

  // add to log manager
  logManager.addProperty(p);
}
Пример #4
0
/*
 * Check log in workspace
 */
void ProcessDasNexusLog::checkLog(API::MatrixWorkspace_sptr ws,
                                  std::string logname) {
  // 1. Get log
  Kernel::Property *log = ws->run().getProperty(logname);
  if (!log) {
    g_log.error() << "Log " << logname << " does not exist!" << std::endl;
    throw std::invalid_argument("Non-exising log name");
  }
  Kernel::TimeSeriesProperty<double> *tslog =
      dynamic_cast<Kernel::TimeSeriesProperty<double> *>(log);
  if (!tslog) {
    g_log.error() << "Log " << logname << " is not time series log"
                  << std::endl;
    throw std::invalid_argument("Log type error!");
  }

  // 2. Survey
  std::vector<Kernel::DateAndTime> times = tslog->timesAsVector();
  g_log.information() << "Entries of times = " << times.size() << std::endl;
  size_t countsame = 0;
  size_t countinverse = 0;
  for (size_t i = 1; i < times.size(); i++) {
    Kernel::DateAndTime tprev = times[i - 1];
    Kernel::DateAndTime tpres = times[i];
    if (tprev == tpres)
      countsame++;
    else if (tprev > tpres)
      countinverse++;
  }

  // 3. Output
  Kernel::DateAndTime t0(ws->run().getProperty("run_start")->value());
  Kernel::time_duration dts = times[0] - t0;
  Kernel::time_duration dtf = times[times.size() - 1] - t0;
  size_t f = times.size() - 1;

  g_log.information() << "Number of Equal Time Stamps    = " << countsame
                      << std::endl;
  g_log.information() << "Number of Inverted Time Stamps = " << countinverse
                      << std::endl;
  g_log.information() << "Run Start = " << t0.totalNanoseconds() << std::endl;
  g_log.information() << "First Log (Absolute Time, Relative Time): "
                      << times[0].totalNanoseconds() << ", "
                      << Kernel::DateAndTime::nanosecondsFromDuration(dts)
                      << std::endl;
  g_log.information() << "Last  Log (Absolute Time, Relative Time): "
                      << times[f].totalNanoseconds() << ", "
                      << Kernel::DateAndTime::nanosecondsFromDuration(dtf)
                      << std::endl;

  return;
}
Пример #5
0
    /** Creates a TimeSeriesProperty<bool> showing times when a particular period was active.
    *  @param period :: The data period
    *  @return the times when requested period was active
    */
    Kernel::Property*  LoadRaw::createPeriodLog(int period)const
    {
      Kernel::TimeSeriesProperty<int>* periods = dynamic_cast< Kernel::TimeSeriesProperty<int>* >(m_perioids.get());
      if(!periods) return 0;
      std::ostringstream ostr;
      ostr<<period;
      Kernel::TimeSeriesProperty<bool>* p = new Kernel::TimeSeriesProperty<bool> ("period "+ostr.str());
      std::map<Kernel::DateAndTime, int> pMap = periods->valueAsMap();
      std::map<Kernel::DateAndTime, int>::const_iterator it = pMap.begin();
      if (it->second != period)
        p->addValue(it->first,false);
      for(;it!=pMap.end();++it)
        p->addValue(it->first, (it->second == period) );

      return p;
    }
Пример #6
0
/** Export part of designated log to an file in column format and a output file
  * @param logname :: name of log to export
  * @param numentries :: number of log entries to export
  * @param outputeventws :: boolean.  output workspace is event workspace if
 * true.
 */
void ExportTimeSeriesLog::exportLog(string logname, int numentries,
                                    bool outputeventws) {

  // 1.  Get log, time, and etc.
  std::vector<Kernel::DateAndTime> times;
  std::vector<double> values;

  if (logname.size() > 0) {
    // Log
    Kernel::TimeSeriesProperty<double> *tlog =
        dynamic_cast<Kernel::TimeSeriesProperty<double> *>(
            m_dataWS->run().getProperty(logname));
    if (!tlog) {
      std::stringstream errmsg;
      errmsg << "TimeSeriesProperty Log " << logname
             << " does not exist in workspace " << m_dataWS->getName();
      g_log.error(errmsg.str());
      throw std::invalid_argument(errmsg.str());
    }
    times = tlog->timesAsVector();
    values = tlog->valuesAsVector();
  } else {
    throw std::runtime_error("Log name cannot be left empty.");
  }

  // 2. Determine number of export log
  if (numentries == EMPTY_INT()) {
    numentries = static_cast<int>(times.size());
  } else if (numentries <= 0) {
    stringstream errmsg;
    errmsg << "For Export Log, NumberEntriesExport must be greater than 0.  "
              "Input = " << numentries;
    g_log.error(errmsg.str());
    throw std::runtime_error(errmsg.str());
  } else if (static_cast<size_t>(numentries) > times.size()) {
    numentries = static_cast<int>(times.size());
  }

  // 3. Create otuput workspace
  if (outputeventws) {
    setupEventWorkspace(numentries, times, values);
  } else {
    setupWorkspace2D(numentries, times, values);
  }

  return;
}
Пример #7
0
/// Run the LoadLog Child Algorithm
void LoadMuonNexus1::runLoadLog(DataObjects::Workspace2D_sptr localWorkspace) {
  IAlgorithm_sptr loadLog = createChildAlgorithm("LoadMuonLog");
  // Pass through the same input filename
  loadLog->setPropertyValue("Filename", m_filename);
  // Set the workspace property to be the same one filled above
  loadLog->setProperty<MatrixWorkspace_sptr>("Workspace", localWorkspace);

  // Now execute the Child Algorithm. Catch and log any error, but don't stop.
  try {
    loadLog->execute();
  } catch (std::runtime_error &) {
    g_log.error("Unable to successfully run LoadLog Child Algorithm");
  } catch (std::logic_error &) {
    g_log.error("Unable to successfully run LoadLog Child Algorithm");
  }

  if (!loadLog->isExecuted())
    g_log.error("Unable to successfully run LoadLog Child Algorithm");

  NXRoot root(m_filename);

  try {
    NXChar orientation = root.openNXChar("run/instrument/detector/orientation");
    // some files have no data there
    orientation.load();

    if (orientation[0] == 't') {
      Kernel::TimeSeriesProperty<double> *p =
          new Kernel::TimeSeriesProperty<double>("fromNexus");
      std::string start_time = root.getString("run/start_time");
      p->addValue(start_time, -90.0);
      localWorkspace->mutableRun().addLogData(p);
      setProperty("MainFieldDirection", "Transverse");
    } else {
      setProperty("MainFieldDirection", "Longitudinal");
    }
  } catch (...) {
    setProperty("MainFieldDirection", "Longitudinal");
  }

  auto &run = localWorkspace->mutableRun();
  int n = static_cast<int>(m_numberOfPeriods);
  ISISRunLogs runLogs(run, n);
  runLogs.addStatusLog(run);
}
Пример #8
0
/** Write value from a RunInfo property (i.e., log) to a stream
    */
void writeLogValue(std::ostream &os, const Run &runinfo,
                   const std::string &name,
                   const std::string &defValue = "UNKNOWN") {
  // Return without property exists
  if (!runinfo.hasProperty(name)) {
    os << defValue;
    return;
  }

  // Get handler of property
  Kernel::Property *prop = runinfo.getProperty(name);

  // Return without a valid pointer to property
  if (prop == NULL) {
    os << defValue;
    return;
  }

  // Get value
  Kernel::TimeSeriesProperty<double> *log =
      dynamic_cast<Kernel::TimeSeriesProperty<double> *>(prop);
  if (log) {
    // Time series to get mean
    os << log->getStatistics().mean;
  } else {
    // None time series
    os << prop->value();
  }

  // Unit
  std::string units = prop->units();
  if (!units.empty())
    os << " " << units;

  return;
}
Пример #9
0
/*
 * Merge 2 TimeSeries log together for the third one
 * @param ilogname1:  name of log 1 to be merged
 * @param ilogname2:  name of log 2 to be merged
 * @param ologname:   name of the merged log to be added to workspace
 */
void Merge2WorkspaceLogs::mergeLogs(std::string ilogname1,
                                    std::string ilogname2, std::string ologname,
                                    bool resetlogvalue, double logvalue1,
                                    double logvalue2) {

  // 1. Get log
  Kernel::TimeSeriesProperty<double> *p1 = getTimeSeriesLog(ilogname1);
  Kernel::TimeSeriesProperty<double> *p2 = getTimeSeriesLog(ilogname2);

  std::vector<Kernel::DateAndTime> times1 = p1->timesAsVector();
  std::vector<Kernel::DateAndTime> times2 = p2->timesAsVector();

  Kernel::TimeSeriesProperty<double> *rp =
      new Kernel::TimeSeriesProperty<double>(ologname);

  // 2. Merge
  size_t index1 = 0;
  size_t index2 = 0;
  bool icont = true;

  Kernel::DateAndTime tmptime;
  double tmpvalue;
  bool launch1 = true;
  ;
  bool nocomparison = false;

  std::cout << "Merging!!" << std::endl;

  while (icont) {
    // std::cout << "index1 = " << index1 << ", index2 = " << index2 << ",
    // launch1 = " << launch1 << ", nocomparison = " << nocomparison <<
    // std::endl;

    // i. Determine which log to work on
    if (!nocomparison) {
      if (times1[index1] < times2[index2]) {
        launch1 = true;
      } else {
        launch1 = false;
      }
    }

    // ii. Retrieve data from source log
    if (launch1) {
      // Add log1
      tmptime = times1[index1];
      if (resetlogvalue) {
        tmpvalue = logvalue1;
      } else {
        tmpvalue = p1->getSingleValue(tmptime);
      }
    } else {
      // Add log 2
      tmptime = times2[index2];
      if (resetlogvalue) {
        tmpvalue = logvalue2;
      } else {
        tmpvalue = p2->getSingleValue(tmptime);
      }
    }

    // iii. Add log
    rp->addValue(tmptime, tmpvalue);

    // iv. Increase step
    if (launch1) {
      index1++;
    } else {
      index2++;
    }

    // v. Determine status
    if (nocomparison) {
      // no comparison case: transition to terminate while
      if (launch1 && index1 >= times1.size()) {
        icont = false;
      } else if (!launch1 && index2 >= times2.size()) {
        icont = false;
      }
    } else {
      // still in comparison: transition to no-comparison
      if (launch1 && index1 >= times1.size()) {
        nocomparison = true;
        launch1 = false;
      } else if (!launch1 && index2 >= times2.size()) {
        nocomparison = true;
        launch1 = true;
      }
    } // ENDIFELSE nocomparison
  }   // ENDWHILE

  // 3. Check and add new log
  int newlogsize = rp->size();
  if (size_t(newlogsize) != (times1.size() + times2.size())) {
    g_log.error()
        << "Resulted log size is not equal to the sum of two source log sizes"
        << std::endl;
    throw;
  }

  matrixWS->mutableRun().addProperty(rp);

  return;
}
Пример #10
0
    /**
     * reads the .log stream and creates timeseries property and sets that to the run object
     * @param logFileStream :: The stream of the log file (data).
     * @param logFileName :: The name of the log file to load.
     * @param run :: The run information object
     */
    void LoadLog::loadThreeColumnLogFile(std::ifstream& logFileStream, std::string logFileName, API::Run& run)
    {
      std::string str;
      std::string propname;
      Mantid::Kernel::TimeSeriesProperty<double>* logd = 0;
      Mantid::Kernel::TimeSeriesProperty<std::string>* logs = 0;
      std::map<std::string,Kernel::TimeSeriesProperty<double>*> dMap;
      std::map<std::string,Kernel::TimeSeriesProperty<std::string>*> sMap;
      typedef std::pair<std::string,Kernel::TimeSeriesProperty<double>* > dpair;
      typedef std::pair<std::string,Kernel::TimeSeriesProperty<std::string>* > spair;
      kind l_kind(LoadLog::empty);
      bool isNumeric(false);

      if (!logFileStream)
      {
        throw std::invalid_argument("Unable to open file " + m_filename);
      }

      while(Mantid::Kernel::Strings::extractToEOL(logFileStream,str))
      {
        if ( !isDateTimeString(str) )
        {
          throw std::invalid_argument("File" + logFileName + " is not a standard ISIS log file. Expected to be a file starting with DateTime String format.");
        }

        if (!Kernel::TimeSeriesProperty<double>::isTimeString(str) || (str[0]=='#'))
        {    //if the line doesn't start with a time read the next line
          continue;
        }

        std::stringstream line(str);
        std::string timecolumn;
        line >> timecolumn;

        std::string blockcolumn;
        line >> blockcolumn;
        l_kind = classify(blockcolumn);

        if ( LoadLog::string != l_kind )
        {
          throw std::invalid_argument("ISIS log file contains unrecognised second column entries:" + logFileName);
        }

        std::string valuecolumn;
        line >> valuecolumn;
        l_kind = classify(valuecolumn);

        if ( LoadLog::string != l_kind && LoadLog::number != l_kind)
        {
          continue; //no value defined, just skip this entry
        }

        // column two in .log file is called block column
        propname = stringToLower(blockcolumn);
        //check if the data is numeric
        std::istringstream istr(valuecolumn);
        double dvalue;
        istr >> dvalue;
        isNumeric = !istr.fail();

        if (isNumeric)
        {
          std::map<std::string,Kernel::TimeSeriesProperty<double>*>::iterator ditr = dMap.find(propname);
          if(ditr != dMap.end())
          {
            Kernel::TimeSeriesProperty<double>* prop = ditr->second;
            if (prop) prop->addValue(timecolumn,dvalue);
          }
          else
          {
            logd = new Kernel::TimeSeriesProperty<double>(propname);
            logd->addValue(timecolumn,dvalue);
            dMap.insert(dpair(propname,logd));
          }
        }
        else
        {
          std::map<std::string,Kernel::TimeSeriesProperty<std::string>*>::iterator sitr = sMap.find(propname);
          if(sitr != sMap.end())
          {
            Kernel::TimeSeriesProperty<std::string>* prop = sitr->second;
            if (prop) prop->addValue(timecolumn,valuecolumn);
          }
          else
          {
            logs = new Kernel::TimeSeriesProperty<std::string>(propname);
            logs->addValue(timecolumn,valuecolumn);
            sMap.insert(spair(propname,logs));
          }
        }
      }
      try
      {
        std::map<std::string,Kernel::TimeSeriesProperty<double>*>::const_iterator itr = dMap.begin();
        for(;itr != dMap.end(); ++itr)
        {
          run.addLogData(itr->second);
        }
        std::map<std::string,Kernel::TimeSeriesProperty<std::string>*>::const_iterator sitr = sMap.begin();
        for(;sitr!=sMap.end();++sitr)
        {
          run.addLogData(sitr->second);
        }
      }
      catch(std::invalid_argument &e)
      {
        g_log.warning() << e.what();
      }
      catch(Exception::ExistsError&e)
      {
        g_log.warning() << e.what();
      }
    }
Пример #11
0
/** Export part of designated log to an file in column format and a output file
 * @brief ExportTimeSeriesLog::exportLog
 * @param logname ::  name of log to export
 * @param timeunit :: unit of time for input start/stop time and output
 * @param starttime :: relative start time of the output time series log
 * @param stoptime :: relative stop time of the output time series log
 * @param exportepoch :: flag to output time as epoch time/absolute time
 * @param outputeventws :: boolean.  output workspace is event workspace if
 * @param numentries :: number of log entries to export
 */
void ExportTimeSeriesLog::exportLog(const std::string &logname,
                                    const std::string timeunit,
                                    const double &starttime,
                                    const double &stoptime,
                                    const bool exportepoch, bool outputeventws,
                                    int numentries) {

  // Get log, time, and etc.
  std::vector<Kernel::DateAndTime> times;
  std::vector<double> values;

  if (logname.size() > 0) {
    // Log
    Kernel::TimeSeriesProperty<double> *tlog =
        dynamic_cast<Kernel::TimeSeriesProperty<double> *>(
            m_inputWS->run().getProperty(logname));
    if (!tlog) {
      std::stringstream errmsg;
      errmsg << "TimeSeriesProperty Log " << logname
             << " does not exist in workspace " << m_inputWS->getName();
      g_log.error(errmsg.str());
      throw std::invalid_argument(errmsg.str());
    }
    times = tlog->timesAsVector();
    values = tlog->valuesAsVector();
  } else {
    throw std::runtime_error("Log name cannot be left empty.");
  }

  // Get start time, stop time and unit factor
  double timeunitfactor = 1.;
  if (timeunit.compare("Seconds") == 0)
    timeunitfactor = 1.E-9;

  // Get index for start time
  size_t i_start = 0;
  size_t i_stop = times.size() - 1;
  // Rule out the case that start time is behind last log entry
  bool i_start_cal = false;
  if (starttime != EMPTY_DBL()) {
    int64_t timerangens =
        times.back().totalNanoseconds() - times.front().totalNanoseconds();
    double timerange = static_cast<double>(timerangens) * timeunitfactor;
    g_log.debug() << "Time range is " << timerange << ", Start time is "
                  << starttime << "\n";
    if (timerange < starttime) {
      i_start = times.size() - 1;
      i_start_cal = true;
    }
  }

  if ((!i_start_cal) && (starttime != EMPTY_DBL() || stoptime != EMPTY_DBL())) {
    bool export_partial = calculateTimeSeriesRangeByTime(
        times, starttime, i_start, stoptime, i_stop, timeunitfactor);
    if (!export_partial)
      throw std::runtime_error(
          "Unable to find proton_charge for run start time. "
          "Failed to get partial time series.");
  }

  // Determine number of export log
  if (numentries == EMPTY_INT()) {
    numentries = static_cast<int>(times.size());
  } else if (numentries <= 0) {
    stringstream errmsg;
    errmsg << "For Export Log, NumberEntriesExport must be greater than 0.  "
              "Input = " << numentries;
    g_log.error(errmsg.str());
    throw std::runtime_error(errmsg.str());
  } else if (static_cast<size_t>(numentries) > times.size()) {
    numentries = static_cast<int>(times.size());
  }

  // Create otuput workspace
  if (outputeventws) {
    setupEventWorkspace(i_start, i_stop, numentries, times, values,
                        exportepoch);
  } else {
    setupWorkspace2D(i_start, i_stop, numentries, times, values, exportepoch,
                     timeunitfactor);
  }

  return;
}
Пример #12
0
/*
 * Add and check log from processed absolute time stamps
 */
void ProcessDasNexusLog::addLog(API::MatrixWorkspace_sptr ws,
                                std::vector<Kernel::DateAndTime> timevec,
                                double unifylogvalue, std::string logname,
                                std::vector<Kernel::DateAndTime> pulsetimes,
                                std::vector<double> orderedtofs, bool docheck) {
  // 1. Do some static
  g_log.notice() << "Vector size = " << timevec.size() << std::endl;
  double sum1dtms = 0.0; // sum(dt^2)
  double sum2dtms = 0.0; // sum(dt^2)
  size_t numinvert = 0;
  size_t numsame = 0;
  size_t numnormal = 0;
  double maxdtms = 0;
  double mindtms = 1.0E20;
  size_t numdtabove10p = 0;
  size_t numdtbelow10p = 0;

  double sampledtms = 0.00832646 * 1.0E6;
  double dtmsA10p = sampledtms * 1.1;
  double dtmsB10p = sampledtms / 1.0;

  for (size_t i = 1; i < timevec.size(); i++) {
    int64_t dtns =
        timevec[i].totalNanoseconds() - timevec[i - 1].totalNanoseconds();
    double dtms = static_cast<double>(dtns) * 1.0E-3;

    sum1dtms += dtms;
    sum2dtms += dtms * dtms;
    if (dtns == 0)
      numsame++;
    else if (dtns < 0)
      numinvert++;
    else
      numnormal++;

    if (dtms > maxdtms)
      maxdtms = dtms;
    if (dtms < mindtms)
      mindtms = dtms;

    if (dtms > dtmsA10p)
      numdtabove10p++;
    else if (dtms < dtmsB10p)
      numdtbelow10p++;

  } // ENDFOR

  double dt = sum1dtms / static_cast<double>(timevec.size()) * 1.0E-6;
  double stddt =
      sqrt(sum2dtms / static_cast<double>(timevec.size()) * 1.0E-12 - dt * dt);

  g_log.notice() << "Normal   dt = " << numnormal << std::endl;
  g_log.notice() << "Zero     dt = " << numsame << std::endl;
  g_log.notice() << "Negative dt = " << numinvert << std::endl;
  g_log.notice() << "Avg d(T) = " << dt << " seconds +/- " << stddt
                 << ",  Frequency = " << 1.0 / dt << std::endl;
  g_log.notice() << "d(T) (unit ms) is in range [" << mindtms << ", " << maxdtms
                 << "]" << std::endl;
  g_log.notice() << "Number of d(T) 10% larger than average  = "
                 << numdtabove10p << std::endl;
  g_log.notice() << "Number of d(T) 10% smaller than average = "
                 << numdtbelow10p << std::endl;

  g_log.notice() << "Size of timevec, pulsestimes, orderedtofs = "
                 << timevec.size() << ", " << pulsetimes.size() << ", "
                 << orderedtofs.size() << std::endl;

  if (docheck) {
    exportErrorLog(ws, timevec, pulsetimes, orderedtofs, 1 / (0.5 * 240.1));
    calDistributions(timevec, 1 / (0.5 * 240.1));
  }

  // 2. Add log
  Kernel::TimeSeriesProperty<double> *newlog =
      new Kernel::TimeSeriesProperty<double>(logname);
  for (size_t i = 0; i < timevec.size(); i++) {
    newlog->addValue(timevec[i], unifylogvalue);
  }
  ws->mutableRun().addProperty(newlog, true);

  return;
}
Пример #13
0
/** Executes the algorithm. Reading in the file and creating and populating
*  the output workspace
*
*  @throw Exception::FileError If the Nexus file cannot be found/opened
*  @throw std::invalid_argument If the optional properties are set to invalid
*values
*/
void LoadNexusLogs::exec() {
  std::string filename = getPropertyValue("Filename");
  MatrixWorkspace_sptr workspace = getProperty("Workspace");

  // Find the entry name to use (normally "entry" for SNS, "raw_data_1" for
  // ISIS)
  std::string entry_name = LoadTOFRawNexus::getEntryName(filename);

  ::NeXus::File file(filename);
  // Find the root entry
  try {
    file.openGroup(entry_name, "NXentry");
  } catch (::NeXus::Exception &) {
    throw std::invalid_argument("Unknown NeXus file format found in file '" +
                                filename + "'");
  }

  /// Use frequency start for Monitor19 and Special1_19 logs with "No Time" for
  /// SNAP
  try {
    file.openPath("DASlogs");
    try {
      file.openGroup("frequency", "NXlog");
      try {
        file.openData("time");

        //----- Start time is an ISO8601 string date and time. ------
        try {
          file.getAttr("start", freqStart);

        } catch (::NeXus::Exception &) {
          // Some logs have "offset" instead of start
          try {
            file.getAttr("offset", freqStart);
          } catch (::NeXus::Exception &) {
            g_log.warning() << "Log entry has no start time indicated.\n";
            file.closeData();
            throw;
          }
        }
        file.closeData();
      } catch (::NeXus::Exception &) {
        // No time. This is not an SNS SNAP file
      }
      file.closeGroup();
    } catch (::NeXus::Exception &) {
      // No time. This is not an SNS frequency group
    }
    file.closeGroup();
  } catch (::NeXus::Exception &) {
    // No time. This is not an SNS group
  }
  // print out the entry level fields
  std::map<std::string, std::string> entries = file.getEntries();
  std::map<std::string, std::string>::const_iterator iend = entries.end();
  for (std::map<std::string, std::string>::const_iterator it = entries.begin();
       it != iend; ++it) {
    std::string group_name(it->first);
    std::string group_class(it->second);
    if (group_name == "DASlogs" || group_class == "IXrunlog" ||
        group_class == "IXselog" || group_name == "framelog") {
      loadLogs(file, group_name, group_class, workspace);
    }
    if (group_class == "IXperiods") {
      loadNPeriods(file, workspace);
    }
  }

  // If there's measurement information, load that info as logs.
  loadAndApplyMeasurementInfo(&file, *workspace);

  // Freddie Akeroyd 12/10/2011
  // current ISIS implementation contains an additional indirection between
  // collected frames via an
  // "event_frame_number" array in NXevent_data (which eliminates frames with no
  // events).
  // the proton_log is for all frames and so is longer than the event_index
  // array, so we need to
  // filter the proton_charge log based on event_frame_number
  // This difference will be removed in future for compatibility with SNS, but
  // the code below will allow current SANS2D files to load
  if (workspace->mutableRun().hasProperty("proton_log")) {
    std::vector<int> event_frame_number;
    this->getLogger().notice()
        << "Using old ISIS proton_log and event_frame_number indirection..."
        << std::endl;
    try {
      // Find the bank/name corresponding to the first event data entry, i.e.
      // one with type NXevent_data.
      file.openPath("/" + entry_name);
      std::map<std::string, std::string> entries = file.getEntries();
      std::map<std::string, std::string>::const_iterator it = entries.begin();
      std::string eventEntry;
      for (; it != entries.end(); ++it) {
        if (it->second == "NXevent_data") {
          eventEntry = it->first;
          break;
        }
      }
      this->getLogger().debug()
          << "Opening"
          << " /" + entry_name + "/" + eventEntry + "/event_frame_number"
          << " to find the event_frame_number\n";
      file.openPath("/" + entry_name + "/" + eventEntry +
                    "/event_frame_number");
      file.getData(event_frame_number);
    } catch (const ::NeXus::Exception &) {
      this->getLogger().warning() << "Unable to load event_frame_number - "
                                     "filtering events by time will not work "
                                  << std::endl;
    }
    file.openPath("/" + entry_name);
    if (!event_frame_number.empty()) // ISIS indirection - see above comments
    {
      Kernel::TimeSeriesProperty<double> *plog =
          dynamic_cast<Kernel::TimeSeriesProperty<double> *>(
              workspace->mutableRun().getProperty("proton_log"));
      if (!plog)
        throw std::runtime_error(
            "Could not cast (interpret) proton_log as a time "
            "series property. Cannot continue.");
      Kernel::TimeSeriesProperty<double> *pcharge =
          new Kernel::TimeSeriesProperty<double>("proton_charge");
      std::vector<double> pval;
      std::vector<Mantid::Kernel::DateAndTime> ptime;
      pval.reserve(event_frame_number.size());
      ptime.reserve(event_frame_number.size());
      std::vector<Mantid::Kernel::DateAndTime> plogt = plog->timesAsVector();
      std::vector<double> plogv = plog->valuesAsVector();
      for (auto number : event_frame_number) {
        ptime.push_back(plogt[number]);
        pval.push_back(plogv[number]);
      }
      pcharge->create(ptime, pval);
      pcharge->setUnits("uAh");
      workspace->mutableRun().addProperty(pcharge, true);
    }
  }
  try {
    // Read the start and end time strings
    file.openData("start_time");
    Kernel::DateAndTime start(file.getStrData());
    file.closeData();
    file.openData("end_time");
    Kernel::DateAndTime end(file.getStrData());
    file.closeData();
    workspace->mutableRun().setStartAndEndTime(start, end);
  } catch (::NeXus::Exception &) {
  }

  if (!workspace->run().hasProperty("gd_prtn_chrg")) {
    // Try pulling it from the main proton_charge entry first
    try {
      file.openData("proton_charge");
      std::vector<double> values;
      file.getDataCoerce(values);
      std::string units;
      file.getAttr("units", units);
      double charge = values.front();
      if (units.find("picoCoulomb") != std::string::npos) {
        charge *= 1.e-06 / 3600.;
      }
      workspace->mutableRun().setProtonCharge(charge);
    } catch (::NeXus::Exception &) {
      // Try and integrate the proton logs
      try {
        // Use the DAS logs to integrate the proton charge (if any).
        workspace->mutableRun().getProtonCharge();
      } catch (Exception::NotFoundError &) {
        // Ignore not found property error.
      }
    }
  }

  // Close the file
  file.close();
}