예제 #1
0
/** Looks for and examines a peak close to that specified by the input parameters and
*  examines it to find a representative time for when the neutrons hit the detector
*  @param WS :: the workspace containing the monitor spectrum
*  @param monitIn :: the index of the histogram that contains the monitor spectrum
*  @param peakTime :: the estimated TOF of the monitor peak in the time units of the workspace
*  @return a time of flight value in the peak in microseconds
*  @throw invalid_argument if a good peak fit wasn't made or the input workspace does not have common binning
*  @throw out_of_range if the peak runs off the edge of the histogram
*  @throw runtime_error a sub-algorithm just falls over
*/
double GetEi::getPeakCentre(API::MatrixWorkspace_const_sptr WS, const int64_t monitIn, const double peakTime)
{
  const MantidVec& timesArray = WS->readX(monitIn);
  // we search for the peak only inside some window because there are often more peaks in the monitor histogram
  double halfWin = ( timesArray.back() - timesArray.front() )*HALF_WINDOW;
  // runs CropWorkspace as a sub-algorithm to and puts the result in a new temporary workspace that will be deleted when this algorithm has finished
  extractSpec(monitIn, peakTime-halfWin, peakTime+halfWin);
  // converting the workspace to count rate is required by the fitting algorithm if the bin widths are not all the same
  WorkspaceHelpers::makeDistribution(m_tempWS);
  // look out for user cancel messgages as the above command can take a bit of time
  advanceProgress(GET_COUNT_RATE);

  // to store fit results
  int64_t centreGausInd;
  double height, backGroundlev;
  getPeakEstimates(height, centreGausInd, backGroundlev);
  // look out for user cancel messgages
  advanceProgress(FIT_PEAK);

  // the peak centre is defined as the centre of the two half maximum points as this is better for asymmetric peaks
  // first loop backwards along the histogram to get the first half height point
  const double lHalf = findHalfLoc(centreGausInd, height, backGroundlev, GO_LEFT);
  // go forewards to get the half height on the otherside of the peak
  const double rHalf = findHalfLoc(centreGausInd, height, backGroundlev, GO_RIGHT);
  // the peak centre is defined as the mean of the two half height times 
  return (lHalf + rHalf)/2;
}
예제 #2
0
    /**
     * Integrate each spectra to get the number of counts
     * @param inputWS :: The workspace to integrate
     * @param indexMin :: The lower bound of the spectra to integrate
     * @param indexMax :: The upper bound of the spectra to integrate
     * @param lower :: The lower bound
     * @param upper :: The upper bound
     * @param outputWorkspace2D :: set to true to output a workspace 2D even if the input is an EventWorkspace
     * @returns A workspace containing the integrated counts
     */
    MatrixWorkspace_sptr 
    DetectorDiagnostic::integrateSpectra(MatrixWorkspace_sptr inputWS, 
        const int indexMin, const int indexMax, const double lower, const double upper,
        const bool outputWorkspace2D)
    {
      g_log.debug() << "Integrating input spectra.\n";
      // If the input spectra only has one bin, assume it has been integrated already
      // but we need to pass it to the algorithm so that a copy of the input workspace is
      // actually created to use for further calculations
      // get percentage completed estimates for now, t0 and when we've finished t1
      double t0 = m_fracDone, t1 = advanceProgress(RTGetTotalCounts);
      IAlgorithm_sptr childAlg = createChildAlgorithm("Integration", t0, t1 );
      childAlg->setProperty( "InputWorkspace", inputWS );
      childAlg->setProperty( "StartWorkspaceIndex", indexMin );
      childAlg->setProperty( "EndWorkspaceIndex", indexMax );
      // pass inputed values straight to this integration trusting the checking done there
      childAlg->setProperty("RangeLower",  lower );
      childAlg->setProperty("RangeUpper", upper);
      childAlg->setPropertyValue("IncludePartialBins", "1");
      childAlg->executeAsChildAlg();

      // Convert to 2D if desired, and if the input was an EventWorkspace.
      MatrixWorkspace_sptr outputW = childAlg->getProperty("OutputWorkspace");
      MatrixWorkspace_sptr finalOutputW = outputW;
      if (outputWorkspace2D && boost::dynamic_pointer_cast<EventWorkspace>(outputW))
      {
        g_log.debug() << "Converting output Event Workspace into a Workspace2D." << std::endl;
        childAlg = createChildAlgorithm("ConvertToMatrixWorkspace", t0, t1 );
        childAlg->setProperty("InputWorkspace", outputW);
        childAlg->executeAsChildAlg();
        finalOutputW = childAlg->getProperty("OutputWorkspace");
      }

      return finalOutputW;
    }
예제 #3
0
 /** Makes a workspace with the total solid angle all the detectors in each spectrum cover from the sample
  *  note returns an empty shared pointer on failure, uses the SolidAngle algorithm
  * @param firstSpec :: the index number of the first histogram to analyse
  * @param lastSpec :: the index number of the last histogram to analyse
  * @return A pointer to the workspace (or an empty pointer)
  */
 API::MatrixWorkspace_sptr MedianDetectorTest::getSolidAngles(int firstSpec, int lastSpec )
 {
   g_log.debug("Calculating solid angles");
   // get percentage completed estimates for now, t0 and when we've finished t1
   double t0 = m_fracDone, t1 = advanceProgress(RTGetSolidAngle);
   IAlgorithm_sptr childAlg = createChildAlgorithm("SolidAngle", t0, t1, true);
   childAlg->setProperty( "InputWorkspace", m_inputWS);
   childAlg->setProperty( "StartWorkspaceIndex", firstSpec );
   childAlg->setProperty( "EndWorkspaceIndex", lastSpec );
   try
   {
     // Execute the Child Algorithm, it could throw a runtime_error at this point which would abort execution
     childAlg->execute();
     if ( ! childAlg->isExecuted() )
     {
       throw std::runtime_error("Unexpected problem calculating solid angles");
     }
   }
   //catch all exceptions because the solid angle calculation is optional
   catch(std::exception&)
   {
     g_log.warning(
         "Precision warning:  Can't find detector geometry " + name() +
         " will continue with the solid angles of all spectra set to the same value" );
     failProgress(RTGetSolidAngle);
     //The return is an empty workspace pointer, which must be handled by the calling function
     MatrixWorkspace_sptr empty;
     //function returns normally
     return empty;
   }
   return childAlg->getProperty("OutputWorkspace");
 }
예제 #4
0
        Node<Status, T> createLeaf(
                const typename NodeTypes<Status, T>::ValueList& originalValueList,
                int depthRemaining,
                const State& collectedState)
        {
            typedef typename NodeTypes<Status, T>::ValuePtr ValuePtr;
            typedef typename NodeTypes<Status, T>::ValueList ValueList;

            ValueList valueList;
            if (checker_) {
                boost::remove_copy_if(
                        originalValueList,
                        std::back_inserter(valueList),
                        [this, &collectedState](const ValuePtr& value)
                        {
                            State state(collectedState);
                            for (Point  p: value->first.state()) {
                                state.addStone(p);
                            }
                            return !checkState(*checker_, value->first.table(), state);
                        });
            } else {
                valueList = originalValueList;
            }
            advanceProgress(valueList.size(), depthRemaining);
            return LeafNode<Status, T>(std::move(valueList));
        }
예제 #5
0
    /** 
     * Convert to a distribution
     * @param workspace :: The input workspace to convert to a count rate
     * @return distribution workspace with equiv. data
     */
    API::MatrixWorkspace_sptr DetectorDiagnostic::convertToRate(API::MatrixWorkspace_sptr workspace)
    {
      if( workspace->isDistribution() )
      {
        g_log.information() << "Workspace already contains a count rate, nothing to do.\n";
        return workspace;
      }

      g_log.information("Calculating time averaged count rates");
      // get percentage completed estimates for now, t0 and when we've finished t1
      double t0 = m_fracDone, t1 = advanceProgress(RTGetRate);
      IAlgorithm_sptr childAlg = createChildAlgorithm("ConvertToDistribution", t0, t1);
      childAlg->setProperty<MatrixWorkspace_sptr>("Workspace", workspace); 
      // Now execute the Child Algorithm but allow any exception to bubble up
      childAlg->execute();
      return childAlg->getProperty("Workspace");
    }
예제 #6
0
    /** 
     * Takes a single valued histogram workspace and assesses which histograms are within the limits. 
     * Those that are not are masked on the input workspace.
     * @param countsWS :: Input/Output Integrated workspace to diagnose.
     * @param medianvec The median value calculated from the current counts.
     * @param indexmap Index map.
     * @param maskWS :: A mask workspace to apply.
     * @return The number of detectors that failed the tests, not including those skipped.
     */
    int MedianDetectorTest::doDetectorTests(const API::MatrixWorkspace_sptr countsWS, const std::vector<double> medianvec,
                                            std::vector<std::vector<size_t> > indexmap, API::MatrixWorkspace_sptr maskWS)
    {
      g_log.debug("Applying the criteria to find failing detectors");

      // A spectra can't fail if the statistics show its value is consistent with the mean value, 
      // check the error and how many errorbars we are away
      const double minSigma = getProperty("SignificanceTest");

      // prepare to report progress
      const int numSpec(m_maxSpec - m_minSpec);
      const int progStep = static_cast<int>(ceil(numSpec/30.0));
      int steps(0);

      const double deadValue(1.0);
      int numFailed(0);


      bool checkForMask = false;
      Geometry::Instrument_const_sptr instrument = countsWS->getInstrument();
      if (instrument != NULL)
      {
        checkForMask = ((instrument->getSource() != NULL) && (instrument->getSample() != NULL));
      }

      PARALLEL_FOR2(countsWS, maskWS)
      for (int j=0;j<static_cast<int>(indexmap.size());++j)
      {
        std::vector<size_t> hists=indexmap.at(j);
        double median=medianvec.at(j);
        const size_t nhist = hists.size();
        g_log.debug() << "new component with " <<nhist <<" spectra.\n";
        for (size_t i = 0; i < nhist; ++i)
        {
          g_log.debug() << "Counts workspace index=" << i 
                        << ", Mask workspace index=" << hists.at(i) << std::endl;
          PARALLEL_START_INTERUPT_REGION
          ++steps;
          // update the progressbar information
          if (steps % progStep == 0)
          {
            progress(advanceProgress(progStep*static_cast<double>(RTMarkDetects)/numSpec));
          }

          if (checkForMask)
          {
            const std::set<detid_t>& detids = countsWS->getSpectrum(i)->getDetectorIDs();
            if (instrument->isDetectorMasked(detids))
            {
              maskWS->dataY(hists.at(i))[0] = deadValue;
              continue;
            }
            if (instrument->isMonitor(detids))
            {
              // Don't include in calculation but don't mask it
              continue;
            }
          }

          const double signal = countsWS->dataY(hists.at(i))[0];

          // Mask out NaN and infinite
          if( boost::math::isinf(signal) || boost::math::isnan(signal) )
          {
            maskWS->dataY(hists.at(i))[0] = deadValue;
            PARALLEL_ATOMIC
            ++numFailed;
            continue;
          }

          const double error = minSigma*countsWS->readE(hists.at(i))[0];

          if( (signal < median*m_loFrac && (signal-median < -error)) ||
              (signal > median*m_hiFrac && (signal-median > error)) )
          {
            maskWS->dataY(hists.at(i))[0] = deadValue;
            PARALLEL_ATOMIC
            ++numFailed;
          }

          PARALLEL_END_INTERUPT_REGION
        }
        PARALLEL_CHECK_INTERUPT_REGION

      // Log finds
      g_log.information() << numFailed << " spectra failed the median tests.\n";

      }
      return numFailed;
    }
예제 #7
0
 /** Update the percentage complete estimate assuming that the algorithm aborted a task with the given
  *  estimated run time
  * @param aborted :: the amount of algorithm run time that was saved by aborting a 
  * part of the algorithm, where m_TotalTime holds the total algorithm run time
  */
 void DetectorDiagnostic::failProgress(RunTime aborted)
 {
   advanceProgress(-aborted);
   m_TotalTime -= aborted;
 };
예제 #8
0
/**
 * Apply the detector test criterion
 * @param counts1 :: A workspace containing the integrated counts of the first
 * white beam run
 * @param counts2 :: A workspace containing the integrated counts of the first
 * white beam run
 * @param average :: The computed median
 * @param variation :: The allowed variation in terms of number of medians, i.e
 * those spectra where
 * the ratio of the counts outside this range will fail the tests and will be
 * masked on counts1
 * @return number of detectors for which tests failed
 */
int DetectorEfficiencyVariation::doDetectorTests(
    API::MatrixWorkspace_const_sptr counts1,
    API::MatrixWorkspace_const_sptr counts2, const double average,
    double variation) {
  // DIAG in libISIS did this.  A variation of less than 1 doesn't make sense in
  // this algorithm
  if (variation < 1) {
    variation = 1.0 / variation;
  }
  // criterion for if the the first spectrum is larger than expected
  double largest = average * variation;
  // criterion for if the the first spectrum is lower than expected
  double lowest = average / variation;

  const int numSpec = static_cast<int>(counts1->getNumberHistograms());
  const int progStep = static_cast<int>(std::ceil(numSpec / 30.0));

  // Create a workspace for the output
  MaskWorkspace_sptr maskWS = this->generateEmptyMask(counts1);

  bool checkForMask = false;
  Geometry::Instrument_const_sptr instrument = counts1->getInstrument();
  if (instrument != nullptr) {
    checkForMask = ((instrument->getSource() != nullptr) &&
                    (instrument->getSample() != nullptr));
  }

  const double deadValue(1.0);
  int numFailed(0);
  PARALLEL_FOR3(counts1, counts2, maskWS)
  for (int i = 0; i < numSpec; ++i) {
    PARALLEL_START_INTERUPT_REGION
    // move progress bar
    if (i % progStep == 0) {
      advanceProgress(progStep * static_cast<double>(RTMarkDetects) / numSpec);
      progress(m_fracDone);
      interruption_point();
    }

    if (checkForMask) {
      const std::set<detid_t> &detids =
          counts1->getSpectrum(i)->getDetectorIDs();
      if (instrument->isMonitor(detids))
        continue;
      if (instrument->isDetectorMasked(detids)) {
        // Ensure it is masked on the output
        maskWS->dataY(i)[0] = deadValue;
        continue;
      }
    }

    const double signal1 = counts1->readY(i)[0];
    const double signal2 = counts2->readY(i)[0];

    // Mask out NaN and infinite
    if (boost::math::isinf(signal1) || boost::math::isnan(signal1) ||
        boost::math::isinf(signal2) || boost::math::isnan(signal2)) {
      maskWS->dataY(i)[0] = deadValue;
      PARALLEL_ATOMIC
      ++numFailed;
      continue;
    }

    // Check the ratio is within the given range
    const double ratio = signal1 / signal2;
    if (ratio < lowest || ratio > largest) {
      maskWS->dataY(i)[0] = deadValue;
      PARALLEL_ATOMIC
      ++numFailed;
    }

    PARALLEL_END_INTERUPT_REGION
  }
  PARALLEL_CHECK_INTERUPT_REGION

  // Register the results with the ADS
  setProperty("OutputWorkspace", maskWS);

  return numFailed;
}
예제 #9
0
ZSwcTree* ZNeuronTracer::trace(Stack *stack, bool doResampleAfterTracing)
{
  startProgress();

  ZSwcTree *tree = NULL;

  //Extract seeds
  //First mask
  std::cout << "Binarizing ..." << std::endl;

  /* <bw> allocated */
  Stack *bw = binarize(stack);
  C_Stack::translate(bw, GREY, 1);

  advanceProgress(0.05);

  std::cout << "Removing noise ..." << std::endl;

  /* <mask> allocated */
  Stack *mask = bwsolid(bw);
  advanceProgress(0.05);

  /* <bw> freed */
  C_Stack::kill(bw);

  //Thin line mask
  /* <mask2> allocated */
  Stack *mask2 = NULL;

  if (m_enhancingMask) {
    std::cout << "Enhancing thin branches ..." << std::endl;
    mask2 = enhanceLine(stack);
    advanceProgress(0.05);
  }

  if (mask2 != NULL) {
    std::cout << "Making mask for thin branches ..." << std::endl;
    ZStackBinarizer binarizer;
    binarizer.setMethod(ZStackBinarizer::BM_LOCMAX);
    binarizer.setRetryCount(5);
    binarizer.setMinObjectSize(27);

    if (binarizer.binarize(mask2) == false) {
      std::cout << "Thresholding failed" << std::endl;
      C_Stack::kill(mask2);
      mask2 = NULL;
    }
  }

  /* <mask2> freed */
  if (mask2 != NULL) {
    C_Stack::translate(mask2, GREY, 1);
    Stack_Or(mask, mask2, mask);
    C_Stack::kill(mask2);
    mask2 = NULL;
  }
  advanceProgress(0.05);

  //Trace each seed
  std::cout << "Extracting seed points ..." << std::endl;

  /* <seedPointArray> allocated */
  Geo3d_Scalar_Field *seedPointArray = extractSeed(mask);
  m_mask = mask;

  advanceProgress(0.05);

  std::cout << "Sorting seeds ..." << std::endl;
  ZNeuronTraceSeeder seeder;
  setTraceScoreThreshold(TRACING_SEED);
  m_baseMask = seeder.sortSeed(seedPointArray, stack, m_traceWorkspace);

#ifdef _DEBUG_2
  C_Stack::write(GET_TEST_DATA_DIR + "/test.tif", m_baseMask);
#endif

  advanceProgress(0.1);

  /* <seedPointArray> freed */
  Kill_Geo3d_Scalar_Field(seedPointArray);

  std::vector<Local_Neuroseg>& locsegArray = seeder.getSeedArray();
  std::vector<double>& scoreArray = seeder.getScoreArray();

  std::cout << "Tracing ..." << std::endl;

  /* <chainArray> allocated */

  std::vector<Locseg_Chain*> chainArray = trace(stack, locsegArray, scoreArray);

  if (m_recover > 0) {
    std::vector<Locseg_Chain*> newChainArray = recover(stack);
    chainArray.insert(
          chainArray.end(), newChainArray.begin(), newChainArray.end());
  }
  advanceProgress(0.1);

  chainArray = screenChain(stack, chainArray);
  advanceProgress(0.3);

  /* <mask2> freed */
//  C_Stack::kill(mask);

  std::cout << "Reconstructing ..." << std::endl;
  ZNeuronConstructor constructor;
  constructor.setWorkspace(m_connWorkspace);
  constructor.setSignal(stack);

  //Create neuron structure

  BOOL oldSpTest = m_connWorkspace->sp_test;
  if (chainArray.size() > 1000) {
    std::cout << "Too many chains: " << chainArray.size() << std::endl;
    std::cout << "Turn off shortest path test" << std::endl;
    m_connWorkspace->sp_test = FALSE;
  }

  /* free <chainArray> */
  tree = constructor.reconstruct(chainArray);

  m_connWorkspace->sp_test = oldSpTest;

  advanceProgress(0.1);

  //Post process
  Swc_Tree_Remove_Zigzag(tree->data());
  Swc_Tree_Tune_Branch(tree->data());
  Swc_Tree_Remove_Spur(tree->data());
  Swc_Tree_Merge_Close_Node(tree->data(), 0.01);
  Swc_Tree_Remove_Overshoot(tree->data());

  if (doResampleAfterTracing) {
    ZSwcResampler resampler;
    resampler.optimalDownsample(tree);
  }
  advanceProgress(0.1);

  std::cout << "Done!" << std::endl;
  endProgress();

  return tree;
}