Пример #1
0
RefMatrixWSImageView::RefMatrixWSImageView( QString wps_name, int peak_min, int peak_max, int back_min, int back_max, int tof_min, int tof_max)
{

    IEventWorkspace_sptr ws;
    ws = AnalysisDataService::Instance().retrieveWS<IEventWorkspace>(wps_name.toStdString());

    const double total_ymin = 0.0;
    const double total_ymax = 255.0;
    const size_t total_rows = 256;
//    const double total_ymax = 303;
//    const size_t total_rows = 304;
    
    
    std::vector<double> xaxis = ws->readX(0);
    const size_t sz = xaxis.size()-1;
    const size_t total_cols = sz;
    
    double total_xmin = xaxis[0];
    double total_xmax = xaxis[sz];
    
    float *data = new float[static_cast<size_t>(total_ymax) * sz];
    
//    std::cout << "Starting the for loop " << std::endl;
//    std::cout << "total_xmax: " << total_xmax << std::endl;
//    std::cout << "sz is : " << sz << std::endl;
    
    std::vector<double> yaxis;
    for (size_t px=0; px<total_ymax; px++)
    {
        //retrieve data now
        yaxis = ws->readY(px);
        for (size_t tof=0; tof<sz; tof++)
        {
            data[px*sz + tof] = static_cast<float>(yaxis[tof]);
        }
    }
    
    SpectrumView::ArrayDataSource* source = new SpectrumView::ArrayDataSource(total_xmin, total_xmax,
                                                        total_ymin, total_ymax,
                                                        total_rows, total_cols,
                                                        data);
    
//    std::cout << "ws->readX(0).size(): " << ws->readX(0).size() << std::endl;

    
    
    image_view = new RefImageView( source,
                                  peak_min, peak_max,
                                  back_min, back_max,
                                  tof_min, tof_max);

}
Пример #2
0
IEventWorkspace_sptr RefReduction::loadData(const std::string dataRun,
    const std::string polarization)
{
  const std::string instrument = getProperty("Instrument");

  // Check whether dataRun refers to an existing workspace
  // Create a good name for the raw workspace
  std::string ws_name = "__ref_"+dataRun+"-"+polarization+"_raw";
  IEventWorkspace_sptr rawWS;
  if (AnalysisDataService::Instance().doesExist(dataRun))
  {
    rawWS = AnalysisDataService::Instance().retrieveWS<EventWorkspace>(dataRun);
    g_log.notice() << "Found workspace: " << dataRun << std::endl;
    m_output_message += "    |Input data run is a workspace: " + dataRun + "\n";
  }
  else if (AnalysisDataService::Instance().doesExist(ws_name))
  {
    rawWS = AnalysisDataService::Instance().retrieveWS<EventWorkspace>(ws_name);
    g_log.notice() << "Using existing workspace: " << ws_name << std::endl;
    m_output_message += "    |Found workspace from previous reduction: " + ws_name + "\n";
  }
  else
  {
    // If we can't find a workspace, find a file to load
    std::string path = FileFinder::Instance().getFullPath(dataRun);

    if (path.size()==0 || !Poco::File(path).exists())
    {
      try
      {
        std::vector<std::string> paths = FileFinder::Instance().findRuns(instrument+dataRun);
        path = paths[0];
      }
      catch(Exception::NotFoundError&) { /* Pass. We report the missing file later. */ }
    }

    if (path.size()==0 || !Poco::File(path).exists())
    {
      try
      {
        std::vector<std::string> paths = FileFinder::Instance().findRuns(dataRun);
        path = paths[0];
      }
      catch(Exception::NotFoundError&) { /* Pass. We report the missing file later. */ }
    }

    if (Poco::File(path).exists()) {
      g_log.notice() << "Found: " << path << std::endl;
      m_output_message += "    |Loading from " + path + "\n";
      IAlgorithm_sptr loadAlg = createChildAlgorithm("LoadEventNexus", 0, 0.2);
      loadAlg->setProperty("Filename", path);
      if (polarization.compare(PolStateNone)!=0)
        loadAlg->setProperty("NXentryName", polarization);
      loadAlg->executeAsChildAlg();
      rawWS = loadAlg->getProperty("OutputWorkspace");
      if (rawWS->getNumberEvents()==0)
      {
        g_log.notice() << "No data in " << polarization << std::endl;
        m_output_message += "    |No data for " + polarization + "\n";
        return rawWS;
      }

      // Move the detector to the right position
      if (instrument.compare("REF_M")==0)
      {
          double det_distance = rawWS->getInstrument()->getDetector(0)->getPos().Z();
          Mantid::Kernel::Property* prop = rawWS->run().getProperty("SampleDetDis");
          Mantid::Kernel::TimeSeriesProperty<double>* dp = dynamic_cast<Mantid::Kernel::TimeSeriesProperty<double>* >(prop);
          double sdd = dp->getStatistics().mean/1000.0;
          IAlgorithm_sptr mvAlg = createChildAlgorithm("MoveInstrumentComponent", 0.2, 0.25);
          mvAlg->setProperty<MatrixWorkspace_sptr>("Workspace", rawWS);
          mvAlg->setProperty("ComponentName", "detector1");
          mvAlg->setProperty("Z", sdd-det_distance);
          mvAlg->setProperty("RelativePosition", true);
          mvAlg->executeAsChildAlg();
          g_log.notice() << "Ensuring correct Z position: Correction = "
              << Poco::NumberFormatter::format(sdd-det_distance)
              << " m" << std::endl;
      }
      AnalysisDataService::Instance().addOrReplace(ws_name, rawWS);
    } else {
        g_log.error() << "Could not find a data file for " << dataRun << std::endl;
        throw std::invalid_argument("Could not find a data file for the given input");
    }
  }

  // Crop TOF as needed and set binning
  double tofMin = getProperty("TOFMin");
  double tofMax = getProperty("TOFMax");
  if (isEmpty(tofMin) || isEmpty(tofMax))
  {
    const MantidVec& x = rawWS->readX(0);
    if (isEmpty(tofMin)) tofMin = *std::min_element(x.begin(), x.end());
    if (isEmpty(tofMax)) tofMax = *std::max_element(x.begin(), x.end());
  }

  int nBins = getProperty("NBins");
  double tofStep = getProperty("TOFStep");
  if (!isEmpty(nBins))
    tofStep = (tofMax-tofMin)/nBins;
  else
    nBins = (int)floor( (tofMax-tofMin)/tofStep );

  std::vector<double> params;
  params.push_back(tofMin);
  params.push_back(tofStep);
  params.push_back(tofMax);

  IAlgorithm_sptr rebinAlg = createChildAlgorithm("Rebin", 0.25, 0.3);
  rebinAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", rawWS);
  rebinAlg->setProperty("Params", params);
  rebinAlg->setProperty("PreserveEvents", true);
  rebinAlg->executeAsChildAlg();
  MatrixWorkspace_sptr outputWS = rebinAlg->getProperty("OutputWorkspace");
  m_output_message += "    |TOF binning: "
      +  Poco::NumberFormatter::format(tofMin) + " to "
      +  Poco::NumberFormatter::format(tofMax) + " in steps of "
      +  Poco::NumberFormatter::format(tofStep) + " microsecs\n";

  // Normalise by current
  IAlgorithm_sptr normAlg = createChildAlgorithm("NormaliseByCurrent", 0.3, 0.35);
  normAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputWS);
  //normAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", outputWS);
  normAlg->executeAsChildAlg();
  outputWS = normAlg->getProperty("OutputWorkspace");

  // Convert to wavelength
  IAlgorithm_sptr convAlg = createChildAlgorithm("ConvertUnits", 0.35, 0.4);
  convAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputWS);
  convAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", outputWS);
  convAlg->setProperty("Target", "Wavelength");
  convAlg->executeAsChildAlg();

  // Rebin in wavelength
  const MantidVec& x = outputWS->readX(0);
  double wlMin = *std::min_element(x.begin(), x.end());
  double wlMax = *std::max_element(x.begin(), x.end());

  std::vector<double> wl_params;
  wl_params.push_back(wlMin);
  wl_params.push_back((wlMax-wlMin)/nBins);
  wl_params.push_back(wlMax);

  IAlgorithm_sptr rebinAlg2 = createChildAlgorithm("Rebin", 0.25, 0.3);
  rebinAlg2->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputWS);
  rebinAlg2->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", outputWS);
  rebinAlg2->setProperty("Params", wl_params);
  rebinAlg2->setProperty("PreserveEvents", true);
  rebinAlg2->executeAsChildAlg();

  IEventWorkspace_sptr outputEvtWS = boost::dynamic_pointer_cast<IEventWorkspace>(outputWS);
  return outputEvtWS;
}
Пример #3
0
MatrixWorkspace_sptr RefReduction::processData(const std::string polarization)
{
  m_output_message += "Processing " + polarization + '\n';
  const std::string dataRun = getPropertyValue("DataRun");
  IEventWorkspace_sptr evtWS = loadData(dataRun, polarization);
  MatrixWorkspace_sptr dataWS = boost::dynamic_pointer_cast<MatrixWorkspace>(evtWS);
  MatrixWorkspace_sptr dataWSTof = boost::dynamic_pointer_cast<MatrixWorkspace>(evtWS);
    

  // If we have no events, stop here
  if (evtWS->getNumberEvents()==0) return dataWS;

  // Get low-res pixel range
  int low_res_min = 0;
  int low_res_max = 0;
  const bool cropLowRes = getProperty("CropLowResDataAxis");
  const std::vector<int> lowResRange = getProperty("LowResDataAxisPixelRange");
  if (cropLowRes)
  {
    if (lowResRange.size()<2) {
      g_log.error() << "LowResDataAxisPixelRange parameter should be a vector of two values" << std::endl;
      throw std::invalid_argument("LowResDataAxisPixelRange parameter should be a vector of two values");
    }
    low_res_min = lowResRange[0];
    low_res_max = lowResRange[1];
    m_output_message += "    |Cropping low-res axis: ["
        + Poco::NumberFormatter::format(low_res_min) + ", "
        + Poco::NumberFormatter::format(low_res_max) + "]\n";
  }

  // Get peak range
  const std::vector<int> peakRange = getProperty("SignalPeakPixelRange");
  if (peakRange.size()<2) {
    g_log.error() << "SignalPeakPixelRange parameter should be a vector of two values" << std::endl;
    throw std::invalid_argument("SignalPeakPixelRange parameter should be a vector of two values");
  }

  // Get scattering angle in degrees
  double theta = getProperty("Theta");
  const std::string instrument = getProperty("Instrument");
  const bool integrateY = instrument.compare("REF_M")==0;

  // Get pixel ranges in real pixels
  int xmin = 0;
  int xmax = 0;
  int ymin = 0;
  int ymax = 0;
  if (integrateY)
  {
    if (isEmpty(theta)) theta = calculateAngleREFM(dataWS);
    if (!cropLowRes) low_res_max = NY_PIXELS-1;
    xmin = 0;
    xmax = NX_PIXELS-1;
    ymin = low_res_min;
    ymax = low_res_max;
  } else {
    if (isEmpty(theta)) theta = calculateAngleREFL(dataWS);
    if (!cropLowRes) low_res_max = NX_PIXELS-1;
    ymin = 0;
    ymax = NY_PIXELS-1;
    xmin = low_res_min;
    xmax = low_res_max;
  }
  m_output_message += "    |Scattering angle: "
      + Poco::NumberFormatter::format(theta,6) + " deg\n";

  // Subtract background
  if (getProperty("SubtractSignalBackground"))
  {
    // Get background range
    const std::vector<int> bckRange = getProperty("SignalBackgroundPixelRange");
    if (bckRange.size()<2) {
      g_log.error() << "SignalBackgroundPixelRange parameter should be a vector of two values" << std::endl;
      throw std::invalid_argument("SignalBackgroundPixelRange parameter should be a vector of two values");
    }

    IAlgorithm_sptr convAlg = createChildAlgorithm("ConvertToMatrixWorkspace", 0.50, 0.55);
    convAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS);
    convAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", dataWS);
    convAlg->executeAsChildAlg();

    dataWS = subtractBackground(dataWS, dataWS,
        peakRange[0], peakRange[1], bckRange[0], bckRange[1], low_res_min, low_res_max);
    m_output_message += "    |Subtracted background ["
        + Poco::NumberFormatter::format(bckRange[0]) + ", "
        + Poco::NumberFormatter::format(bckRange[1]) + "]\n";
  }

  // Process normalization run
  if (getProperty("PerformNormalization"))
  {
    MatrixWorkspace_sptr normWS = processNormalization();
    IAlgorithm_sptr rebinAlg = createChildAlgorithm("RebinToWorkspace", 0.50, 0.55);
    rebinAlg->setProperty<MatrixWorkspace_sptr>("WorkspaceToRebin", normWS);
    rebinAlg->setProperty<MatrixWorkspace_sptr>("WorkspaceToMatch", dataWS);
    rebinAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", normWS);
    rebinAlg->executeAsChildAlg();
    normWS = rebinAlg->getProperty("OutputWorkspace");

    IAlgorithm_sptr divAlg = createChildAlgorithm("Divide", 0.55, 0.65);
    divAlg->setProperty<MatrixWorkspace_sptr>("LHSWorkspace", dataWS);
    divAlg->setProperty<MatrixWorkspace_sptr>("RHSWorkspace", normWS);
    divAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", dataWS);
    divAlg->executeAsChildAlg();

    IAlgorithm_sptr repAlg = createChildAlgorithm("ReplaceSpecialValues", 0.55, 0.65);
    repAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS);
    repAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", dataWS);
    repAlg->setProperty("NaNValue", 0.0);
    repAlg->setProperty("NaNError", 0.0);
    repAlg->setProperty("InfinityValue", 0.0);
    repAlg->setProperty("InfinityError", 0.0);
    repAlg->executeAsChildAlg();
    m_output_message += "Normalization completed\n";
  }

//    // Integrate over Y
//    IAlgorithm_sptr refAlg = createChildAlgorithm("RefRoi", 0.90, 0.95);
//    refAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS);
//    refAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS);
//    refAlg->setProperty("NXPixel", NX_PIXELS);
//    refAlg->setProperty("NYPixel", NY_PIXELS);
//    refAlg->setProperty("YPixelMin", ymin);
//    refAlg->setProperty("YPixelMax", ymax);
//    refAlg->setProperty("XPixelMin", xmin);
//    refAlg->setProperty("XPixelMax", xmax);
//    refAlg->setProperty("IntegrateY", integrateY);
//    refAlg->setProperty("ScatteringAngle", theta);
//    refAlg->executeAsChildAlg();
//    
//    // Convert back to TOF
//    IAlgorithm_sptr convAlgToTof = createChildAlgorithm("ConvertUnits", 0.85, 0.90);
//    convAlgToTof->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS);
//    convAlgToTof->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", dataWSTof);
//    convAlgToTof->setProperty("Target", "TOF");
//    convAlgToTof->executeAsChildAlg();
//
//    MatrixWorkspace_sptr outputWS2 = convAlgToTof->getProperty("OutputWorkspace");
//    declareProperty(new WorkspaceProperty<>("OutputWorkspace_jc_" + polarization, "TOF_"+polarization, Direction::Output));
//    setProperty("OutputWorkspace_jc_" + polarization, outputWS2);

    //integrated over Y and keep in lambda scale
    IAlgorithm_sptr refAlg1 = createChildAlgorithm("RefRoi", 0.90, 0.95);
    refAlg1->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS);
    refAlg1->setProperty("NXPixel", NX_PIXELS);
    refAlg1->setProperty("NYPixel", NY_PIXELS);
    refAlg1->setProperty("ConvertToQ", false);
    refAlg1->setProperty("YPixelMin", ymin);
    refAlg1->setProperty("YPixelMax", ymax);
    refAlg1->setProperty("XPixelMin", xmin);
    refAlg1->setProperty("XPixelMax", xmax);
    refAlg1->setProperty("IntegrateY", integrateY);
    refAlg1->setProperty("ScatteringAngle", theta);
    refAlg1->executeAsChildAlg();
    MatrixWorkspace_sptr outputWS2 = refAlg1->getProperty("OutputWorkspace");
    declareProperty(new WorkspaceProperty<>("OutputWorkspace_jc_" + polarization, "Lambda_"+polarization, Direction::Output));
    setProperty("OutputWorkspace_jc_" + polarization, outputWS2);
    
    // Conversion to Q
  IAlgorithm_sptr refAlg = createChildAlgorithm("RefRoi", 0.90, 0.95);
  refAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS);
  refAlg->setProperty("NXPixel", NX_PIXELS);
  refAlg->setProperty("NYPixel", NY_PIXELS);
  refAlg->setProperty("ConvertToQ", true);

  refAlg->setProperty("YPixelMin", ymin);
  refAlg->setProperty("YPixelMax", ymax);
  refAlg->setProperty("XPixelMin", xmin);
  refAlg->setProperty("XPixelMax", xmax);
  refAlg->setProperty("IntegrateY", integrateY);
  refAlg->setProperty("ScatteringAngle", theta);
  refAlg->executeAsChildAlg();

  MatrixWorkspace_sptr output2DWS = refAlg->getProperty("OutputWorkspace");
  std::vector<int> spectra;
  for(int i=peakRange[0]; i<peakRange[1]+1; i++) spectra.push_back(i);

  IAlgorithm_sptr grpAlg = createChildAlgorithm("GroupDetectors", 0.95, 0.99);
  grpAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", output2DWS);
  grpAlg->setProperty("SpectraList", spectra);
  grpAlg->executeAsChildAlg();

  MatrixWorkspace_sptr outputWS = grpAlg->getProperty("OutputWorkspace");

  const std::string prefix = getPropertyValue("OutputWorkspacePrefix");
  if (polarization.compare(PolStateNone)==0)
  {
    declareProperty(new WorkspaceProperty<>("OutputWorkspace", prefix, Direction::Output));
    setProperty("OutputWorkspace", outputWS);
    declareProperty(new WorkspaceProperty<>("OutputWorkspace2D", "2D_"+prefix, Direction::Output));
    setProperty("OutputWorkspace2D", output2DWS);
  } else {
    std::string wsName = prefix+polarization;
    Poco::replaceInPlace(wsName, "entry", "");
    declareProperty(new WorkspaceProperty<>("OutputWorkspace_"+polarization, wsName, Direction::Output));
    setProperty("OutputWorkspace_"+polarization, outputWS);
    declareProperty(new WorkspaceProperty<>("OutputWorkspace2D_"+polarization, "2D_"+wsName, Direction::Output));
    setProperty("OutputWorkspace2D_"+polarization, output2DWS);
  }
  m_output_message += "Reflectivity calculation completed\n";
  return outputWS;
}
Пример #4
0
//----------------------------------------------------------------------------------------------
/// @copydoc Mantid::API::Algorithm::exec()
void LoadPreNexus::exec()
{
    string runinfo = this->getPropertyValue(RUNINFO_PARAM);
    string mapfile = this->getPropertyValue(MAP_PARAM);
    int chunkTotal = this->getProperty("TotalChunks");
    int chunkNumber = this->getProperty("ChunkNumber");
    if ( isEmpty(chunkTotal) || isEmpty(chunkNumber))
    {
        chunkNumber = EMPTY_INT();
        chunkTotal = EMPTY_INT();
    }
    else
    {
        if (chunkNumber > chunkTotal)
            throw std::out_of_range("ChunkNumber cannot be larger than TotalChunks");
    }
    string useParallel = this->getProperty("UseParallelProcessing");
    string wsname = this->getProperty("OutputWorkspace");
    bool loadmonitors = this->getProperty("LoadMonitors");

    // determine the event file names
    Progress prog(this, 0., .1, 1);
    vector<string> eventFilenames;
    string dataDir;
    this->parseRuninfo(runinfo, dataDir, eventFilenames);
    prog.doReport("parsed runinfo file");

    // do math for the progress bar
    size_t numFiles = eventFilenames.size() + 1; // extra 1 is nexus logs
    if (loadmonitors)
        numFiles++;
    double prog_start = .1;
    double prog_delta = (1.-prog_start)/static_cast<double>(numFiles);

    // load event files
    string temp_wsname;

    for (size_t i = 0; i < eventFilenames.size(); i++) {
        if (i == 0)
            temp_wsname = wsname;
        else
            temp_wsname = "__" + wsname + "_temp__";

        IAlgorithm_sptr alg = this->createChildAlgorithm("LoadEventPreNexus", prog_start, prog_start+prog_delta);
        alg->setProperty("EventFilename", dataDir + eventFilenames[i]);
        alg->setProperty("MappingFilename", mapfile);
        alg->setProperty("ChunkNumber", chunkNumber);
        alg->setProperty("TotalChunks", chunkTotal);
        alg->setProperty("UseParallelProcessing", useParallel);
        alg->setPropertyValue("OutputWorkspace", temp_wsname);
        alg->executeAsChildAlg();
        prog_start += prog_delta;

        if (i == 0)
        {
            m_outputWorkspace = alg->getProperty("OutputWorkspace");
        }
        else
        {
            IEventWorkspace_sptr tempws = alg->getProperty("OutputWorkspace");
            // clean up properties before adding data
            Run & run = tempws->mutableRun();
            if (run.hasProperty("gd_prtn_chrg"))
                run.removeProperty("gd_prtn_chrg");
            if (run.hasProperty("proton_charge"))
                run.removeProperty("proton_charge");

            m_outputWorkspace += tempws;
        }
    }


    // load the logs
    this->runLoadNexusLogs(runinfo, dataDir, prog_start, prog_start+prog_delta);
    prog_start += prog_delta;

    // publish output workspace
    this->setProperty("OutputWorkspace", m_outputWorkspace);

    // load the monitor
    if (loadmonitors)
    {
        this->runLoadMonitors(prog_start, 1.);
    }
}
Пример #5
0
/**
 * Execute the algorithm.
 */
void RebinByTimeBase::exec() {
  using Mantid::DataObjects::EventWorkspace;
  IEventWorkspace_sptr inWS = getProperty("InputWorkspace");

  if (!boost::dynamic_pointer_cast<EventWorkspace>(inWS)) {
    const std::string algName = this->name();
    throw std::invalid_argument(
        algName + " Algorithm requires an EventWorkspace as an input.");
  }

  MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace");

  // retrieve the properties
  const std::vector<double> inParams = getProperty("Params");
  std::vector<double> rebinningParams;

  // workspace independent determination of length
  const int histnumber = static_cast<int>(inWS->getNumberHistograms());

  const uint64_t nanoSecondsInASecond = static_cast<uint64_t>(1e9);
  const DateAndTime runStartTime = inWS->run().startTime();
  // The validator only passes parameters with size 1, or 3xn.

  double tStep = 0;
  if (inParams.size() >= 3) {
    // Use the start of the run to offset the times provided by the user. pulse
    // time of the events are absolute.
    const DateAndTime startTime = runStartTime + inParams[0];
    const DateAndTime endTime = runStartTime + inParams[2];
    // Rebinning params in nanoseconds.
    rebinningParams.push_back(
        static_cast<double>(startTime.totalNanoseconds()));
    tStep = inParams[1] * nanoSecondsInASecond;
    rebinningParams.push_back(tStep);
    rebinningParams.push_back(static_cast<double>(endTime.totalNanoseconds()));
  } else if (inParams.size() == 1) {
    const uint64_t xmin = getMinX(inWS);
    const uint64_t xmax = getMaxX(inWS);

    rebinningParams.push_back(static_cast<double>(xmin));
    tStep = inParams[0] * nanoSecondsInASecond;
    rebinningParams.push_back(tStep);
    rebinningParams.push_back(static_cast<double>(xmax));
  }

  // Validate the timestep.
  if (tStep <= 0) {
    throw std::invalid_argument(
        "Cannot have a timestep less than or equal to zero.");
  }

  // Initialize progress reporting.
  Progress prog(this, 0.0, 1.0, histnumber);

  MantidVecPtr XValues_new;
  // create new X axis, with absolute times in seconds.
  const int ntcnew = VectorHelper::createAxisFromRebinParams(
      rebinningParams, XValues_new.access());

  ConvertToRelativeTime transformToRelativeT(runStartTime);

  // Transform the output into relative times in seconds.
  MantidVec OutXValues_scaled(XValues_new->size());
  std::transform(XValues_new->begin(), XValues_new->end(),
                 OutXValues_scaled.begin(), transformToRelativeT);

  outputWS = WorkspaceFactory::Instance().create("Workspace2D", histnumber,
                                                 ntcnew, ntcnew - 1);
  WorkspaceFactory::Instance().initializeFromParent(inWS, outputWS, true);

  // Copy all the axes
  for (int i = 1; i < inWS->axes(); i++) {
    outputWS->replaceAxis(i, inWS->getAxis(i)->clone(outputWS.get()));
    outputWS->getAxis(i)->unit() = inWS->getAxis(i)->unit();
  }

  // X-unit is relative time since the start of the run.
  outputWS->getAxis(0)->unit() = boost::make_shared<Units::Time>();

  // Copy the units over too.
  for (int i = 1; i < outputWS->axes(); ++i) {
    outputWS->getAxis(i)->unit() = inWS->getAxis(i)->unit();
  }
  outputWS->setYUnit(inWS->YUnit());
  outputWS->setYUnitLabel(inWS->YUnitLabel());

  // Assign it to the output workspace property
  setProperty("OutputWorkspace", outputWS);

  // Go through all the histograms and set the data
  doHistogramming(inWS, outputWS, XValues_new, OutXValues_scaled, prog);
}