int MaskPeaksWorkspace::findPixelID(std::string bankName, int col, int row) { Geometry::Instrument_const_sptr Iptr = m_inputW->getInstrument(); boost::shared_ptr<const IComponent> parent = Iptr->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::string bankName0 = bankName; // Only works for WISH bankName0.erase(0, 4); std::ostringstream pixelString; pixelString << Iptr->getName() << "/" << bankName0 << "/" << bankName << "/tube" << std::setw(3) << std::setfill('0') << col << "/pixel" << std::setw(4) << std::setfill('0') << row; boost::shared_ptr<const Geometry::IComponent> component = Iptr->getComponentByName(pixelString.str()); boost::shared_ptr<const Detector> pixel = boost::dynamic_pointer_cast<const Detector>(component); return pixel->getID(); } }
Peak PeakHKLErrors::createNewPeak(const Geometry::IPeak &peak_old, Geometry::Instrument_sptr instrNew, double T0, double L0) { Geometry::Instrument_const_sptr inst = peak_old.getInstrument(); if (inst->getComponentID() != instrNew->getComponentID()) { g_log.error("All peaks must have the same instrument"); throw std::invalid_argument("All peaks must have the same instrument"); } double T = peak_old.getTOF() + T0; int ID = peak_old.getDetectorID(); Kernel::V3D hkl = peak_old.getHKL(); // peak_old.setDetectorID(ID); //set det positions Peak peak(instrNew, ID, peak_old.getWavelength(), hkl, peak_old.getGoniometerMatrix()); Wavelength wl; wl.initialize(L0, peak.getL2(), peak.getScattering(), 0, peak_old.getInitialEnergy(), 0.0); peak.setWavelength(wl.singleFromTOF(T)); peak.setIntensity(peak_old.getIntensity()); peak.setSigmaIntensity(peak_old.getSigmaIntensity()); peak.setRunNumber(peak_old.getRunNumber()); peak.setBinCount(peak_old.getBinCount()); //!!!peak.setDetectorID(ID); return peak; }
/** * Apply any instrument adjustments from the file * @param filename :: The file to take the positions */ void CreateSimulationWorkspace::adjustInstrument(const std::string &filename) { // If requested update the instrument to positions in the raw file const Geometry::ParameterMap &pmap = m_outputWS->instrumentParameters(); Geometry::Instrument_const_sptr instrument = m_outputWS->getInstrument(); boost::shared_ptr<Geometry::Parameter> updateDets = pmap.get(instrument->getComponentID(), "det-pos-source"); if (!updateDets) return; // No tag, use IDF std::string value = updateDets->value<std::string>(); if (value.substr(0, 8) == "datafile") { IAlgorithm_sptr updateInst = createChildAlgorithm("UpdateInstrumentFromFile", 0.75, 1.0); updateInst->setProperty<MatrixWorkspace_sptr>("Workspace", m_outputWS); updateInst->setPropertyValue("Filename", filename); if (value == "datafile-ignore-phi") { updateInst->setProperty("IgnorePhi", true); g_log.information("Detector positions in IDF updated with positions in " "the data file except for the phi values"); } else { g_log.information( "Detector positions in IDF updated with positions in the data file"); } // We want this to throw if it fails to warn the user that the information // is not correct. updateInst->execute(); } }
/** * Get position in space of a componentName */ V3D LoadILLSANS::getComponentPosition(const std::string &componentName) { Geometry::Instrument_const_sptr instrument = m_localWorkspace->getInstrument(); Geometry::IComponent_const_sptr component = instrument->getComponentByName(componentName); return component->getPos(); }
void LoadILLIndirect::moveComponent(const std::string &componentName, double twoTheta, double offSet) { try { Geometry::Instrument_const_sptr instrument = m_localWorkspace->getInstrument(); Geometry::IComponent_const_sptr component = instrument->getComponentByName(componentName); double r, theta, phi, newTheta, newR; V3D oldPos = component->getPos(); oldPos.getSpherical(r, theta, phi); newTheta = twoTheta; newR = offSet; V3D newPos; newPos.spherical(newR, newTheta, phi); // g_log.debug() << tube->getName() << " : t = " << theta << " ==> t = " << // newTheta << "\n"; Geometry::ParameterMap &pmap = m_localWorkspace->instrumentParameters(); Geometry::ComponentHelper::moveComponent( *component, pmap, newPos, Geometry::ComponentHelper::Absolute); } catch (Mantid::Kernel::Exception::NotFoundError &) { throw std::runtime_error("Error when trying to move the " + componentName + " : NotFoundError"); } catch (std::runtime_error &) { throw std::runtime_error("Error when trying to move the " + componentName + " : runtime_error"); } }
/** Convert bank to detectors * This routine has never been used. Dead code. * @param singlebanks -- vector of string containing bank names * @param detectors -- vector of detector-id-s belonging to these banks */ void LoadMask::bankToDetectors(const std::vector<std::string> &singlebanks, std::vector<detid_t> &detectors) { std::stringstream infoss; infoss << "Bank IDs to be converted to detectors: \n"; for (auto &singlebank : singlebanks) { infoss << "Bank: " << singlebank << '\n'; } g_log.debug(infoss.str()); Geometry::Instrument_const_sptr minstrument = m_maskWS->getInstrument(); for (auto &singlebank : singlebanks) { std::vector<Geometry::IDetector_const_sptr> idetectors; minstrument->getDetectorsInBank(idetectors, singlebank); g_log.debug() << "Bank: " << singlebank << " has " << idetectors.size() << " detectors\n"; // a) get information size_t numdets = idetectors.size(); detid_t detid_first = idetectors.front()->getID(); detid_t detid_last = idetectors.back()->getID(); // b) set detectors for (const auto &det : idetectors) { detid_t detid = det->getID(); detectors.push_back(detid); } g_log.debug() << "Number of Detectors in Bank " << singlebank << " is: " << numdets << "\nRange From: " << detid_first << " To: " << detid_last << '\n'; } // ENDFOR }
bool CentroidPeaks::edgePixel(std::string bankName, int col, int row, int Edge) { if (bankName.compare("None") == 0) return false; Geometry::Instrument_const_sptr Iptr = inWS->getInstrument(); boost::shared_ptr<const IComponent> parent = Iptr->getComponentByName(bankName); if (parent->type().compare("RectangularDetector") == 0) { boost::shared_ptr<const RectangularDetector> RDet = boost::dynamic_pointer_cast<const RectangularDetector>(parent); return col < Edge || col >= (RDet->xpixels() - Edge) || row < Edge || row >= (RDet->ypixels() - Edge); } 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); boost::shared_ptr<const Geometry::ICompAssembly> asmb2 = boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(children[0]); std::vector<Geometry::IComponent_const_sptr> grandchildren; asmb2->getChildren(grandchildren, false); int NROWS = static_cast<int>(grandchildren.size()); int NCOLS = static_cast<int>(children.size()); // Wish pixels and tubes start at 1 not 0 return col - 1 < Edge || col - 1 >= (NCOLS - Edge) || row - 1 < Edge || row - 1 >= (NROWS - Edge); } return false; }
double LoadHelper::getL1(const API::MatrixWorkspace_sptr& workspace) { Geometry::Instrument_const_sptr instrument = workspace->getInstrument(); Geometry::IComponent_const_sptr sample = instrument->getSample(); double l1 = instrument->getSource()->getDistance(*sample); return l1; }
/** 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; }
/** This function will check how to group spectra when calculating median * * */ std::vector<std::vector<size_t> > DetectorDiagnostic::makeMap(API::MatrixWorkspace_sptr countsWS) { std::multimap<Mantid::Geometry::ComponentID,size_t> mymap; Geometry::Instrument_const_sptr instrument = countsWS->getInstrument(); if (m_parents==0) { return makeInstrumentMap(countsWS); } if (!instrument) { g_log.warning("Workspace has no instrument. LevelsUP is ignored"); return makeInstrumentMap(countsWS); } //check if not grouped. If grouped, it will throw if ( countsWS->hasGroupedDetectors() ) { throw std::runtime_error("Median detector test: not able to create detector to spectra map. Try with LevelUp=0."); } for(size_t i=0;i < countsWS->getNumberHistograms();i++) { detid_t d=(*((countsWS->getSpectrum(i))->getDetectorIDs().begin())); std::vector<boost::shared_ptr<const Mantid::Geometry::IComponent> > anc=instrument->getDetector(d)->getAncestors(); //std::vector<boost::shared_ptr<const IComponent> > anc=(*(countsWS->getSpectrum(i)->getDetectorIDs().begin()))->getAncestors(); if (anc.size()<static_cast<size_t>(m_parents)) { g_log.warning("Too many levels up. Will ignore LevelsUp"); m_parents=0; return makeInstrumentMap(countsWS); } mymap.insert(std::pair<Mantid::Geometry::ComponentID,size_t>(anc[m_parents-1]->getComponentID(),i)); } std::vector<std::vector<size_t> > speclist; std::vector<size_t> speclistsingle; std::multimap<Mantid::Geometry::ComponentID,size_t>::iterator m_it, s_it; for (m_it = mymap.begin(); m_it != mymap.end(); m_it = s_it) { Mantid::Geometry::ComponentID theKey = (*m_it).first; std::pair<std::multimap<Mantid::Geometry::ComponentID,size_t>::iterator,std::multimap<Mantid::Geometry::ComponentID,size_t>::iterator> keyRange = mymap.equal_range(theKey); // Iterate over all map elements with key == theKey speclistsingle.clear(); for (s_it = keyRange.first; s_it != keyRange.second; ++s_it) { speclistsingle.push_back( (*s_it).second ); } speclist.push_back(speclistsingle); } return speclist; }
// read the monitors list from the workspace and try to do it once for any // particular ws; bool MonIDPropChanger::monitorIdReader( API::MatrixWorkspace_const_sptr inputWS) const { // no workspace if (!inputWS) return false; // no instrument Geometry::Instrument_const_sptr pInstr = inputWS->getInstrument(); if (!pInstr) return false; std::vector<detid_t> mon = pInstr->getMonitors(); if (mon.empty()) { if (iExistingAllowedValues.empty()) { return false; } else { iExistingAllowedValues.clear(); return true; } } // are these monitors really there? // got the index of correspondent spectra. std::vector<size_t> indexList = inputWS->getIndicesFromDetectorIDs(mon); if (indexList.empty()) { if (iExistingAllowedValues.empty()) { return false; } else { iExistingAllowedValues.clear(); return true; } } // index list can be less or equal to the mon list size (some monitors do not // have spectra) size_t mon_count = (mon.size() < indexList.size()) ? mon.size() : indexList.size(); std::vector<int> allowed_values(mon_count); for (size_t i = 0; i < mon_count; i++) { allowed_values[i] = mon[i]; } // are known values the same as the values we have just identified? if (iExistingAllowedValues.size() != mon_count) { iExistingAllowedValues.clear(); iExistingAllowedValues.assign(allowed_values.begin(), allowed_values.end()); return true; } // the monitor list has the same size as before. Is it equivalent to the // existing one? bool values_redefined = false; for (size_t i = 0; i < mon_count; i++) { if (iExistingAllowedValues[i] != allowed_values[i]) { values_redefined = true; iExistingAllowedValues[i] = allowed_values[i]; } } return values_redefined; }
double LoadHelper::getL2(const API::MatrixWorkspace_sptr& workspace, int detId) { // Get a pointer to the instrument contained in the workspace Geometry::Instrument_const_sptr instrument = workspace->getInstrument(); // Get the distance between the source and the sample (assume in metres) Geometry::IComponent_const_sptr sample = instrument->getSample(); // Get the sample-detector distance for this detector (in metres) double l2 = workspace->getDetector(detId)->getPos().distance(sample->getPos()); return l2; }
// read the monitors list from the workspace and try to do it once for any // particular ws; bool MonIDPropChanger::monitorIdReader( MatrixWorkspace_const_sptr inputWS) const { // no workspace if (!inputWS) return false; // no instrument Geometry::Instrument_const_sptr pInstr = inputWS->getInstrument(); if (!pInstr) return false; // are these monitors really there? std::vector<detid_t> monitorIDList = pInstr->getMonitors(); { const auto &specInfo = inputWS->spectrumInfo(); std::set<detid_t> idsInWorkspace; size_t i = 0; // Loop over spectra, but finish early if we find everything while (i < specInfo.size() && idsInWorkspace.size() < monitorIDList.size()) { if (specInfo.isMonitor(i)) idsInWorkspace.insert(specInfo.detector(i).getID()); ++i; } monitorIDList = std::vector<detid_t>(idsInWorkspace.begin(), idsInWorkspace.end()); } if (monitorIDList.empty()) { if (iExistingAllowedValues.empty()) { return false; } else { iExistingAllowedValues.clear(); return true; } } // are known values the same as the values we have just identified? if (iExistingAllowedValues.size() != monitorIDList.size()) { iExistingAllowedValues.clear(); iExistingAllowedValues.assign(monitorIDList.begin(), monitorIDList.end()); return true; } // the monitor list has the same size as before. Is it equivalent to the // existing one? bool values_redefined = false; for (size_t i = 0; i < monitorIDList.size(); i++) { if (iExistingAllowedValues[i] != monitorIDList[i]) { values_redefined = true; iExistingAllowedValues[i] = monitorIDList[i]; } } return values_redefined; }
/** * Setup a detector cache for randomly picking IDs from the first * instrument in the ExperimentInfo list. * @param ws :: The input workspace */ void FakeMDEventData::setupDetectorCache(const API::IMDEventWorkspace &ws) { try { Geometry::Instrument_const_sptr inst = ws.getExperimentInfo(0)->getInstrument(); m_detIDs = inst->getDetectorIDs(true); // true=skip monitors size_t max = m_detIDs.size() - 1; m_uniformDist = boost::uniform_int<size_t>(0, max); // Includes max } catch (std::invalid_argument &) { g_log.information("Cannot retrieve instrument from input workspace, " "detector information will be garbage."); } }
V3D LoadHelper::getComponentPosition(API::MatrixWorkspace_sptr ws, const std::string &componentName) { try { Geometry::Instrument_const_sptr instrument = ws->getInstrument(); Geometry::IComponent_const_sptr component = instrument->getComponentByName(componentName); V3D pos = component->getPos(); return pos; } catch (Mantid::Kernel::Exception::NotFoundError&) { throw std::runtime_error("Error when trying to move the " + componentName + " : NotFoundError"); } }
/** 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 }
/** * Mask the outlier values to get a better median value. * @param medianvec The median value calculated from the current counts. * @param countsWS The counts workspace. Any outliers will be masked here. * @param indexmap Index map. * @returns The number failed. */ int MedianDetectorTest::maskOutliers(const std::vector<double> medianvec, API::MatrixWorkspace_sptr countsWS,std::vector<std::vector<size_t> > indexmap) { // Fractions of the median const double out_lo = getProperty("LowOutlier"); const double out_hi = getProperty("HighOutlier"); int numFailed(0); bool checkForMask = false; Geometry::Instrument_const_sptr instrument = countsWS->getInstrument(); if (instrument != NULL) { checkForMask = ((instrument->getSource() != NULL) && (instrument->getSample() != NULL)); } for (size_t i=0; i<indexmap.size(); ++i) { std::vector<size_t> hists=indexmap.at(i); double median=medianvec.at(i); PARALLEL_FOR1(countsWS) for(int j = 0; j < static_cast<int>(hists.size()); ++j) { const double value = countsWS->readY(hists.at(j))[0]; if ((value == 0.) && checkForMask) { const std::set<detid_t>& detids = countsWS->getSpectrum(hists.at(j))->getDetectorIDs(); if (instrument->isDetectorMasked(detids)) { numFailed -= 1; // it was already masked } } if( (value < out_lo*median) && (value > 0.0) ) { countsWS->maskWorkspaceIndex(hists.at(j)); PARALLEL_ATOMIC ++numFailed; } else if( value > out_hi*median ) { countsWS->maskWorkspaceIndex(hists.at(j)); PARALLEL_ATOMIC ++numFailed; } } PARALLEL_CHECK_INTERUPT_REGION } return numFailed; }
/** * Creates a new parameterized instrument for which the parameter values can be changed * * @param Peaks - a PeaksWorkspace used to get the original instrument. The instrument from the 0th peak is * the one that is used. * * NOTE: All the peaks in the PeaksWorkspace must use the same instrument. */ boost::shared_ptr<Geometry::Instrument> PeakHKLErrors::getNewInstrument( PeaksWorkspace_sptr Peaks )const { Geometry::Instrument_const_sptr instSave = Peaks->getPeak( 0 ).getInstrument(); boost::shared_ptr<Geometry::ParameterMap> pmap( new Geometry::ParameterMap() ); boost::shared_ptr<const Geometry::ParameterMap> pmapSv = instSave->getParameterMap(); if ( !instSave ) { g_log.error( " Peaks workspace does not have an instrument" ); throw std::invalid_argument( " Not all peaks have an instrument" ); } boost::shared_ptr<Geometry::Instrument> instChange( new Geometry::Instrument() ); if ( !instSave->isParametrized() ) { boost::shared_ptr<Geometry::Instrument> instClone( instSave->clone() ); boost::shared_ptr<Geometry::Instrument> Pinsta( new Geometry::Instrument( instSave, pmap ) ); instChange = Pinsta; } else //catch(... ) { boost::shared_ptr<Geometry::Instrument> P1( new Geometry::Instrument( instSave->baseInstrument(), pmap ) ); instChange = P1; } if ( !instChange ) { g_log.error( "Cannot 'clone' instrument" ); throw std::logic_error( "Cannot clone instrument" ); } //------------------"clone" orig instruments pmap ------------------- cLone( pmap, instSave, pmapSv ); IComponent_const_sptr sample = instChange->getSample(); V3D sampPos = sample->getRelativePos(); V3D sampOffsets( getParameter( "SampleXOffset" ), getParameter( "SampleYOffset" ), getParameter( "SampleZOffset" ) ); pmap->addPositionCoordinate( sample.get(), std::string("x"), sampPos.X() + sampOffsets.X() ); pmap->addPositionCoordinate( sample.get(), std::string("y"), sampPos.Y() + sampOffsets.Y() ); pmap->addPositionCoordinate( sample.get(), std::string("z"), sampPos.Z() + sampOffsets.Z() ); return instChange; }
/** Check whether workspace has a non-trivial instrument * (1) There is an instrument associated with * (2) Number of detectors is larger than 0 */ bool MaskWorkspace::hasInstrument() { bool hasinst; Geometry::Instrument_const_sptr inst = this->getInstrument(); if (inst) { if (inst->getNumberDetectors() > 0) hasinst = true; else hasinst = false; } else hasinst = false; return hasinst; }
/** Convert bank to detectors */ void LoadMask::bankToDetectors(std::vector<std::string> singlebanks, std::vector<int32_t> &detectors, std::vector<int32_t> &detectorpairslow, std::vector<int32_t> &detectorpairsup) { std::stringstream infoss; infoss << "Bank IDs to be converted to detectors: " << endl; for (auto &singlebank : singlebanks) { infoss << "Bank: " << singlebank << std::endl; } g_log.debug(infoss.str()); Geometry::Instrument_const_sptr minstrument = m_maskWS->getInstrument(); for (auto &singlebank : singlebanks) { std::vector<Geometry::IDetector_const_sptr> idetectors; minstrument->getDetectorsInBank(idetectors, singlebank); g_log.debug() << "Bank: " << singlebank << " has " << idetectors.size() << " detectors" << std::endl; // a) get information size_t numdets = idetectors.size(); detid_t detid_first = idetectors[0]->getID(); detid_t detid_last = idetectors[idetectors.size() - 1]->getID(); // b) set detectors if (detid_first + int32_t(numdets) == detid_last + 1 && false) { // TODO This save-time method is not used at this stage g_log.information() << "Using Range of Detectors" << std::endl; detectorpairslow.push_back(detid_first); detectorpairsup.push_back(detid_last); } else { g_log.debug() << "Apply 1 by 1 " << "DetID: " << detid_first << ", " << detid_last << std::endl; for (const auto &det : idetectors) { int32_t detid = det->getID(); detectors.push_back(detid); } } // if-else } // ENDFOR return; }
/** Gets the primary flightpath (L1) * @return L1 * @throw Kernel::Exception::InstrumentDefinitionError if L1 is not available */ double UnwrapMonitor::getPrimaryFlightpath() const { // Get a pointer to the instrument contained in the input workspace Geometry::Instrument_const_sptr instrument = m_inputWS->getInstrument(); // Get the distance between the source and the sample Geometry::IComponent_const_sptr sample = instrument->getSample(); double L1; try { L1 = instrument->getSource()->getDistance(*sample); g_log.debug() << "Source-sample distance (in metres): " << L1 << std::endl; } catch (Exception::NotFoundError &) { g_log.error("Unable to calculate source-sample distance"); throw Exception::InstrumentDefinitionError( "Unable to calculate source-sample distance", m_inputWS->getTitle()); } return L1; }
/** * Set the absolute detector position of a detector * @param instrument :: The instrument that contains the defined detector * @param detID :: Detector ID * @param pos :: new position of Dectector * @param sameParent :: true if detector has same parent as previous detector set here. */ void ApplyCalibration::setDetectorPosition(const Geometry::Instrument_const_sptr & instrument, int detID, V3D pos, bool /*sameParent*/ ) { Geometry::IDetector_const_sptr det = instrument->getDetector(detID); // Then find the corresponding relative position boost::shared_ptr<const Geometry::IComponent> parent = det->getParent(); if (parent) { pos -= parent->getPos(); Quat rot = parent->getRelativeRot(); rot.inverse(); rot.rotate(pos); } boost::shared_ptr<const Geometry::IComponent>grandparent = parent->getParent(); if (grandparent) { Quat rot = grandparent->getRelativeRot(); rot.inverse(); rot.rotate(pos); boost::shared_ptr<const Geometry::IComponent>greatgrandparent = grandparent->getParent(); if (greatgrandparent) { Quat rot2 = greatgrandparent->getRelativeRot(); rot2.inverse(); rot2.rotate(pos); } } // Add a parameter for the new position m_pmap->addV3D(det.get(), "pos", pos); }
/* * Define edges for each instrument by masking. For CORELLI, tubes 1 and 16, and *pixels 0 and 255. * Get Q in the lab frame for every peak, call it C * For every point on the edge, the trajectory in reciprocal space is a straight *line, going through O=V3D(0,0,0). * Calculate a point at a fixed momentum, say k=1. Q in the lab frame *E=V3D(-k*sin(tt)*cos(ph),-k*sin(tt)*sin(ph),k-k*cos(ph)). * Normalize E to 1: E=E*(1./E.norm()) * * @param inst: instrument */ void IntegrateEllipsoids::calculateE1(Geometry::Instrument_const_sptr inst) { std::vector<detid_t> detectorIDs = inst->getDetectorIDs(); for (auto &detectorID : detectorIDs) { Mantid::Geometry::IDetector_const_sptr det = inst->getDetector(detectorID); if (det->isMonitor()) continue; // skip monitor if (!det->isMasked()) continue; // edge is masked so don't check if not masked double tt1 = det->getTwoTheta(V3D(0, 0, 0), V3D(0, 0, 1)); // two theta double ph1 = det->getPhi(); // phi V3D E1 = V3D(-std::sin(tt1) * std::cos(ph1), -std::sin(tt1) * std::sin(ph1), 1. - std::cos(tt1)); // end of trajectory E1 = E1 * (1. / E1.norm()); // normalize E1Vec.push_back(E1); } }
/** * Set the absolute detector position of a detector * @param instrument :: The instrument that contains the defined detector * @param detID :: Detector ID * @param pos :: new position of Dectector * @param sameParent :: true if detector has same parent as previous detector set here. */ void ApplyCalibration::setDetectorPosition(const Geometry::Instrument_const_sptr & instrument, int detID, V3D pos, bool /*sameParent*/ ) { IComponent_const_sptr det =instrument->getDetector(detID); ; // Do the move using namespace Geometry::ComponentHelper; TransformType positionType = Absolute; // TransformType positionType = Relative; Geometry::ComponentHelper::moveComponent(*det, *m_pmap, pos, positionType); }
/** * Set the detector positions given the r,theta and phi. * @param detID :: A vector of detector IDs * @param l2 :: A vector of l2 distances * @param theta :: A vector of theta distances * @param phi :: A vector of phi values */ void UpdateInstrumentFromFile::setDetectorPositions(const std::vector<int32_t> & detID, const std::vector<float> & l2, const std::vector<float> & theta, const std::vector<float> & phi) { Geometry::Instrument_const_sptr inst = m_workspace->getInstrument(); const int numDetector = static_cast<int>(detID.size()); g_log.information() << "Setting new positions for " << numDetector << " detectors\n"; for (int i = 0; i < numDetector; ++i) { try { Geometry::IDetector_const_sptr det = inst->getDetector(detID[i]); setDetectorPosition(det, l2[i], theta[i], phi[i]); } catch (Kernel::Exception::NotFoundError&) { continue; } progress(static_cast<double>(i)/numDetector,"Updating Detector Positions from File"); } }
/** @param ws Name of workspace containing peaks @param bankName Name of bank containing peak @param col Column number containing peak @param row Row number containing peak @param Edge Number of edge points for each bank @return True if peak is on edge */ bool OptimizeLatticeForCellType::edgePixel(PeaksWorkspace_sptr ws, std::string bankName, int col, int row, int Edge) { if (bankName.compare("None") == 0) return false; Geometry::Instrument_const_sptr Iptr = ws->getInstrument(); boost::shared_ptr<const IComponent> parent = Iptr->getComponentByName(bankName); if (parent->type().compare("RectangularDetector") == 0) { boost::shared_ptr<const RectangularDetector> RDet = boost::dynamic_pointer_cast<const RectangularDetector>(parent); return col < Edge || col >= (RDet->xpixels() - Edge) || row < Edge || row >= (RDet->ypixels() - Edge); } 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 startI = 1; if (children[0]->getName() == "sixteenpack") { startI = 0; parent = children[0]; children.clear(); boost::shared_ptr<const Geometry::ICompAssembly> asmb = boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(parent); asmb->getChildren(children, false); } boost::shared_ptr<const Geometry::ICompAssembly> asmb2 = boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(children[0]); std::vector<Geometry::IComponent_const_sptr> grandchildren; asmb2->getChildren(grandchildren, false); int NROWS = static_cast<int>(grandchildren.size()); int NCOLS = static_cast<int>(children.size()); // Wish pixels and tubes start at 1 not 0 return col - startI < Edge || col - startI >= (NCOLS - Edge) || row - startI < Edge || row - startI >= (NROWS - Edge); } return false; }
/** * Init variables caches * @param :: Workspace pointer */ void SofQW2::initCachedValues(API::MatrixWorkspace_const_sptr workspace) { m_progress->report("Initializing caches"); // Retrieve the emode & efixed properties const std::string emode = getProperty("EMode"); // Convert back to an integer representation m_emode = 0; if (emode == "Direct") m_emode=1; else if (emode == "Indirect") m_emode = 2; m_efixed = getProperty("EFixed"); // Conversion constant for E->k. k(A^-1) = sqrt(energyToK*E(meV)) m_EtoK = 8.0*M_PI*M_PI*PhysicalConstants::NeutronMass*PhysicalConstants::meV*1e-20 / (PhysicalConstants::h*PhysicalConstants::h); // Get a pointer to the instrument contained in the workspace Geometry::Instrument_const_sptr instrument = workspace->getInstrument(); // Get the distance between the source and the sample (assume in metres) Geometry::IObjComponent_const_sptr source = instrument->getSource(); Geometry::IObjComponent_const_sptr sample = instrument->getSample(); m_samplePos = sample->getPos(); m_beamDir = m_samplePos - source->getPos(); m_beamDir.normalize(); // Is the instrument set up correctly double l1(0.0); try { l1 = source->getDistance(*sample); g_log.debug() << "Source-sample distance: " << l1 << std::endl; } catch (Exception::NotFoundError &) { throw Exception::InstrumentDefinitionError("Unable to calculate source-sample distance", workspace->getTitle()); } // Index Q cache initQCache(workspace); }
void LoadHelper::rotateComponent(API::MatrixWorkspace_sptr ws, const std::string &componentName, const Kernel::Quat & rot) { try { Geometry::Instrument_const_sptr instrument = ws->getInstrument(); Geometry::IComponent_const_sptr component = instrument->getComponentByName(componentName); //g_log.debug() << tube->getName() << " : t = " << theta << " ==> t = " << newTheta << "\n"; Geometry::ParameterMap& pmap = ws->instrumentParameters(); Geometry::ComponentHelper::rotateComponent(*component, pmap, rot, Geometry::ComponentHelper::Absolute); } catch (Mantid::Kernel::Exception::NotFoundError&) { throw std::runtime_error("Error when trying to move the " + componentName + " : NotFoundError"); } catch (std::runtime_error &) { throw std::runtime_error("Error when trying to move the " + componentName + " : runtime_error"); } }
void PoldiBasicChopper::loadConfiguration( Geometry::Instrument_const_sptr poldiInstrument) { Geometry::ICompAssembly_const_sptr chopperGroup = boost::dynamic_pointer_cast<const Geometry::ICompAssembly>( poldiInstrument->getComponentByName(std::string("chopper"))); size_t numberOfSlits = chopperGroup->nelements(); std::vector<double> slitPositions(numberOfSlits); for (size_t i = 0; i < numberOfSlits; ++i) { slitPositions[i] = chopperGroup->getChild(static_cast<const int>(i))->getPos().X(); } double distance = chopperGroup->getPos().norm() * 1000.0; double t0 = chopperGroup->getNumberParameter("t0").front(); double t0const = chopperGroup->getNumberParameter("t0_const").front(); initializeFixedParameters(slitPositions, distance, t0, t0const); }
/** Execute the algorithm. */ void EditInstrumentGeometry::exec() { // Lots of things have to do with the input workspace MatrixWorkspace_sptr workspace = getProperty("Workspace"); Geometry::Instrument_const_sptr originstrument = workspace->getInstrument(); // Get and check the primary flight path double l1 = this->getProperty("PrimaryFlightPath"); if (isEmpty(l1)) { // Use the original L1 if (!originstrument) { std::string errmsg( "It is not supported that L1 is not given, ", "while there is no instrument associated to input workspace."); g_log.error(errmsg); throw std::runtime_error(errmsg); } Geometry::IComponent_const_sptr source = originstrument->getSource(); Geometry::IComponent_const_sptr sample = originstrument->getSample(); l1 = source->getDistance(*sample); g_log.information() << "Retrieve L1 from input data workspace. \n"; } g_log.information() << "Using L1 = " << l1 << "\n"; // Get spectra number in case they are in a funny order std::vector<int32_t> specids = this->getProperty("SpectrumIDs"); if (specids.empty()) // they are using the order of the input workspace { size_t numHist = workspace->getNumberHistograms(); for (size_t i = 0; i < numHist; ++i) { specids.push_back(workspace->getSpectrum(i).getSpectrumNo()); g_log.information() << "Add spectrum " << workspace->getSpectrum(i).getSpectrumNo() << ".\n"; } } // Get the detector ids - empsy means ignore it const vector<int> vec_detids = getProperty("DetectorIDs"); const bool renameDetID(!vec_detids.empty()); // Get individual detector geometries ordered by input spectrum Numbers const std::vector<double> l2s = this->getProperty("L2"); const std::vector<double> tths = this->getProperty("Polar"); std::vector<double> phis = this->getProperty("Azimuthal"); // empty list of L2 and 2-theta is not allowed if (l2s.empty()) { throw std::runtime_error("User must specify L2 for all spectra. "); } if (tths.empty()) { throw std::runtime_error("User must specify 2theta for all spectra."); } // empty list of phi means that they are all zero if (phis.empty()) { phis.assign(l2s.size(), 0.); } // Validate for (size_t ib = 0; ib < l2s.size(); ib++) { g_log.information() << "Detector " << specids[ib] << " L2 = " << l2s[ib] << " 2Theta = " << tths[ib] << '\n'; if (specids[ib] < 0) { // Invalid spectrum Number : less than 0. stringstream errmsgss; errmsgss << "Detector ID = " << specids[ib] << " cannot be less than 0."; throw std::invalid_argument(errmsgss.str()); } if (l2s[ib] <= 0.0) { throw std::invalid_argument("L2 cannot be less or equal to 0"); } } // Keep original instrument and set the new instrument, if necessary const auto spec2indexmap = workspace->getSpectrumToWorkspaceIndexMap(); // ??? Condition: spectrum has 1 and only 1 detector size_t nspec = workspace->getNumberHistograms(); // Initialize another set of L2/2-theta/Phi/DetectorIDs vector ordered by // workspace index std::vector<double> storL2s(nspec, 0.); std::vector<double> stor2Thetas(nspec, 0.); std::vector<double> storPhis(nspec, 0.); vector<int> storDetIDs(nspec, 0); // Map the properties from spectrum Number to workspace index for (size_t i = 0; i < specids.size(); i++) { // Find spectrum's workspace index auto it = spec2indexmap.find(specids[i]); if (it == spec2indexmap.end()) { stringstream errss; errss << "Spectrum Number " << specids[i] << " is not found. " << "Instrument won't be edited for this spectrum. \n"; g_log.error(errss.str()); throw std::runtime_error(errss.str()); } // Store and set value size_t workspaceindex = it->second; storL2s[workspaceindex] = l2s[i]; stor2Thetas[workspaceindex] = tths[i]; storPhis[workspaceindex] = phis[i]; if (renameDetID) storDetIDs[workspaceindex] = vec_detids[i]; g_log.debug() << "workspace index = " << workspaceindex << " is for Spectrum " << specids[i] << '\n'; } // Generate a new instrument // Name of the new instrument std::string name = std::string(getProperty("InstrumentName")); if (name.empty()) { // Use the original L1 if (!originstrument) { std::string errmsg( "It is not supported that InstrumentName is not given, ", "while there is no instrument associated to input workspace."); g_log.error(errmsg); throw std::runtime_error(errmsg); } name = originstrument->getName(); } // Create a new instrument from scratch any way. auto instrument = boost::make_shared<Geometry::Instrument>(name); if (!bool(instrument)) { stringstream errss; errss << "Trying to use a Parametrized Instrument as an Instrument."; g_log.error(errss.str()); throw std::runtime_error(errss.str()); } // Set up source and sample information Geometry::ObjComponent *samplepos = new Geometry::ObjComponent("Sample", instrument.get()); instrument->add(samplepos); instrument->markAsSamplePos(samplepos); samplepos->setPos(0.0, 0.0, 0.0); Geometry::ObjComponent *source = new Geometry::ObjComponent("Source", instrument.get()); instrument->add(source); instrument->markAsSource(source); source->setPos(0.0, 0.0, -1.0 * l1); // Add/copy detector information auto indexInfo = workspace->indexInfo(); std::vector<detid_t> detIDs; for (size_t i = 0; i < workspace->getNumberHistograms(); i++) { // Create a new detector. // (Instrument will take ownership of pointer so no need to delete.) detid_t newdetid; if (renameDetID) newdetid = storDetIDs[i]; else newdetid = detid_t(i) + 100; Geometry::Detector *detector = new Geometry::Detector("det", newdetid, samplepos); // Set up new detector parameters related to new instrument double l2 = storL2s[i]; double tth = stor2Thetas[i]; double phi = storPhis[i]; Kernel::V3D pos; pos.spherical(l2, tth, phi); detector->setPos(pos); // Add new detector to spectrum and instrument // Good and do some debug output g_log.debug() << "Orignal spectrum " << indexInfo.spectrumNumber(i) << "has " << indexInfo.detectorIDs(i).size() << " detectors. \n"; detIDs.push_back(newdetid); instrument->add(detector); instrument->markAsDetector(detector); } // ENDFOR workspace index indexInfo.setDetectorIDs(std::move(detIDs)); workspace->setIndexInfo(indexInfo); // Add the new instrument workspace->setInstrument(instrument); }