/** Retrieves the detector postion for a given spectrum * @param index :: The workspace index of the spectrum * @param l1 :: Returns the source-sample distance * @param l2 :: Returns the sample-detector distance * @param twoTheta :: Returns the detector's scattering angle */ void RemoveBins::calculateDetectorPosition(const int& index, double& l1, double& l2, double& twoTheta) { // Get a pointer to the instrument contained in the workspace Geometry::Instrument_const_sptr instrument = m_inputWorkspace->getInstrument(); // Get the distance between the source and the sample (assume in metres) Geometry::IObjComponent_const_sptr sample = instrument->getSample(); // Check for valid instrument if (sample == NULL) { throw Exception::InstrumentDefinitionError("Instrument not sufficiently defined: failed to get sample"); } l1 = instrument->getSource()->getDistance(*sample); Geometry::IDetector_const_sptr det = m_inputWorkspace->getDetector(index); // Get the sample-detector distance for this detector (in metres) if ( ! det->isMonitor() ) { l2 = det->getDistance(*sample); // The scattering angle for this detector (in radians). twoTheta = m_inputWorkspace->detectorTwoTheta(det); } else // If this is a monitor then make l1+l2 = source-detector distance and twoTheta=0 { l2 = det->getDistance(*(instrument->getSource())); l2 = l2 - l1; twoTheta = 0.0; } g_log.debug() << "Detector for index " << index << " has L1+L2=" << l1+l2 << " & 2theta= " << twoTheta << std::endl; return; }
/** Calculates the total flightpath for the given detector. * This is L1+L2 normally, but is the source-detector distance for a monitor. * @param spectrum :: The workspace index * @param L1 :: The primary flightpath * @param isMonitor :: Output: true is this detector is a monitor * @return The flightpath (Ld) for the detector linked to spectrum * @throw Kernel::Exception::InstrumentDefinitionError if the detector position * can't be obtained */ double UnwrapMonitor::calculateFlightpath(const int &spectrum, const double &L1, bool &isMonitor) const { double Ld = -1.0; try { // Get the detector object for this histogram Geometry::IDetector_const_sptr det = m_inputWS->getDetector(spectrum); // Get the sample-detector distance for this detector (or source-detector if // a monitor) // This is the total flightpath isMonitor = det->isMonitor(); // Get the L2 distance if this detector is not a monitor if (!isMonitor) { double L2 = det->getDistance(*(m_inputWS->getInstrument()->getSample())); Ld = L1 + L2; } // If it is a monitor, then the flightpath is the distance to the source else { Ld = det->getDistance(*(m_inputWS->getInstrument()->getSource())); } } catch (Exception::NotFoundError &) { // If the detector information is missing, return a negative number } return Ld; }
void FindDetectorsPar::populate_values_from_file( const API::MatrixWorkspace_sptr &inputWS) { size_t nHist = inputWS->getNumberHistograms(); if (this->current_ASCII_file.Type == PAR_type) { // in this case data in azimuthal width and polar width are in fact real // sizes in meters; have to transform it in into angular values for (size_t i = 0; i < nHist; i++) { azimuthalWidth[i] = atan2(azimuthalWidth[i], secondaryFlightpath[i]) * rad2deg; polarWidth[i] = atan2(polarWidth[i], secondaryFlightpath[i]) * rad2deg; } m_SizesAreLinear = false; } else { Geometry::IComponent_const_sptr sample = inputWS->getInstrument()->getSample(); secondaryFlightpath.resize(nHist); // Loop over the spectra for (size_t i = 0; i < nHist; i++) { Geometry::IDetector_const_sptr spDet; try { spDet = inputWS->getDetector(i); } catch (Kernel::Exception::NotFoundError &) { continue; } // Check that we aren't writing a monitor... if (spDet->isMonitor()) continue; /// this is the only value, which is not defined in phx file, so we /// calculate it secondaryFlightpath[i] = spDet->getDistance(*sample); } } }
/** method does preliminary calculations of the detectors positions to convert results into k-dE space ; and places the results into static cash to be used in subsequent calls to this algorithm */ void PreprocessDetectorsToMD::processDetectorsPositions( const API::MatrixWorkspace_const_sptr &inputWS, DataObjects::TableWorkspace_sptr &targWS) { g_log.information() << "Preprocessing detector locations in a target reciprocal space\n"; // Geometry::Instrument_const_sptr instrument = inputWS->getInstrument(); // this->pBaseInstr = instrument->baseInstrument(); // Geometry::IComponent_const_sptr source = instrument->getSource(); Geometry::IComponent_const_sptr sample = instrument->getSample(); if ((!source) || (!sample)) { g_log.error() << " Instrument is not fully defined. Can not identify " "source or sample\n"; throw Kernel::Exception::InstrumentDefinitionError( "Instrument not sufficiently defined: failed to get source and/or " "sample"); } // L1 try { double L1 = source->getDistance(*sample); targWS->logs()->addProperty<double>("L1", L1, true); g_log.debug() << "Source-sample distance: " << L1 << std::endl; } catch (Kernel::Exception::NotFoundError &) { throw Kernel::Exception::InstrumentDefinitionError( "Unable to calculate source-sample distance for workspace", inputWS->getTitle()); } // Instrument name std::string InstrName = instrument->getName(); targWS->logs()->addProperty<std::string>( "InstrumentName", InstrName, true); // "The name which should unique identify current instrument"); targWS->logs()->addProperty<bool>("FakeDetectors", false, true); // get access to the workspace memory auto &sp2detMap = targWS->getColVector<size_t>("spec2detMap"); auto &detId = targWS->getColVector<int32_t>("DetectorID"); auto &detIDMap = targWS->getColVector<size_t>("detIDMap"); auto &L2 = targWS->getColVector<double>("L2"); auto &TwoTheta = targWS->getColVector<double>("TwoTheta"); auto &Azimuthal = targWS->getColVector<double>("Azimuthal"); auto &detDir = targWS->getColVector<Kernel::V3D>("DetDirections"); // Efixed; do we need one and does one exist? double Efi = targWS->getLogs()->getPropertyValueAsType<double>("Ei"); float *pEfixedArray(nullptr); const Geometry::ParameterMap &pmap = inputWS->constInstrumentParameters(); if (m_getEFixed) pEfixedArray = targWS->getColDataArray<float>("eFixed"); // check if one needs to generate masked detectors column. int *pMasksArray(nullptr); if (m_getIsMasked) pMasksArray = targWS->getColDataArray<int>("detMask"); //// progress message appearance size_t div = 100; size_t nHist = targWS->rowCount(); Mantid::API::Progress theProgress(this, 0, 1, nHist); //// Loop over the spectra uint32_t liveDetectorsCount(0); for (size_t i = 0; i < nHist; i++) { sp2detMap[i] = std::numeric_limits<uint64_t>::quiet_NaN(); detId[i] = std::numeric_limits<int32_t>::quiet_NaN(); detIDMap[i] = std::numeric_limits<uint64_t>::quiet_NaN(); L2[i] = std::numeric_limits<double>::quiet_NaN(); TwoTheta[i] = std::numeric_limits<double>::quiet_NaN(); Azimuthal[i] = std::numeric_limits<double>::quiet_NaN(); // detMask[i] = true; // get detector or detector group which corresponds to the spectra i Geometry::IDetector_const_sptr spDet; try { spDet = inputWS->getDetector(i); } catch (Kernel::Exception::NotFoundError &) { continue; } // Check that we aren't dealing with monitor... if (spDet->isMonitor()) continue; // if masked detectors state is not used, masked detectors just ignored; bool maskDetector = spDet->isMasked(); if (m_getIsMasked) *(pMasksArray + liveDetectorsCount) = maskDetector ? 1 : 0; else if (maskDetector) continue; // calculate the requested values; sp2detMap[i] = liveDetectorsCount; detId[liveDetectorsCount] = int32_t(spDet->getID()); detIDMap[liveDetectorsCount] = i; L2[liveDetectorsCount] = spDet->getDistance(*sample); double polar = inputWS->detectorTwoTheta(spDet); double azim = spDet->getPhi(); TwoTheta[liveDetectorsCount] = polar; Azimuthal[liveDetectorsCount] = azim; double sPhi = sin(polar); double ez = cos(polar); double ex = sPhi * cos(azim); double ey = sPhi * sin(azim); detDir[liveDetectorsCount].setX(ex); detDir[liveDetectorsCount].setY(ey); detDir[liveDetectorsCount].setZ(ez); // double sinTheta=sin(0.5*polar); // this->SinThetaSq[liveDetectorsCount] = sinTheta*sinTheta; // specific code which should work and makes sense // for indirect instrument but may be deployed on any code with Ei property // defined; if (pEfixedArray) { try { Geometry::Parameter_sptr par = pmap.getRecursive(spDet.get(), "eFixed"); if (par) Efi = par->value<double>(); } catch (std::runtime_error &) { } // set efixed for each existing detector *(pEfixedArray + liveDetectorsCount) = static_cast<float>(Efi); } liveDetectorsCount++; if (i % div == 0) theProgress.report(i, "Preprocessing detectors"); } targWS->logs()->addProperty<uint32_t>("ActualDetectorsNum", liveDetectorsCount, true); theProgress.report(); g_log.information() << "Finished preprocessing detector locations. Found: " << liveDetectorsCount << " detectors out of: " << nHist << " histograms\n"; }