Exemple #1
0
  /** Write out all of the event lists in the given workspace
   * @param ws :: an EventWorkspace */
  int NexusFileIO::writeNexusProcessedDataEvent( const DataObjects::EventWorkspace_const_sptr& ws)
  {
    //write data entry
    NXstatus status=NXmakegroup(fileID,"event_workspace","NXdata");
    if(status==NX_ERROR) return(2);
    NXopengroup(fileID,"event_workspace","NXdata");

    for (size_t wi=0; wi < ws->getNumberHistograms(); wi++)
    {
      std::ostringstream group_name;
      group_name << "event_list_" << wi;
      this->writeEventList( ws->getEventList(wi), group_name.str());
    }

    // Close up the overall group
    status=NXclosegroup(fileID);
    return((status==NX_ERROR)?3:0);
  }
void ConvertToMatrixWorkspace::exec()
{
  MatrixWorkspace_const_sptr inputWorkspace = getProperty("InputWorkspace");
  // Let's see if we have to do anything first. Basically we want to avoid the data copy if we can
  DataObjects::EventWorkspace_const_sptr eventW = 
    boost::dynamic_pointer_cast<const DataObjects::EventWorkspace>(inputWorkspace);
  MatrixWorkspace_sptr outputWorkspace;
  if( eventW )
  {
    g_log.information() << "Converting EventWorkspace to Workspace2D.\n";

    const size_t numHists = inputWorkspace->getNumberHistograms();
    Progress prog(this,0.0,1.0,numHists*2);

    // Sort the input workspace in-place by TOF. This can be faster if there are few event lists.
    eventW->sortAll(TOF_SORT, &prog);

    // Create the output workspace. This will copy many aspects fron the input one.
    outputWorkspace = WorkspaceFactory::Instance().create(inputWorkspace);

    // ...but not the data, so do that here.
    PARALLEL_FOR2(inputWorkspace,outputWorkspace)
    for (int64_t i = 0; i < (int64_t)numHists; ++i)
    {
      PARALLEL_START_INTERUPT_REGION
      const ISpectrum * inSpec = inputWorkspace->getSpectrum(i);
      ISpectrum * outSpec = outputWorkspace->getSpectrum(i);

      outSpec->copyInfoFrom(*inSpec);
      outSpec->setX(inSpec->ptrX());
      outSpec->dataY() = inSpec->dataY();
      outSpec->dataE() = inSpec->dataE();
      
      prog.report("Binning");

      PARALLEL_END_INTERUPT_REGION
    }
    PARALLEL_CHECK_INTERUPT_REGION

    outputWorkspace->generateSpectraMap();
  }
  else
  {
Exemple #3
0
  /** Write out a combined chunk of event data
   *
   * @param ws :: an EventWorkspace
   * @param indices :: array of event list indexes
   * @param tofs :: array of TOFs
   * @param weights :: array of event weights
   * @param errorSquareds :: array of event squared errors
   * @param pulsetimes :: array of pulsetimes
   * @param compress :: if true, compress the entry
   */
  int NexusFileIO::writeNexusProcessedDataEventCombined( const DataObjects::EventWorkspace_const_sptr& ws,
      std::vector<int64_t> & indices,
      double * tofs, float * weights, float * errorSquareds, int64_t * pulsetimes,
      bool compress) const
  {
    NXopengroup(fileID,"event_workspace","NXdata");

    // The array of indices for each event list #
    int dims_array[1] = { static_cast<int>(indices.size()) };
    if (indices.size() > 0)
    {
      if (compress)
        NXcompmakedata(fileID, "indices", NX_INT64, 1, dims_array, m_nexuscompression, dims_array);
      else
        NXmakedata(fileID, "indices", NX_INT64, 1, dims_array);
      NXopendata(fileID, "indices");
      NXputdata(fileID, (void*)(indices.data()) );
      std::string yUnits=ws->YUnit();
      std::string yUnitLabel=ws->YUnitLabel();
      NXputattr (fileID, "units",  reinterpret_cast<void*>(const_cast<char*>(yUnits.c_str())), static_cast<int>(yUnits.size()), NX_CHAR);
      NXputattr (fileID, "unit_label",  reinterpret_cast<void*>(const_cast<char*>(yUnitLabel.c_str())), static_cast<int>(yUnitLabel.size()), NX_CHAR);
      NXclosedata(fileID);
    }

    // Write out each field
    dims_array[0] = static_cast<int>(indices.back()); // TODO big truncation error! This is the # of events
    if (tofs)
      NXwritedata("tof", NX_FLOAT64, 1, dims_array, (void *)(tofs), compress);
    if (pulsetimes)
      NXwritedata("pulsetime", NX_INT64, 1, dims_array, (void *)(pulsetimes), compress);
    if (weights)
      NXwritedata("weight", NX_FLOAT32, 1, dims_array, (void *)(weights), compress);
    if (errorSquareds)
      NXwritedata("error_squared", NX_FLOAT32, 1, dims_array, (void *)(errorSquareds), compress);


    // Close up the overall group
    NXstatus status=NXclosegroup(fileID);
    return((status==NX_ERROR)?3:0);
  }
Exemple #4
0
/**
*  Only to be used if the KeepUnGrouped property is true, moves the spectra that were not selected
*  to be in a group to the end of the output spectrum
*  @param unGroupedSet :: list of WORKSPACE indexes that were included in a group
*  @param inputWS :: user selected input workspace for the algorithm
*  @param outputWS :: user selected output workspace for the algorithm
*  @param outIndex :: the next spectra index available after the grouped spectra
*/
void GroupDetectors2::moveOthersEvent(const std::set<int64_t> &unGroupedSet, DataObjects::EventWorkspace_const_sptr inputWS,
                                      DataObjects::EventWorkspace_sptr outputWS,size_t outIndex)
{
  g_log.debug() << "Starting to copy the ungrouped spectra" << std::endl;
  double prog4Copy = (1. - 1.*static_cast<double>(m_FracCompl))/static_cast<double>(unGroupedSet.size());

  std::set<int64_t>::const_iterator copyFrIt = unGroupedSet.begin();
  // go thorugh all the spectra in the input workspace
  for ( ; copyFrIt != unGroupedSet.end(); ++copyFrIt )
  {
    if( *copyFrIt == USED ) continue; //Marked as not to be used
    size_t sourceIndex = static_cast<size_t>(*copyFrIt);

    // The input spectrum we'll copy
    const EventList & inputSpec = inputWS->getEventList(sourceIndex);

    // Destination of the copying
    EventList & outputSpec=outputWS->getEventList(outIndex);

    // Copy the data
    outputSpec+=inputSpec;

    // Spectrum numbers etc.
    outputSpec.setSpectrumNo(inputSpec.getSpectrumNo());
    outputSpec.clearDetectorIDs();
    outputSpec.addDetectorIDs( inputSpec.getDetectorIDs() );

    // go to the next free index in the output workspace
    outIndex ++;
    // make regular progress reports and check for cancelling the algorithm
    if ( outIndex % INTERVAL == 0 )
    {
      m_FracCompl += INTERVAL*prog4Copy;
      if ( m_FracCompl > 1.0 )
      {
        m_FracCompl = 1.0;
      }
      progress(m_FracCompl);
      interruption_point();
    }
  }
  // Refresh the spectraDetectorMap
  outputWS->doneAddingEventLists();

  g_log.debug() << name() << " copied " << unGroupedSet.size()-1 << " ungrouped spectra\n";
}
/**
 * Create an output EventWorkspace w/o any events
 */
DataObjects::EventWorkspace_sptr CountEventsInPulses::createEventWorkspace(
    DataObjects::EventWorkspace_const_sptr parentws, bool sumspectrum) {
  size_t numspec;
  bool diffsize;
  if (sumspectrum) {
    numspec = 1;
    diffsize = true;
  } else {
    numspec = parentws->getNumberHistograms();
    diffsize = false;
  }

  DataObjects::EventWorkspace_sptr outputWS =
      boost::dynamic_pointer_cast<DataObjects::EventWorkspace>(
          API::WorkspaceFactory::Instance().create("EventWorkspace", numspec, 1,
                                                   1));
  API::WorkspaceFactory::Instance().initializeFromParent(parentws, outputWS,
                                                         diffsize);

  outputWS->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create("Time");

  return outputWS;
}
Exemple #6
0
/**
*  Move the user selected spectra in the input workspace into groups in the output workspace
*  @param inputWS :: user selected input workspace for the algorithm
*  @param outputWS :: user selected output workspace for the algorithm
*  @param prog4Copy :: the amount of algorithm progress to attribute to moving a single spectra
*  @return number of new grouped spectra
*/
size_t GroupDetectors2::formGroupsEvent( DataObjects::EventWorkspace_const_sptr inputWS, DataObjects::EventWorkspace_sptr  outputWS,
            const double prog4Copy)
{
  // get "Behaviour" string
  const std::string behaviour = getProperty("Behaviour");
  int bhv = 0;
  if ( behaviour == "Average" ) bhv = 1;

  API::MatrixWorkspace_sptr beh = API::WorkspaceFactory::Instance().create(
    "Workspace2D", static_cast<int>(m_GroupSpecInds.size()), 1, 1);

  g_log.debug() << name() << ": Preparing to group spectra into " << m_GroupSpecInds.size() << " groups\n";


  // where we are copying spectra to, we start copying to the start of the output workspace
  size_t outIndex = 0;
  // Only used for averaging behaviour. We may have a 1:1 map where a Divide would be waste as it would be just dividing by 1
  bool requireDivide(false);
  for ( storage_map::const_iterator it = m_GroupSpecInds.begin(); it != m_GroupSpecInds.end() ; ++it )
  {
    // This is the grouped spectrum
    EventList & outEL = outputWS->getEventList(outIndex);

    // The spectrum number of the group is the key
    outEL.setSpectrumNo(it->first);
    // Start fresh with no detector IDs
    outEL.clearDetectorIDs();

    // the Y values and errors from spectra being grouped are combined in the output spectrum
    // Keep track of number of detectors required for masking
    size_t nonMaskedSpectra(0);
    beh->dataX(outIndex)[0] = 0.0;
    beh->dataE(outIndex)[0] = 0.0;
    for( std::vector<size_t>::const_iterator wsIter = it->second.begin(); wsIter != it->second.end(); ++wsIter)
    {
      const size_t originalWI = *wsIter;

      const EventList & fromEL=inputWS->getEventList(originalWI);
      //Add the event lists with the operator
      outEL += fromEL;


      // detectors to add to the output spectrum
      outEL.addDetectorIDs(fromEL.getDetectorIDs() );
      try
      {
        Geometry::IDetector_const_sptr det = inputWS->getDetector(originalWI);
        if( !det->isMasked() ) ++nonMaskedSpectra;
      }
      catch(Exception::NotFoundError&)
      {
        // If a detector cannot be found, it cannot be masked
        ++nonMaskedSpectra;
      }
    }
    if( nonMaskedSpectra == 0 ) ++nonMaskedSpectra; // Avoid possible divide by zero
    if(!requireDivide) requireDivide = (nonMaskedSpectra > 1);
    beh->dataY(outIndex)[0] = static_cast<double>(nonMaskedSpectra);

    // make regular progress reports and check for cancelling the algorithm
    if ( outIndex % INTERVAL == 0 )
    {
      m_FracCompl += INTERVAL*prog4Copy;
      if ( m_FracCompl > 1.0 )
        m_FracCompl = 1.0;
      progress(m_FracCompl);
      interruption_point();
    }
    outIndex ++;
  }

  // Refresh the spectraDetectorMap
  outputWS->doneAddingEventLists();

  if ( bhv == 1 && requireDivide )
  {
    g_log.debug() << "Running Divide algorithm to perform averaging.\n";
    Mantid::API::IAlgorithm_sptr divide = createChildAlgorithm("Divide");
    divide->initialize();
    divide->setProperty<API::MatrixWorkspace_sptr>("LHSWorkspace", outputWS);
    divide->setProperty<API::MatrixWorkspace_sptr>("RHSWorkspace", beh);
    divide->setProperty<API::MatrixWorkspace_sptr>("OutputWorkspace", outputWS);
    divide->execute();
  }


  g_log.debug() << name() << " created " << outIndex << " new grouped spectra\n";
  return outIndex;
}
/** Executes the algorithm
 */
void FilterByTime2::exec() {
  DataObjects::EventWorkspace_const_sptr inWS =
      this->getProperty("InputWorkspace");
  if (!inWS) {
    g_log.error() << "Input is not EventWorkspace" << std::endl;
    throw std::invalid_argument("Input is not EventWorksapce");
  } else {
    g_log.debug() << "DB5244 InputWorkspace Name = " << inWS->getName()
                  << std::endl;
  }

  double starttime = this->getProperty("StartTime");
  double stoptime = this->getProperty("StopTime");
  std::string absstarttime = this->getProperty("AbsoluteStartTime");
  std::string absstoptime = this->getProperty("AbsoluteStopTime");

  std::string start, stop;
  if ((absstarttime != "") && (absstoptime != "") && (starttime <= 0.0) &&
      (stoptime <= 0.0)) {
    // Use the absolute string
    start = absstarttime;
    stop = absstoptime;
  } else if ((absstarttime != "" || absstoptime != "") &&
             (starttime > 0.0 || stoptime > 0.0)) {
    throw std::invalid_argument(
        "It is not allowed to provide both absolute time and relative time.");
  } else {
    // Use second
    std::stringstream ss;
    ss << starttime;
    start = ss.str();
    std::stringstream ss2;
    ss2 << stoptime;
    stop = ss2.str();
  }

  // 1. Generate Filters
  g_log.debug() << "\nDB441: About to generate Filter.  StartTime = "
                << starttime << "  StopTime = " << stoptime << std::endl;

  API::Algorithm_sptr genfilter =
      createChildAlgorithm("GenerateEventsFilter", 0.0, 20.0, true, 1);
  genfilter->initialize();
  genfilter->setPropertyValue("InputWorkspace", inWS->getName());
  genfilter->setPropertyValue("OutputWorkspace", "FilterWS");
  genfilter->setProperty("StartTime", start);
  genfilter->setProperty("StopTime", stop);
  genfilter->setProperty("UnitOfTime", "Seconds");
  genfilter->setProperty("FastLog", false);

  bool sucgen = genfilter->execute();
  if (!sucgen) {
    g_log.error() << "Unable to generate event filters" << std::endl;
    throw std::runtime_error("Unable to generate event filters");
  } else {
    g_log.debug() << "Filters are generated. " << std::endl;
  }

  API::Workspace_sptr filterWS = genfilter->getProperty("OutputWorkspace");
  if (!filterWS) {
    g_log.error() << "Unable to retrieve generated SplittersWorkspace object "
                     "from AnalysisDataService." << std::endl;
    throw std::runtime_error("Unable to retrieve Splittersworkspace. ");
  }

  // 2. Filter events
  g_log.debug() << "\nAbout to filter events. "
                << "\n";

  API::Algorithm_sptr filter =
      createChildAlgorithm("FilterEvents", 20.0, 100.0, true, 1);
  filter->initialize();
  filter->setPropertyValue("InputWorkspace", inWS->getName());
  filter->setPropertyValue("OutputWorkspaceBaseName", "ResultWS");
  filter->setProperty("SplitterWorkspace", filterWS);
  filter->setProperty("FilterByPulseTime", true);

  bool sucfilt = filter->execute();
  if (!sucfilt) {
    g_log.error() << "Unable to filter events" << std::endl;
    throw std::runtime_error("Unable to filter events");
  } else {
    g_log.debug() << "Filter events is successful. " << std::endl;
  }

  DataObjects::EventWorkspace_sptr optws =
      filter->getProperty("OutputWorkspace_0");

  this->setProperty("OutputWorkspace", optws);
}
Exemple #8
0
/** Check whether 2 event lists are identical
  */
bool CompareWorkspaces::compareEventWorkspaces(
    DataObjects::EventWorkspace_const_sptr ews1,
    DataObjects::EventWorkspace_const_sptr ews2) {
  bool checkallspectra = getProperty("CheckAllData");
  int numspec2print = getProperty("NumberMismatchedSpectraToPrint");
  int wsindex2print = getProperty("DetailedPrintIndex");

  // Compare number of spectra
  if (ews1->getNumberHistograms() != ews2->getNumberHistograms()) {
    recordMismatch("Mismatched number of histograms.");
    return false;
  }

  if (ews1->getEventType() != ews2->getEventType()) {
    recordMismatch("Mismatched type of events in the EventWorkspaces.");
    return false;
  }

  // Both will end up sorted anyway
  ews1->sortAll(PULSETIMETOF_SORT, m_Prog);
  ews2->sortAll(PULSETIMETOF_SORT, m_Prog);

  // Determine the tolerance for "tof" attribute and "weight" of events
  double toleranceWeight = Tolerance; // Standard tolerance
  int64_t tolerancePulse = 1;
  double toleranceTOF = 0.05;
  if ((ews1->getAxis(0)->unit()->label().ascii() != "microsecond") ||
      (ews2->getAxis(0)->unit()->label().ascii() != "microsecond")) {
    g_log.warning() << "Event workspace has unit as "
                    << ews1->getAxis(0)->unit()->label().ascii() << " and "
                    << ews2->getAxis(0)->unit()->label().ascii()
                    << ".  Tolerance of TOF is set to 0.05 still. "
                    << "\n";
    toleranceTOF = 0.05;
  }
  g_log.notice() << "TOF Tolerance = " << toleranceTOF << "\n";

  bool mismatchedEvent = false;
  int mismatchedEventWI = 0;

  size_t numUnequalNumEventsSpectra = 0;
  size_t numUnequalEvents = 0;
  size_t numUnequalTOFEvents = 0;
  size_t numUnequalPulseEvents = 0;
  size_t numUnequalBothEvents = 0;

  std::vector<int> vec_mismatchedwsindex;
  PARALLEL_FOR_IF(m_ParallelComparison && ews1->threadSafe() &&
                  ews2->threadSafe())
  for (int i = 0; i < static_cast<int>(ews1->getNumberHistograms()); ++i) {
    PARALLEL_START_INTERUPT_REGION
    m_Prog->report("EventLists");
    if (!mismatchedEvent ||
        checkallspectra) // This guard will avoid checking unnecessarily
    {
      const EventList &el1 = ews1->getEventList(i);
      const EventList &el2 = ews2->getEventList(i);
      bool printdetail = (i == wsindex2print);
      if (printdetail) {
        g_log.information() << "Spectrum " << i
                            << " is set to print out in details. "
                            << "\n";
      }

      if (!el1.equals(el2, toleranceTOF, toleranceWeight, tolerancePulse)) {
        size_t tempNumTof = 0;
        size_t tempNumPulses = 0;
        size_t tempNumBoth = 0;

        int tempNumUnequal = 0;

        if (el1.getNumberEvents() != el2.getNumberEvents()) {
          // Number of events are different
          tempNumUnequal = -1;
        } else {
          tempNumUnequal = compareEventsListInDetails(
              el1, el2, toleranceTOF, toleranceWeight, tolerancePulse,
              printdetail, tempNumPulses, tempNumTof, tempNumBoth);
        }

        mismatchedEvent = true;
        mismatchedEventWI = i;
        PARALLEL_CRITICAL(CompareWorkspaces) {
          if (tempNumUnequal == -1) {
            // 2 spectra have different number of events
            ++numUnequalNumEventsSpectra;
          } else {
            // 2 spectra have some events different to each other
            numUnequalEvents += static_cast<size_t>(tempNumUnequal);
            numUnequalTOFEvents += tempNumTof;
            numUnequalPulseEvents += tempNumPulses;
            numUnequalBothEvents += tempNumBoth;
          }

          vec_mismatchedwsindex.push_back(i);
        } // Parallel critical region

      } // If elist 1 is not equal to elist 2
    }
    PARALLEL_END_INTERUPT_REGION
  }
  //----------------------------------------------------------------------------------------------
  /// @copydoc Mantid::API::Algorithm::exec()
  void ResetNegatives::exec()
  {
    MatrixWorkspace_sptr inputWS = this->getProperty("InputWorkspace");
    MatrixWorkspace_sptr outputWS = this->getProperty("OutputWorkspace");

    // get the minimum for each spectrum
    IAlgorithm_sptr alg = this->createChildAlgorithm("Min", 0., .1);
    alg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", inputWS);
    alg->executeAsChildAlg();
    MatrixWorkspace_const_sptr minWS = alg->getProperty("OutputWorkspace");

    // determine if there is anything to do
    int64_t nHist = static_cast<int64_t>(minWS->getNumberHistograms());
    bool hasNegative = false;
    for (int64_t i = 0; i < nHist; i++)
    {
      if (minWS->readY(i)[0] < 0)
      {
        hasNegative = true;
      }
      break;
    }

    // get out early if there is nothing to do
    if (!hasNegative)
    {
      g_log.information() << "No values are negative. Copying InputWorkspace to OutputWorkspace\n";
      if (inputWS != outputWS)
      {
        IAlgorithm_sptr alg = this->createChildAlgorithm("CloneWorkspace", .1, 1.);
        alg->setProperty<Workspace_sptr>("InputWorkspace", inputWS);
        alg->executeAsChildAlg();

        Workspace_sptr temp = alg->getProperty("OutputWorkspace");
        setProperty("OutputWorkspace", boost::dynamic_pointer_cast<MatrixWorkspace>(temp));
      }
      return;
    }

    // sort the event list to make it fast and thread safe
    DataObjects::EventWorkspace_const_sptr eventWS
                 = boost::dynamic_pointer_cast<const DataObjects::EventWorkspace>( inputWS );
    if (eventWS)
      eventWS->sortAll(DataObjects::TOF_SORT, NULL);

    Progress prog(this, .1, 1., 2*nHist);

    // generate output workspace - copy X and dY
    outputWS = API::WorkspaceFactory::Instance().create(inputWS);
    PARALLEL_FOR2(inputWS,outputWS)
    for (int64_t i = 0; i < nHist; i++)
    {
      PARALLEL_START_INTERUPT_REGION
      outputWS->dataY(i) = inputWS->readY(i);
      outputWS->dataE(i) = inputWS->readE(i);
      outputWS->setX(i, inputWS->refX(i)); // share the pointer more
      prog.report();
      PARALLEL_END_INTERUPT_REGION
    }
    PARALLEL_CHECK_INTERUPT_REGION

    // do the actual work
    if (this->getProperty("AddMinimum"))
    {
        this->pushMinimum(minWS, outputWS, prog);
    }
    else
    {
      this->changeNegatives(minWS, this->getProperty("ResetValue"), outputWS, prog);
    }

    setProperty("OutputWorkspace",outputWS);
  }