double EstimateResolutionDiffraction::getWavelength() {
    double wavelength = getProperty("Wavelength");
    if (!isEmpty(wavelength)) {
        return wavelength;
    }

    Property *cwlproperty = m_inputWS->run().getProperty("LambdaRequest");
    if (!cwlproperty)
        throw runtime_error(
            "Unable to locate property LambdaRequest as central wavelength. ");

    TimeSeriesProperty<double> *cwltimeseries =
        dynamic_cast<TimeSeriesProperty<double> *>(cwlproperty);

    if (!cwltimeseries)
        throw runtime_error(
            "LambdaReqeust is not a TimeSeriesProperty in double. ");

    string unit = cwltimeseries->units();
    if (unit.compare("Angstrom") != 0) {
        throw runtime_error("Unit is not recognized: " + unit);
    }

    return cwltimeseries->timeAverageValue();
}
Exemple #2
0
/** Try to load the "Veto_pulse" field in DASLogs
 * and convert it to a sample log.
 *
 * @param file :: open nexus file at the DASLogs group
 * @param workspace :: workspace to add to.
 */
void LoadNexusLogs::loadVetoPulses(
    ::NeXus::File &file,
    boost::shared_ptr<API::MatrixWorkspace> workspace) const {
  try {
    file.openGroup("Veto_pulse", "NXgroup");
  } catch (::NeXus::Exception &) {
    // No group. This is common in older files
    return;
  }
  file.openData("veto_pulse_time");

  // Load the start date/time as ISO8601 string.
  std::string start_time;
  file.getAttr("start_time", start_time);
  DateAndTime start(start_time);

  // Read the offsets
  std::vector<double> time_double;
  file.getData(time_double);

  // Fake values with zeroes.
  std::vector<double> values(time_double.size(), 0.0);
  TimeSeriesProperty<double> *tsp =
      new TimeSeriesProperty<double>("veto_pulse_time");
  tsp->create(start, time_double, values);
  tsp->setUnits("");

  // Add the log
  workspace->mutableRun().addProperty(tsp);

  file.closeData();
  file.closeGroup();
}
  void EstimatePDDetectorResolution::retrieveInstrumentParameters()
  {
#if 0
    // Call SolidAngle to get solid angles for all detectors
    Algorithm_sptr calsolidangle = createChildAlgorithm("SolidAngle", -1, -1, true);
    calsolidangle->initialize();

    calsolidangle->setProperty("InputWorkspace", m_inputWS);

    calsolidangle->execute();
    if (!calsolidangle->isExecuted())
      throw runtime_error("Unable to run solid angle. ");

    m_solidangleWS = calsolidangle->getProperty("OutputWorkspace");
    if (!m_solidangleWS)
      throw runtime_error("Unable to get solid angle workspace from SolidAngle(). ");


    size_t numspec = m_solidangleWS->getNumberHistograms();
    for (size_t i = 0; i < numspec; ++i)
      g_log.debug() << "[DB]: " << m_solidangleWS->readY(i)[0] << "\n";
#endif

    // Calculate centre neutron velocity
    Property* cwlproperty = m_inputWS->run().getProperty("LambdaRequest");
    if (!cwlproperty)
      throw runtime_error("Unable to locate property LambdaRequest as central wavelength. ");
    TimeSeriesProperty<double>* cwltimeseries = dynamic_cast<TimeSeriesProperty<double>* >(cwlproperty);
    if (!cwltimeseries)
      throw runtime_error("LambdaReqeust is not a TimeSeriesProperty in double. ");
    if (cwltimeseries->size() != 1)
      throw runtime_error("LambdaRequest should contain 1 and only 1 entry. ");

    double centrewavelength = cwltimeseries->nthValue(0);
    string unit = cwltimeseries->units();
    if (unit.compare("Angstrom") == 0)
      centrewavelength *= 1.0E-10;
    else
      throw runtime_error("Unit is not recognized");

    m_centreVelocity = PhysicalConstants::h/PhysicalConstants::NeutronMass/centrewavelength;
    g_log.notice() << "Centre wavelength = " << centrewavelength << ", Centre neutron velocity = " << m_centreVelocity << "\n";

    // Calcualte L1 sample to source
    Instrument_const_sptr instrument = m_inputWS->getInstrument();
    V3D samplepos = instrument->getSample()->getPos();
    V3D sourcepos = instrument->getSource()->getPos();
    m_L1 = samplepos.distance(sourcepos);
    g_log.notice() << "L1 = " << m_L1 << "\n";

    return;
  }
/// Do the actual work of modifying the log in the workspace.
void ChangeLogTime::exec()
{
  // check that a log was specified
  string logname = this->getProperty("LogName");
  if (logname.empty()) {
    throw std::runtime_error("Failed to supply a LogName");
  }
  // everything will need an offset
  double offset = this->getProperty("TimeOffset");

  // make sure the log is in the input workspace
  MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");
  Kernel::TimeSeriesProperty<double> * oldlog = dynamic_cast<Kernel::TimeSeriesProperty<double> *>( inputWS->run().getLogData(logname) );
  if (!oldlog) {
    stringstream msg;
    msg << "InputWorkspace \'" << this->getPropertyValue("InputWorkspace")
        << "\' does not have LogName \'" << logname << "\'";
    throw std::runtime_error(msg.str());
  }

  // Create the new log
  TimeSeriesProperty<double>* newlog = new TimeSeriesProperty<double>(logname);
  newlog->setUnits(oldlog->units());
  int size = oldlog->realSize();
  vector<double> values = oldlog->valuesAsVector();
  vector<DateAndTime> times = oldlog->timesAsVector();
  for (int i = 0; i < size; i++) {
    newlog->addValue(times[i] + offset, values[i]);
  }

  // Just overwrite if the change is in place
  MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace");
  if (outputWS != inputWS)
  {
    IAlgorithm_sptr duplicate = createChildAlgorithm("CloneWorkspace");
    duplicate->initialize();
    duplicate->setProperty<Workspace_sptr>("InputWorkspace", boost::dynamic_pointer_cast<Workspace>(inputWS));
    duplicate->execute();
    Workspace_sptr temp = duplicate->getProperty("OutputWorkspace");
    outputWS = boost::dynamic_pointer_cast<MatrixWorkspace>(temp);

    setProperty("OutputWorkspace", outputWS);
  }

  outputWS->mutableRun().addProperty(newlog, true);
}
/**
 * Add a sample environment log for the proton chage (charge of the pulse in
 *picoCoulombs)
 * and set the scalar value (total proton charge, microAmps*hours, on the
 *sample)
 *
 * @param workspace :: Event workspace to set the proton charge on
 */
void LoadEventPreNexus::setProtonCharge(
    DataObjects::EventWorkspace_sptr &workspace) {
  if (this->proton_charge.empty()) // nothing to do
    return;

  Run &run = workspace->mutableRun();

  // Add the proton charge entries.
  TimeSeriesProperty<double> *log =
      new TimeSeriesProperty<double>("proton_charge");
  log->setUnits("picoCoulombs");

  // Add the time and associated charge to the log
  log->addValues(this->pulsetimes, this->proton_charge);

  /// TODO set the units for the log
  run.addLogData(log);
  double integ = run.integrateProtonCharge();
  // run.setProtonCharge(this->proton_charge_tot); //This is now redundant
  this->g_log.information() << "Total proton charge of " << integ
                            << " microAmp*hours found by integrating.\n";
}
Exemple #6
0
    /**
     * Check if the file is SNS text; load it if it is, return false otherwise.
     * @return true if the file was a SNS style; false otherwise.
     */
    bool LoadLog::LoadSNSText()
    {

      // Get the SNS-specific parameter
      std::vector<std::string> names = getProperty("Names");
      std::vector<std::string> units = getProperty("Units");

      // Get the input workspace and retrieve run from workspace.
      // the log file(s) will be loaded into the run object of the workspace
      const MatrixWorkspace_sptr localWorkspace = getProperty("Workspace");

      // open log file
      std::ifstream inLogFile(m_filename.c_str());

      // Get the first line
      std::string aLine;
      if (!Mantid::Kernel::Strings::extractToEOL(inLogFile,aLine))
        return false;

      std::vector<double> cols;
      bool ret = SNSTextFormatColumns(aLine, cols);
      // Any error?
      if (!ret || cols.size() < 2)
        return false;

      size_t numCols = static_cast<size_t>(cols.size()-1);
      if (names.size() != numCols)
        throw std::invalid_argument("The Names parameter should have one fewer entry as the number of columns in a SNS-style text log file.");
      if ((!units.empty()) && (units.size() != numCols))
        throw std::invalid_argument("The Units parameter should have either 0 entries or one fewer entry as the number of columns in a SNS-style text log file.");

      // Ok, create all the logs
      std::vector<TimeSeriesProperty<double>*> props;
      for(size_t i=0; i < numCols; i++)
      {
        TimeSeriesProperty<double>* p = new TimeSeriesProperty<double>(names[i]);
        if (units.size() == numCols)
          p->setUnits(units[i]);
        props.push_back(p);
      }
      // Go back to start
      inLogFile.seekg(0);
      while(Mantid::Kernel::Strings::extractToEOL(inLogFile,aLine))
      {
        if (aLine.size() == 0)
          break;

        if (SNSTextFormatColumns(aLine, cols))
        {
          if (cols.size() == numCols+1)
          {
            DateAndTime time(cols[0], 0.0);
            for(size_t i=0; i<numCols; i++)
              props[i]->addValue(time, cols[i+1]);
          }
          else
            throw std::runtime_error("Inconsistent number of columns while reading SNS-style text file.");
        }
        else
          throw std::runtime_error("Error while reading columns in SNS-style text file.");
      }
      // Now add all the full logs to the workspace
      for(size_t i=0; i < numCols; i++)
      {
        std::string name = props[i]->name();
        if (localWorkspace->mutableRun().hasProperty(name))
        {
          localWorkspace->mutableRun().removeLogData(name);
          g_log.information() << "Log data named " << name << " already existed and was overwritten.\n";
        }
        localWorkspace->mutableRun().addLogData(props[i]);
      }

      return true;
    }
/**
*   Executes the algorithm
*/
void PlotAsymmetryByLogValue::exec()
{
    m_forward_list = getProperty("ForwardSpectra");
    m_backward_list = getProperty("BackwardSpectra");
    m_autogroup = ( m_forward_list.size() == 0 && m_backward_list.size() == 0);

    //double alpha = getProperty("Alpha");

    std::string logName = getProperty("LogValue");

    int red = getProperty("Red");
    int green = getProperty("Green");

    std::string stype = getProperty("Type");
    m_int = stype == "Integral";

    std::string firstFN = getProperty("FirstRun");
    std::string lastFN = getProperty("LastRun");

    std::string ext = firstFN.substr(firstFN.find_last_of("."));

    firstFN.erase(firstFN.size()-4);
    lastFN.erase(lastFN.size()-4);

    std::string fnBase = firstFN;
    size_t i = fnBase.size()-1;
    while(isdigit(fnBase[i]))  i--;
    if (i == fnBase.size()-1)
    {
        g_log.error("File name must end with a number.");
        throw Exception::FileError("File name must end with a number.",firstFN);
    }
    fnBase.erase(i+1);

    firstFN.erase(0,fnBase.size());
    lastFN.erase(0,fnBase.size());

    size_t is = atoi(firstFN.c_str());  // starting run number
    size_t ie = atoi(lastFN.c_str());   // last run number
    int w  = static_cast<int>(firstFN.size());

    // The number of runs
    size_t npoints = ie - is + 1;

    // Create the 2D workspace for the output
    int nplots = green != EMPTY_INT() ? 4 : 1;
    MatrixWorkspace_sptr outWS = WorkspaceFactory::Instance().create("Workspace2D",
                                 nplots,          //  the number of plots
                                 npoints,    //  the number of data points on a plot
                                 npoints     //  it's not a histogram
                                                                    );
    TextAxis* tAxis = new TextAxis(nplots);
    if (nplots == 1)
    {
        tAxis->setLabel(0,"Asymmetry");
    }
    else
    {
        tAxis->setLabel(0,"Red-Green");
        tAxis->setLabel(1,"Red");
        tAxis->setLabel(2,"Green");
        tAxis->setLabel(3,"Red+Green");
    }
    outWS->replaceAxis(1,tAxis);

    Progress progress(this,0,1,ie-is+2);
    for(size_t i=is; i<=ie; i++)
    {
        std::ostringstream fn,fnn;
        fnn << std::setw(w) << std::setfill('0') << i ;
        fn << fnBase << fnn.str() << ext;

        // Load a muon nexus file with auto_group set to true
        IAlgorithm_sptr loadNexus = createChildAlgorithm("LoadMuonNexus");
        loadNexus->setPropertyValue("Filename", fn.str());
        loadNexus->setPropertyValue("OutputWorkspace","tmp"+fnn.str());
        if (m_autogroup)
            loadNexus->setPropertyValue("AutoGroup","1");
        loadNexus->execute();

        std::string wsProp = "OutputWorkspace";

        DataObjects::Workspace2D_sptr ws_red;
        DataObjects::Workspace2D_sptr ws_green;

        // Run through the periods of the loaded file and do calculations on the selected ones
        Workspace_sptr tmp = loadNexus->getProperty(wsProp);
        WorkspaceGroup_sptr wsGroup = boost::dynamic_pointer_cast<WorkspaceGroup>(tmp);
        if (!wsGroup)
        {
            ws_red = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(tmp);
            TimeSeriesProperty<double>* logp =
                dynamic_cast<TimeSeriesProperty<double>*>(ws_red->run().getLogData(logName));
            if (!logp)
            {
                throw std::invalid_argument("Log "+logName+" does not exist or not a double type");
            }
            double Y,E;
            calcIntAsymmetry(ws_red,Y,E);
            outWS->dataY(0)[i-is] = Y;
            outWS->dataX(0)[i-is] = logp->lastValue();
            outWS->dataE(0)[i-is] = E;
        }
        else
        {

            for( int period = 1; period <= wsGroup->getNumberOfEntries(); ++period )
            {
                std::stringstream suffix;
                suffix << period;
                wsProp = "OutputWorkspace_" + suffix.str();// form the property name for higher periods
                // Do only one period
                if (green == EMPTY_INT() && period == red)
                {
                    Workspace_sptr tmpff = loadNexus->getProperty(wsProp);
                    ws_red = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(tmpff);
                    TimeSeriesProperty<double>* logp =
                        dynamic_cast<TimeSeriesProperty<double>*>(ws_red->run().getLogData(logName));
                    if (!logp)
                    {
                        throw std::invalid_argument("Log "+logName+" does not exist or not a double type");
                    }
                    double Y,E;
                    calcIntAsymmetry(ws_red,Y,E);
                    outWS->dataY(0)[i-is] = Y;
                    outWS->dataX(0)[i-is] = logp->lastValue();
                    outWS->dataE(0)[i-is] = E;
                }
                else // red & green
                {
                    if (period == red)
                    {
                        Workspace_sptr temp = loadNexus->getProperty(wsProp);
                        ws_red = boost::dynamic_pointer_cast<Workspace2D>(temp);
                    }
                    if (period == green)
                    {
                        Workspace_sptr temp = loadNexus->getProperty(wsProp);
                        ws_green = boost::dynamic_pointer_cast<Workspace2D>(temp);
                    }
                }

            }
            // red & green claculation
            if (green != EMPTY_INT())
            {
                if (!ws_red || !ws_green)
                    throw std::invalid_argument("Red or green period is out of range");
                TimeSeriesProperty<double>* logp =
                    dynamic_cast<TimeSeriesProperty<double>*>(ws_red->run().getLogData(logName));
                if (!logp)
                {
                    throw std::invalid_argument("Log "+logName+" does not exist or not a double type");
                }
                double Y,E;
                double Y1,E1;
                calcIntAsymmetry(ws_red,Y,E);
                calcIntAsymmetry(ws_green,Y1,E1);
                outWS->dataY(1)[i-is] = Y;
                outWS->dataX(1)[i-is] = logp->lastValue();
                outWS->dataE(1)[i-is] = E;

                outWS->dataY(2)[i-is] = Y1;
                outWS->dataX(2)[i-is] = logp->lastValue();
                outWS->dataE(2)[i-is] = E1;

                outWS->dataY(3)[i-is] = Y + Y1;
                outWS->dataX(3)[i-is] = logp->lastValue();
                outWS->dataE(3)[i-is] = sqrt(E*E+E1*E1);

                // move to last for safety since some grouping takes place in the
                // calcIntAsymmetry call below
                calcIntAsymmetry(ws_red,ws_green,Y,E);
                outWS->dataY(0)[i-is] = Y;
                outWS->dataX(0)[i-is] = logp->lastValue();
                outWS->dataE(0)[i-is] = E;
            }
            else if (!ws_red)
                throw std::invalid_argument("Red period is out of range");

        }
        progress.report();
    }

    outWS->getAxis(0)->title() = logName;
    outWS->setYUnitLabel("Asymmetry");

    // Assign the result to the output workspace property
    setProperty("OutputWorkspace", outWS);

}
Exemple #8
0
    /** 
    *   Executes the algorithm
    */
    void PlotPeakByLogValue::exec()
    {

      // Create a list of the input workspace
      const std::vector<InputData> wsNames = makeNames();

      std::string fun = getPropertyValue("Function");
      //int wi = getProperty("WorkspaceIndex");
      std::string logName = getProperty("LogValue");
      bool sequential = getPropertyValue("FitType") == "Sequential";

      bool isDataName = false; // if true first output column is of type string and is the data source name
      ITableWorkspace_sptr result = WorkspaceFactory::Instance().createTable("TableWorkspace");
      if (logName == "SourceName")
      {
        result->addColumn("str","Source name");
        isDataName = true;
      }
      else if (logName.empty())
      {
        result->addColumn("double","axis-1");
      }
      else
      {
        result->addColumn("double",logName);
      }
      // Create an instance of the fitting function to obtain the names of fitting parameters
      IFitFunction* ifun = FunctionFactory::Instance().createInitialized(fun);
      if (!ifun)
      {
        throw std::invalid_argument("Fitting function failed to initialize");
      }
      for(size_t iPar=0;iPar<ifun->nParams();++iPar)
      {
        result->addColumn("double",ifun->parameterName(iPar));
        result->addColumn("double",ifun->parameterName(iPar)+"_Err");
      }
      result->addColumn("double","Chi_squared");
      delete ifun;
      setProperty("OutputWorkspace",result);

      double dProg = 1./static_cast<double>(wsNames.size());
      double Prog = 0.;
      for(int i=0;i<static_cast<int>(wsNames.size());++i)
      {
        InputData data = getWorkspace(wsNames[i]);

        if (!data.ws)
        {
          g_log.warning() << "Cannot access workspace " << wsNames[i].name << '\n';
          continue;
        }

        if (data.i < 0 && data.indx.empty())
        {
          g_log.warning() << "Zero spectra selected for fitting in workspace " << wsNames[i].name << '\n';
          continue;
        }

        int j,jend;
        if (data.i >= 0)
        {
          j = data.i;
          jend = j + 1;
        }
        else
        {// no need to check data.indx.empty()
          j = data.indx.front();
          jend = data.indx.back() + 1;
        }

        dProg /= abs(jend - j);
        for(;j < jend;++j)
        {

          // Find the log value: it is either a log-file value or simply the workspace number
          double logValue;
          if (logName.empty())
          {
            API::Axis* axis = data.ws->getAxis(1);
            logValue = (*axis)(j);
          }
          else if (logName != "SourceName")
          {
            Kernel::Property* prop = data.ws->run().getLogData(logName);
            if (!prop)
            {
              throw std::invalid_argument("Log value "+logName+" does not exist");
            }
            TimeSeriesProperty<double>* logp = 
              dynamic_cast<TimeSeriesProperty<double>*>(prop); 
            logValue = logp->lastValue();
          }

          std::string resFun = fun;
          std::vector<double> errors;
          double chi2;

          try
          {
            // Fit the function
            API::IAlgorithm_sptr fit = createSubAlgorithm("Fit");
            fit->initialize();
            fit->setProperty("InputWorkspace",data.ws);
            //fit->setPropertyValue("InputWorkspace",data.ws->getName());
            fit->setProperty("WorkspaceIndex",j);
            fit->setPropertyValue("Function",fun);
            fit->setPropertyValue("StartX",getPropertyValue("StartX"));
            fit->setPropertyValue("EndX",getPropertyValue("EndX"));
            fit->setPropertyValue("Minimizer",getPropertyValue("Minimizer"));
            fit->setPropertyValue("CostFunction",getPropertyValue("CostFunction"));
            fit->execute();
            resFun = fit->getPropertyValue("Function");
            errors = fit->getProperty("Errors");
            chi2 = fit->getProperty("OutputChi2overDoF");
          }
          catch(...)
          {
            g_log.error("Error in Fit subalgorithm");
            throw;
          }

          if (sequential)
          {
            fun = resFun;
          }

          // Extract the fitted parameters and put them into the result table
          TableRow row = result->appendRow();
          if (isDataName)
          {
            row << wsNames[i].name;
          }
          else
          {
            row << logValue;
          }
          ifun = FunctionFactory::Instance().createInitialized(resFun);
          for(size_t iPar=0;iPar<ifun->nParams();++iPar)
          {
            row << ifun->getParameter(iPar) << errors[iPar];
          }
          row << chi2;
          delete ifun;
          Prog += dProg;
          progress(Prog);
          interruption_point();
        } // for(;j < jend;++j)
      }
    }
Exemple #9
0
/** Execute the algorithm.
 */
void LoadDNSSCD::exec() {
  MultipleFileProperty *multiFileProp =
      dynamic_cast<MultipleFileProperty *>(getPointerToProperty("Filenames"));
  if (!multiFileProp) {
    throw std::logic_error(
        "Filenames property must have MultipleFileProperty type.");
  }
  std::vector<std::string> filenames =
      VectorHelper::flattenVector(multiFileProp->operator()());
  if (filenames.empty())
    throw std::invalid_argument("Must specify at least one filename.");

  // set type of normalization
  std::string normtype = getProperty("Normalization");
  if (normtype == "monitor") {
    m_normtype = "Monitor";
    m_normfactor = 1.0;
  } else {
    m_normtype = "Timer";
    m_normfactor = 0.0; // error for time should be 0
  }

  g_log.notice() << "The normalization workspace will contain " << m_normtype
                 << ".\n";

  ExperimentInfo_sptr expinfo = boost::make_shared<ExperimentInfo>();
  API::Run &run = expinfo->mutableRun();
  for (auto fname : filenames) {
    std::map<std::string, std::string> str_metadata;
    std::map<std::string, double> num_metadata;
    try {
      read_data(fname, str_metadata, num_metadata);
      // if no stop_time, take file_save_time
      std::string time(str_metadata["stop_time"]);
      if (time.empty()) {
        g_log.warning()
            << "stop_time is empty! File save time will be used instead."
            << std::endl;
        time = str_metadata["file_save_time"];
      }
      updateProperties<std::string>(run, str_metadata, time);
      updateProperties<double>(run, num_metadata, time);
    } catch (...) {
      g_log.warning() << "Failed to read file " << fname;
      g_log.warning() << ". This file will be ignored. " << std::endl;
      g_log.debug() << boost::current_exception_diagnostic_information()
                    << std::endl;
    }
  }

  if (m_data.empty())
    throw std::runtime_error(
        "No valid DNS files have been provided. Nothing to load.");

  m_OutWS = MDEventFactory::CreateMDWorkspace(m_nDims, "MDEvent");

  m_OutWS->addExperimentInfo(expinfo);

  // load huber angles from a table workspace if given
  ITableWorkspace_sptr huberWS = getProperty("LoadHuberFrom");
  if (huberWS) {
    g_log.notice() << "Huber angles will be loaded from " << huberWS->getName()
                   << std::endl;
    loadHuber(huberWS);
  }

  // get wavelength
  TimeSeriesProperty<double> *wlprop =
      dynamic_cast<TimeSeriesProperty<double> *>(
          expinfo->run().getProperty("Lambda"));
  // assume, that lambda is in nm
  double wavelength =
      wlprop->minValue() * 10.0; // needed to estimate extents => minValue
  run.addProperty("wavelength", wavelength);
  run.getProperty("wavelength")->setUnits("Angstrom");

  fillOutputWorkspace(wavelength);

  std::string saveHuberTableWS = getProperty("SaveHuberTo");
  if (!saveHuberTableWS.empty()) {
    Mantid::API::ITableWorkspace_sptr huber_table = saveHuber();
    setProperty("SaveHuberTo", huber_table);
  }
  setProperty("OutputWorkspace", m_OutWS);
}