/** Method calculates averaged polar coordinates of the detector's group (which may consist of one detector) *@param spDet -- shared pointer to the Mantid Detector *@param Observer -- sample position or the centre of the polar system of coordinates to calculate detector's parameters. *@param Detector -- return Detector class containing averaged polar coordinates of the detector or detector's group in spherical coordinate system with centre at Observer */ void FindDetectorsPar::calcDetPar(const Geometry::IDetector_const_sptr &spDet, const Kernel::V3D &Observer, DetParameters &Detector) { // get number of basic detectors within the composit detector size_t nDetectors = spDet->nDets(); // define summator AvrgDetector detSum; // do we want spherical or linear box sizes? detSum.setUseSpherical(!m_SizesAreLinear); if (nDetectors == 1) { detSum.addDetInfo(spDet, Observer); } else { // access contributing detectors; Geometry::DetectorGroup_const_sptr spDetGroup = boost::dynamic_pointer_cast<const Geometry::DetectorGroup>(spDet); if (!spDetGroup) { g_log.error() << "calc_cylDetPar: can not downcast IDetector_sptr to " "detector group for det->ID: " << spDet->getID() << std::endl; throw(std::bad_cast()); } auto detectors = spDetGroup->getDetectors(); auto it = detectors.begin(); auto it_end = detectors.end(); for (; it != it_end; it++) { detSum.addDetInfo(*it, Observer); } } // calculate averages and return the detector parameters detSum.returnAvrgDetPar(Detector); }
int LoadIsawPeaks::findPixelID(Instrument_const_sptr inst, std::string bankName, int col, int row) { boost::shared_ptr<const IComponent> parent = inst->getComponentByName(bankName); if (parent->type().compare("RectangularDetector") == 0) { boost::shared_ptr<const RectangularDetector> RDet = boost::dynamic_pointer_cast< const RectangularDetector>(parent); boost::shared_ptr<Detector> pixel = RDet->getAtXY(col, row); return pixel->getID(); } else { std::vector<Geometry::IComponent_const_sptr> children; boost::shared_ptr<const Geometry::ICompAssembly> asmb = boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(parent); asmb->getChildren(children, false); int col0 = (col%2==0 ? col/2+75 : (col-1)/2); boost::shared_ptr<const Geometry::ICompAssembly> asmb2 = boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(children[col0]); std::vector<Geometry::IComponent_const_sptr> grandchildren; asmb2->getChildren(grandchildren,false); Geometry::IComponent_const_sptr first = grandchildren[row-1]; Geometry::IDetector_const_sptr det = boost::dynamic_pointer_cast<const Geometry::IDetector>(first); return det->getID(); } }
/** Purpose: Process mask workspace * Requirement: m_maskWS is not None * Guarantees: an array will be set up for masked detectors * @brief IntegratePeaksCWSD::processMaskWorkspace * @param maskws */ std::vector<detid_t> IntegratePeaksCWSD::processMaskWorkspace( DataObjects::MaskWorkspace_const_sptr maskws) { std::vector<detid_t> vecMaskedDetID; // Add the detector IDs of all masked detector to a vector size_t numspec = maskws->getNumberHistograms(); for (size_t iws = 0; iws < numspec; ++iws) { Geometry::IDetector_const_sptr detector = maskws->getDetector(iws); const MantidVec &vecY = maskws->readY(iws); if (vecY[0] > 0.1) { // vecY[] > 0 is masked. det->isMasked() may not be reliable. detid_t detid = detector->getID(); vecMaskedDetID.push_back(detid); } } // Sort the vector for future lookup if (vecMaskedDetID.size() > 1) std::sort(vecMaskedDetID.begin(), vecMaskedDetID.end()); g_log.warning() << "[DB] There are " << vecMaskedDetID.size() << " detectors masked." << "\n"; return vecMaskedDetID; }
/** Extract a component's detectors and return it within detectors array * It is a generalized version of bankToDetectors() * * @param componentnames -- vector of component names to process * @param detectors -- vector of detector ids, which belongs to components *provided as input. */ void LoadMask::componentToDetectors( const std::vector<std::string> &componentnames, std::vector<detid_t> &detectors) { Geometry::Instrument_const_sptr minstrument = m_maskWS->getInstrument(); for (auto &componentname : componentnames) { g_log.debug() << "Component name = " << componentname << '\n'; // a) get component Geometry::IComponent_const_sptr component = minstrument->getComponentByName(componentname); if (component) g_log.debug() << "Component ID = " << component->getComponentID() << '\n'; else { // A non-exiting component. Ignore g_log.warning() << "Component " << componentname << " does not exist!\n"; continue; } // b) component -> component assembly --> children (more than detectors) boost::shared_ptr<const Geometry::ICompAssembly> asmb = boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(component); std::vector<Geometry::IComponent_const_sptr> children; asmb->getChildren(children, true); g_log.debug() << "Number of Children = " << children.size() << '\n'; size_t numdets(0); detid_t id_min(std::numeric_limits<Mantid::detid_t>::max()); detid_t id_max(0); for (const auto &child : children) { // c) convert component to detector Geometry::IDetector_const_sptr det = boost::dynamic_pointer_cast<const Geometry::IDetector>(child); if (det) { detid_t detid = det->getID(); detectors.push_back(detid); numdets++; if (detid < id_min) id_min = detid; if (detid > id_max) id_max = detid; } } g_log.debug() << "Number of Detectors in Children = " << numdets << " Range = " << id_min << ", " << id_max << '\n'; } // for component }
/// helper function to preprocess the detectors directions void ConvertToQ3DdE::process_detectors_positions(const DataObjects::Workspace2D_const_sptr inputWS) { const size_t nHist = inputWS->getNumberHistograms(); det_loc.det_dir.resize(nHist); det_loc.det_id.resize(nHist); // Loop over the spectra size_t ic(0); 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 dealing with monitor... if (spDet->isMonitor())continue; det_loc.det_id[ic] = spDet->getID(); // dist = spDet->getDistance(*sample); double polar = inputWS->detectorTwoTheta(spDet); double azim = spDet->getPhi(); double sPhi=sin(polar); double ez = cos(polar); double ex = sPhi*cos(azim); double ey = sPhi*sin(azim); det_loc.det_dir[ic].setX(ex); det_loc.det_dir[ic].setY(ey); det_loc.det_dir[ic].setZ(ez); ic++; } // if(ic<nHist){ det_loc.det_dir.resize(ic); det_loc.det_id.resize(ic); } }
std::pair<double, double> LoadILLSANS::calculateQMaxQMin() { double min = std::numeric_limits<double>::max(), max = std::numeric_limits<double>::min(); g_log.debug("Calculating Qmin Qmax..."); std::size_t nHist = m_localWorkspace->getNumberHistograms(); for (std::size_t i = 0; i < nHist; ++i) { Geometry::IDetector_const_sptr det = m_localWorkspace->getDetector(i); if (!det->isMonitor()) { const MantidVec &lambdaBinning = m_localWorkspace->readX(i); Kernel::V3D detPos = det->getPos(); double r, theta, phi; detPos.getSpherical(r, theta, phi); double v1 = calculateQ(*(lambdaBinning.begin()), theta); double v2 = calculateQ(*(lambdaBinning.end() - 1), theta); // std::cout << "i=" << i << " theta="<<theta << " lambda_i=" << // *(lambdaBinning.begin()) << " lambda_f=" << *(lambdaBinning.end()-1) << // " v1=" << v1 << " v2=" << v2 << '\n'; if (i == 0) { min = v1; max = v1; } if (v1 < min) { min = v1; } if (v2 < min) { min = v2; } if (v1 > max) { max = v1; } if (v2 > max) { max = v2; } } else g_log.debug() << "Detector " << i << " is a Monitor : " << det->getID() << '\n'; } g_log.debug() << "Calculating Qmin Qmax. Done : [" << min << "," << max << "]\n"; return std::pair<double, double>(min, max); }
/* * Convert Componenet -> Detector IDs -> Workspace Indices -> set group ID */ void LoadDetectorsGroupingFile::setByComponents() { // 0. Check if (!m_instrument) { std::map<int, std::vector<std::string>>::iterator mapiter; bool norecord = true; for (mapiter = m_groupComponentsMap.begin(); mapiter != m_groupComponentsMap.end(); ++mapiter) { if (mapiter->second.size() > 0) { g_log.error() << "Instrument is not specified in XML file. " << "But tag 'component' is used in XML file for Group " << mapiter->first << " It is not allowed" << std::endl; norecord = false; break; } } if (!norecord) throw std::invalid_argument( "XML definition involving component causes error"); } // 1. Prepare const detid2index_map indexmap = m_groupWS->getDetectorIDToWorkspaceIndexMap(true); // 2. Set for (auto &componentMap : m_groupComponentsMap) { g_log.debug() << "Group ID = " << componentMap.first << " With " << componentMap.second.size() << " Components" << std::endl; for (auto &name : componentMap.second) { // a) get component Geometry::IComponent_const_sptr component = m_instrument->getComponentByName(name); // b) component -> component assembly --> children (more than detectors) boost::shared_ptr<const Geometry::ICompAssembly> asmb = boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(component); std::vector<Geometry::IComponent_const_sptr> children; asmb->getChildren(children, true); g_log.debug() << "Component Name = " << name << " Component ID = " << component->getComponentID() << "Number of Children = " << children.size() << std::endl; for (auto child : children) { // c) convert component to detector Geometry::IDetector_const_sptr det = boost::dynamic_pointer_cast<const Geometry::IDetector>(child); if (det) { // Component is DETECTOR: int32_t detid = det->getID(); auto itx = indexmap.find(detid); if (itx != indexmap.end()) { size_t wsindex = itx->second; m_groupWS->dataY(wsindex)[0] = componentMap.first; } else { g_log.error() << "Pixel w/ ID = " << detid << " Cannot Be Located" << std::endl; } } // ENDIF Detector } // ENDFOR (children of component) } // ENDFOR (component) } // ENDFOR GroupID return; }
/** 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"; }