Beispiel #1
0
    /** Executes the rebin algorithm
    *
    *  @throw runtime_error Thrown if the bin range does not intersect the range of the input workspace
    */
    void Rebin::exec()
    {
      // Get the input workspace
      MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");
      MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace");

      // Are we preserving event workspace-iness?
      bool PreserveEvents = getProperty("PreserveEvents");

      // Rebinning in-place
      bool inPlace = (inputWS == outputWS);

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

      // The validator only passes parameters with size 1, or 3xn.  No need to check again here
      if (in_params.size() >= 3){
        // Input are min, delta, max
        rb_params = in_params;

      } else if (in_params.size() == 1){
        double xmin = 0.;
        double xmax = 0.;
        inputWS->getXMinMax(xmin, xmax);

        g_log.information() << "Using the current min and max as default " << xmin << ", " << xmax << std::endl;

        rb_params.push_back(xmin);
        rb_params.push_back(in_params[0]);
        rb_params.push_back(xmax);

      }

      const bool dist = inputWS->isDistribution();

      const bool isHist = inputWS->isHistogramData();

      // workspace independent determination of length
      const int histnumber = static_cast<int>(inputWS->getNumberHistograms());
      MantidVecPtr XValues_new;
      // create new output X axis
      const int ntcnew = VectorHelper::createAxisFromRebinParams(rb_params, XValues_new.access());

      //---------------------------------------------------------------------------------
      //Now, determine if the input workspace is actually an EventWorkspace
      EventWorkspace_const_sptr eventInputWS = boost::dynamic_pointer_cast<const EventWorkspace>(inputWS);

      if (eventInputWS != NULL)
      {
        //------- EventWorkspace as input -------------------------------------
        EventWorkspace_sptr eventOutputWS = boost::dynamic_pointer_cast<EventWorkspace>(outputWS);

        if (inPlace && PreserveEvents)
        {
          // -------------Rebin in-place, preserving events ----------------------------------------------
          // This only sets the X axis. Actual rebinning will be done upon data access.
          eventOutputWS->setAllX(XValues_new);
          this->setProperty("OutputWorkspace", boost::dynamic_pointer_cast<MatrixWorkspace>(eventOutputWS));
        }
        else if (!inPlace && PreserveEvents)
        {
          // -------- NOT in-place, but you want to keep events for some reason. ----------------------
          // Must copy the event workspace to a new EventWorkspace (and bin that).

          //Make a brand new EventWorkspace
          eventOutputWS = boost::dynamic_pointer_cast<EventWorkspace>(
              API::WorkspaceFactory::Instance().create("EventWorkspace", inputWS->getNumberHistograms(), 2, 1));
          //Copy geometry over.
          API::WorkspaceFactory::Instance().initializeFromParent(inputWS, eventOutputWS, false);
          //You need to copy over the data as well.
          eventOutputWS->copyDataFrom( (*eventInputWS) );

          // This only sets the X axis. Actual rebinning will be done upon data access.
          eventOutputWS->setAllX(XValues_new);

          //Cast to the matrixOutputWS and save it
          this->setProperty("OutputWorkspace", boost::dynamic_pointer_cast<MatrixWorkspace>(eventOutputWS));
        }
        else
        {
          //--------- Different output, OR you're inplace but not preserving Events --- create a Workspace2D -------
          g_log.information() << "Creating a Workspace2D from the EventWorkspace " << eventInputWS->getName() << ".\n";

          //Create a Workspace2D
          // This creates a new Workspace2D through a torturous route using the WorkspaceFactory.
          // The Workspace2D is created with an EMPTY CONSTRUCTOR
          outputWS = WorkspaceFactory::Instance().create("Workspace2D",histnumber,ntcnew,ntcnew-1);
          WorkspaceFactory::Instance().initializeFromParent(inputWS, outputWS, true);

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

          //Go through all the histograms and set the data
          PARALLEL_FOR3(inputWS, eventInputWS, outputWS)
          for (int i=0; i < histnumber; ++i)
          {
            PARALLEL_START_INTERUPT_REGION

            //Set the X axis for each output histogram
            outputWS->setX(i, XValues_new);

            //Get a const event list reference. eventInputWS->dataY() doesn't work.
            const EventList& el = eventInputWS->getEventList(i);
            MantidVec y_data, e_data;
            // The EventList takes care of histogramming.
            el.generateHistogram(*XValues_new, y_data, e_data);

            //Copy the data over.
            outputWS->dataY(i).assign(y_data.begin(), y_data.end());
            outputWS->dataE(i).assign(e_data.begin(), e_data.end());

            //Report progress
            prog.report(name());
            PARALLEL_END_INTERUPT_REGION
          }
          PARALLEL_CHECK_INTERUPT_REGION

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

          //Copy the units over too.
          for (int i=0; i < outputWS->axes(); ++i)
            outputWS->getAxis(i)->unit() = inputWS->getAxis(i)->unit();
          outputWS->setYUnit(eventInputWS->YUnit());
          outputWS->setYUnitLabel(eventInputWS->YUnitLabel());

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

      } // END ---- EventWorkspace