/** 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; }
/** * 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; }
/** 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"); }
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)); }
/** * 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"); }
/** * 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; }
/** 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; };
/** * 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; }
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; }