/** * @brief Handle setting fit workspace. * * Creates a list of Q values from each spectrum to be used with WorkspaceIndex * attribute. * * @param ws Pointer to workspace */ void InelasticDiffSphere::setWorkspace( boost::shared_ptr<const API::Workspace> ws) { m_qValueCache.clear(); auto workspace = boost::dynamic_pointer_cast<const API::MatrixWorkspace>(ws); if (!workspace) return; size_t numHist = workspace->getNumberHistograms(); for (size_t idx = 0; idx < numHist; idx++) { Mantid::Geometry::IDetector_const_sptr det; try { det = workspace->getDetector(idx); } catch (Kernel::Exception::NotFoundError &) { m_qValueCache.clear(); g_log.information("Cannot populate Q values from workspace"); break; } try { double efixed = workspace->getEFixed(det); double usignTheta = 0.5 * workspace->detectorTwoTheta(*det); double q = Mantid::Kernel::UnitConversion::run(usignTheta, efixed); m_qValueCache.push_back(q); } catch (std::runtime_error &) { m_qValueCache.clear(); g_log.information("Cannot populate Q values from workspace"); return; } } }
void SANSSolidAngleCorrection::execEvent() { MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); // generate the output workspace pointer MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace"); if (outputWS != inputWS) { outputWS = inputWS->clone(); setProperty("OutputWorkspace", outputWS); } auto outputEventWS = boost::dynamic_pointer_cast<EventWorkspace>(outputWS); const int numberOfSpectra = static_cast<int>(outputEventWS->getNumberHistograms()); Progress progress(this, 0.0, 1.0, numberOfSpectra); progress.report("Solid Angle Correction"); PARALLEL_FOR1(outputEventWS) for (int i = 0; i < numberOfSpectra; i++) { PARALLEL_START_INTERUPT_REGION IDetector_const_sptr det; try { det = outputEventWS->getDetector(i); } catch (Exception::NotFoundError &) { g_log.warning() << "Workspace index " << i << " has no detector assigned to it - discarding\n"; // Catch if no detector. Next line tests whether this happened - test // placed // outside here because Mac Intel compiler doesn't like 'continue' in a // catch // in an openmp block. } if (!det) continue; // Skip if we have a monitor or if the detector is masked. if (det->isMonitor() || det->isMasked()) continue; // Compute solid angle correction factor const bool is_tube = getProperty("DetectorTubes"); const double tanTheta = tan(outputEventWS->detectorTwoTheta(*det)); const double theta_term = sqrt(tanTheta * tanTheta + 1.0); double corr; if (is_tube) { const double tanAlpha = tan(getYTubeAngle(det, inputWS)); const double alpha_term = sqrt(tanAlpha * tanAlpha + 1.0); corr = alpha_term * theta_term * theta_term; } else { corr = theta_term * theta_term * theta_term; } EventList &el = outputEventWS->getSpectrum(i); el *= corr; progress.report("Solid Angle Correction"); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION setProperty("OutputMessage", "Solid angle correction applied"); }
std::vector<Geometry::IDetector_const_sptr> SpectrumInfo::getDetectorVector(const size_t index) const { const auto &det = getDetector(index); const auto &ndet = det.nDets(); if (ndet > 1) { const auto group = dynamic_cast<const Geometry::DetectorGroup *>(&det); return group->getDetectors(); } else { size_t thread = static_cast<size_t>(PARALLEL_THREAD_NUMBER); return {m_lastDetector[thread]}; } }
void RODFDetectorCon::mesoJoin(const std::string& nid, const std::vector<std::string>& oldids) { // build the new detector const RODFDetector& first = getDetector(*(oldids.begin())); RODFDetector* newDet = new RODFDetector(nid, first); addDetector(newDet); // delete previous for (std::vector<std::string>::const_iterator i = oldids.begin(); i != oldids.end(); ++i) { removeDetector(*i); } }
/** * If the InstrumentParameter property is set then it attempts to retrieve the parameter * from the component, else it returns the value of the Factor property * @param inputWS A pointer to the input workspace * @param index The current index to inspect * @return Value for the scale factor */ double ScaleX::getScaleFactor(const API::MatrixWorkspace_const_sptr & inputWS, const size_t index) { if(m_parname.empty()) return m_algFactor; // Try and get factor from component. If we see a DetectorGroup use this will use the first component Geometry::IDetector_const_sptr det; auto inst = inputWS->getInstrument(); auto *spec = inputWS->getSpectrum(index); const auto & ids = spec->getDetectorIDs(); const size_t ndets(ids.size()); if(ndets > 0) { try { det = inst->getDetector(*ids.begin()); } catch(Exception::NotFoundError&) { return 0.0; } } else return 0.0; const auto & pmap = inputWS->constInstrumentParameters(); auto par = pmap.getRecursive(det->getComponentID(), m_parname); if(par) { if(!m_combine) return par->value<double>(); else return m_binOp(m_algFactor,par->value<double>()); } else { std::ostringstream os; os << "Spectrum at index '" << index << "' has no parameter named '" << m_parname << "'\n"; throw std::runtime_error(os.str()); } }
/// Returns true if the detector(s) associated with the spectrum are masked. bool SpectrumInfo::isMasked(const size_t index) const { return getDetector(index).isMasked(); }
void CorrectKiKf::execEvent() { g_log.information("Processing event workspace"); const MatrixWorkspace_const_sptr matrixInputWS = getProperty("InputWorkspace"); auto inputWS = boost::dynamic_pointer_cast<const EventWorkspace>(matrixInputWS); // generate the output workspace pointer API::MatrixWorkspace_sptr matrixOutputWS = getProperty("OutputWorkspace"); if (matrixOutputWS != matrixInputWS) { matrixOutputWS = matrixInputWS->clone(); setProperty("OutputWorkspace", matrixOutputWS); } auto outputWS = boost::dynamic_pointer_cast<EventWorkspace>(matrixOutputWS); const std::string emodeStr = getProperty("EMode"); double efixedProp = getProperty("EFixed"), efixed; if (efixedProp == EMPTY_DBL()) { if (emodeStr == "Direct") { // Check if it has been store on the run object for this workspace if (inputWS->run().hasProperty("Ei")) { Kernel::Property *eiprop = inputWS->run().getProperty("Ei"); efixedProp = boost::lexical_cast<double>(eiprop->value()); g_log.debug() << "Using stored Ei value " << efixedProp << "\n"; } else { throw std::invalid_argument( "No Ei value has been set or stored within the run information."); } } else { // If not specified, will try to get Ef from the parameter file for // indirect geometry, // but it will be done for each spectrum separately, in case of different // analyzer crystals } } // Get the parameter map const ParameterMap &pmap = outputWS->constInstrumentParameters(); int64_t numHistograms = static_cast<int64_t>(inputWS->getNumberHistograms()); API::Progress prog = API::Progress(this, 0.0, 1.0, numHistograms); PARALLEL_FOR_IF(Kernel::threadSafe(*outputWS)) for (int64_t i = 0; i < numHistograms; ++i) { PARALLEL_START_INTERUPT_REGION double Efi = 0; // Now get the detector object for this histogram to check if monitor // or to get Ef for indirect geometry if (emodeStr == "Indirect") { if (efixedProp != EMPTY_DBL()) Efi = efixedProp; else try { IDetector_const_sptr det = inputWS->getDetector(i); if (!det->isMonitor()) { try { Parameter_sptr par = pmap.getRecursive(det.get(), "Efixed"); if (par) { Efi = par->value<double>(); g_log.debug() << "Detector: " << det->getID() << " EFixed: " << Efi << "\n"; } } catch (std::runtime_error &) { /* Throws if a DetectorGroup, use single provided value */ } } } catch (std::runtime_error &) { g_log.information() << "Workspace Index " << i << ": cannot find detector" << "\n"; } } if (emodeStr == "Indirect") efixed = Efi; else efixed = efixedProp; // Do the correction auto &evlist = outputWS->getSpectrum(i); switch (evlist.getEventType()) { case TOF: // Switch to weights if needed. evlist.switchTo(WEIGHTED); /* no break */ // Fall through case WEIGHTED: correctKiKfEventHelper(evlist.getWeightedEvents(), efixed, emodeStr); break; case WEIGHTED_NOTIME: correctKiKfEventHelper(evlist.getWeightedEventsNoTime(), efixed, emodeStr); break; } prog.report(); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION outputWS->clearMRU(); if (inputWS->getNumberEvents() != outputWS->getNumberEvents()) { g_log.information() << "Ef <= 0 or Ei <= 0 for " << inputWS->getNumberEvents() - outputWS->getNumberEvents() << " events, out of " << inputWS->getNumberEvents() << '\n'; if (efixedProp == EMPTY_DBL()) g_log.information() << "Try to set fixed energy\n"; } }
std::string LaneArea::getLaneID(const std::string& detID) { return getDetector(detID)->getLane()->getID(); }
double LaneArea::getPosition(const std::string& detID) { return getDetector(detID)->getStartPos(); }
/// Return a const reference to the detector with given index. const Geometry::IDetector &DetectorInfo::detector(const size_t index) const { return getDetector(index); }
double LaneArea::getLastStepMeanSpeed(const std::string& detID) { return getDetector(detID)->getCurrentMeanSpeed(); }
double LaneArea::getJamLengthMeters(const std::string& detID) { return getDetector(detID)->getCurrentJamLengthInMeters(); }
int LaneArea::getJamLengthVehicle(const std::string& detID) { return getDetector(detID)->getCurrentJamLengthInVehicles(); }
int LaneArea::getLastStepHaltingNumber(const std::string& detID) { return getDetector(detID)->getCurrentHaltingNumber(); }
int LaneArea::getLastStepVehicleNumber(const std::string& detID) { return getDetector(detID)->getCurrentVehicleNumber(); }
double LaneArea::getLength(const std::string& detID) { const MSE2Collector* const e2 = getDetector(detID); return e2->getLength(); }
std::vector<std::string> LaneArea::getLastStepVehicleIDs(const std::string& detID) { return getDetector(detID)->getCurrentVehicleIDs(); }
double LaneArea::getLastStepOccupancy(const std::string& detID) { return getDetector(detID)->getCurrentOccupancy(); }
/// Helper used by SpectrumInfo. boost::shared_ptr<const Geometry::IDetector> DetectorInfo::getDetectorPtr(const size_t index) const { size_t thread = static_cast<size_t>(PARALLEL_THREAD_NUMBER); static_cast<void>(getDetector(index)); return m_lastDetector[thread]; }
void ModeratorTzero::execEvent(const std::string &emode) { g_log.information("Processing event workspace"); const MatrixWorkspace_const_sptr matrixInputWS = getProperty("InputWorkspace"); // generate the output workspace pointer API::MatrixWorkspace_sptr matrixOutputWS = getProperty("OutputWorkspace"); if (matrixOutputWS != matrixInputWS) { matrixOutputWS = matrixInputWS->clone(); setProperty("OutputWorkspace", matrixOutputWS); } auto outputWS = boost::dynamic_pointer_cast<EventWorkspace>(matrixOutputWS); // Get pointers to sample and source IComponent_const_sptr source = m_instrument->getSource(); IComponent_const_sptr sample = m_instrument->getSample(); double Lss = source->getDistance(*sample); // distance from source to sample // calculate tof shift once for all neutrons if emode==Direct double t0_direct(-1); if (emode == "Direct") { Kernel::Property *eiprop = outputWS->run().getProperty("Ei"); double Ei = boost::lexical_cast<double>(eiprop->value()); mu::Parser parser; parser.DefineVar("incidentEnergy", &Ei); // associate E1 to this parser parser.SetExpr(m_formula); t0_direct = parser.Eval(); } // Loop over the spectra const size_t numHists = static_cast<size_t>(outputWS->getNumberHistograms()); Progress prog(this, 0.0, 1.0, numHists); // report progress of algorithm PARALLEL_FOR1(outputWS) for (int i = 0; i < static_cast<int>(numHists); ++i) { PARALLEL_START_INTERUPT_REGION size_t wsIndex = static_cast<size_t>(i); EventList &evlist = outputWS->getEventList(wsIndex); if (evlist.getNumberEvents() > 0) // don't bother with empty lists { IDetector_const_sptr det; double L1(Lss); // distance from source to sample double L2(-1); // distance from sample to detector try { det = outputWS->getDetector(i); if (det->isMonitor()) { // redefine the sample as the monitor L1 = source->getDistance(*det); L2 = 0; } else { L2 = sample->getDistance(*det); } } catch (Exception::NotFoundError &) { g_log.error() << "Unable to calculate distances to/from detector" << i << std::endl; } if (L2 >= 0) { // One parser for each parallel processor needed (except Edirect mode) double E1; mu::Parser parser; parser.DefineVar("incidentEnergy", &E1); // associate E1 to this parser parser.SetExpr(m_formula); // fast neutrons are shifted by min_t0_next, irrespective of tof double v1_max = L1 / m_t1min; E1 = m_convfactor * v1_max * v1_max; double min_t0_next = parser.Eval(); if (emode == "Indirect") { double t2(-1.0); // time from sample to detector. (-1) signals error if (det->isMonitor()) { t2 = 0.0; } else { static const double convFact = 1.0e-6 * sqrt(2 * PhysicalConstants::meV / PhysicalConstants::NeutronMass); std::vector<double> wsProp = det->getNumberParameter("Efixed"); if (!wsProp.empty()) { double E2 = wsProp.at(0); //[E2]=meV double v2 = convFact * sqrt(E2); //[v2]=meter/microsec t2 = L2 / v2; } else { // t2 is kept to -1 if no Efixed is found g_log.debug() << "Efixed not found for detector " << i << std::endl; } } if (t2 >= 0) // t2 < 0 when no detector info is available { // fix the histogram bins MantidVec &x = evlist.dataX(); for (double &tof : x) { if (tof < m_t1min + t2) tof -= min_t0_next; else tof -= CalculateT0indirect(tof, L1, t2, E1, parser); } MantidVec tofs = evlist.getTofs(); for (double &tof : tofs) { if (tof < m_t1min + t2) tof -= min_t0_next; else tof -= CalculateT0indirect(tof, L1, t2, E1, parser); } evlist.setTofs(tofs); evlist.setSortOrder(Mantid::DataObjects::EventSortType::UNSORTED); } // end of if( t2>= 0) } // end of if(emode=="Indirect") else if (emode == "Elastic") { // Apply t0 correction to histogram bins MantidVec &x = evlist.dataX(); for (double &tof : x) { if (tof < m_t1min * (L1 + L2) / L1) tof -= min_t0_next; else tof -= CalculateT0elastic(tof, L1 + L2, E1, parser); } MantidVec tofs = evlist.getTofs(); for (double &tof : tofs) { // add a [-0.1,0.1] microsecond noise to avoid artifacts // resulting from original tof data if (tof < m_t1min * (L1 + L2) / L1) tof -= min_t0_next; else tof -= CalculateT0elastic(tof, L1 + L2, E1, parser); } evlist.setTofs(tofs); evlist.setSortOrder(Mantid::DataObjects::EventSortType::UNSORTED); MantidVec tofs_b = evlist.getTofs(); MantidVec xarray = evlist.readX(); } // end of else if(emode=="Elastic") else if (emode == "Direct") { // fix the histogram bins MantidVec &x = evlist.dataX(); for (double &tof : x) { tof -= t0_direct; } MantidVec tofs = evlist.getTofs(); for (double &tof : tofs) { tof -= t0_direct; } evlist.setTofs(tofs); evlist.setSortOrder(Mantid::DataObjects::EventSortType::UNSORTED); } // end of else if(emode=="Direct") } // end of if(L2 >= 0) } // end of if (evlist.getNumberEvents() > 0) prog.report(); PARALLEL_END_INTERUPT_REGION } // end of for (int i = 0; i < static_cast<int>(numHists); ++i) PARALLEL_CHECK_INTERUPT_REGION outputWS->clearMRU(); // Clears the Most Recent Used lists */ } // end of void ModeratorTzero::execEvent()