V3D SaveIsawDetCal::findPixelPos(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->getPos(); } 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); if (children[0]->getName().compare("sixteenpack") == 0) { asmb = boost::dynamic_pointer_cast<const Geometry::ICompAssembly>( children[0]); children.clear(); asmb->getChildren(children, false); } int col0 = col - 1; // WISH detectors are in bank in this order in instrument if (inst->getName() == "WISH") 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]; return first->getPos(); } }
/** * Cache frequently accessed user input */ void LoadDetectorInfo::cacheInputs() { m_workspace = getProperty("Workspace"); m_moveDets = getProperty("RelocateDets"); // Cache base instrument m_baseInstrument = m_workspace->getInstrument()->baseInstrument(); Geometry::IComponent_const_sptr sample = m_workspace->getInstrument()->getSample(); if (sample) m_samplePos = sample->getPos(); // cache values of instrument level parameters so we only change then if they // are different const auto &pmap = m_workspace->constInstrumentParameters(); // delay auto param = pmap.get(m_baseInstrument->getComponentID(), DELAY_PARAM); if (param) m_instDelta = param->value<double>(); // pressure param = pmap.get(m_baseInstrument->getComponentID(), PRESSURE_PARAM); if (param) m_instPressure = param->value<double>(); // thickness param = pmap.get(m_baseInstrument->getComponentID(), THICKNESS_PARAM); if (param) m_instThickness = param->value<double>(); }
/** * 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"); } }
/** Initialization method: @param bkgWS -- shared pointer to the workspace which contains background @param sourceWS -- shared pointer to the workspace to remove background from @param emode -- energy conversion mode used during internal units conversion (0 -- elastic, 1-direct, 2 indirect, as defined in Units conversion @param pLog -- pointer to the logger class which would report errors @param nThreads -- number of threads to be used for background removal @param inPlace -- if the background removal occurs from the existing workspace or target workspace has to be cloned. */ void BackgroundHelper::initialize(const API::MatrixWorkspace_const_sptr &bkgWS, const API::MatrixWorkspace_sptr &sourceWS, int emode, Kernel::Logger *pLog, int nThreads, bool inPlace) { m_bgWs = bkgWS; m_wkWS = sourceWS; m_Emode = emode; m_pgLog = pLog; m_inPlace = inPlace; std::string bgUnits = bkgWS->getAxis(0)->unit()->unitID(); if (bgUnits != "TOF") throw std::invalid_argument(" Background Workspace: " + bkgWS->getName() + " should be in the units of TOF"); if (!(bkgWS->getNumberHistograms() == 1 || sourceWS->getNumberHistograms() == bkgWS->getNumberHistograms())) throw std::invalid_argument(" Background Workspace: " + bkgWS->getName() + " should have the same number of spectra as " "source workspace or be a single histogram " "workspace"); auto WSUnit = sourceWS->getAxis(0)->unit(); if (!WSUnit) throw std::invalid_argument(" Source Workspace: " + sourceWS->getName() + " should have units"); Geometry::IComponent_const_sptr source = sourceWS->getInstrument()->getSource(); m_Sample = sourceWS->getInstrument()->getSample(); if ((!source) || (!m_Sample)) throw std::invalid_argument( "Instrument on Source workspace:" + sourceWS->getName() + "is not sufficiently defined: failed to get source and/or sample"); m_L1 = source->getDistance(*m_Sample); // just in case. this->deleteUnitsConverters(); // allocate the array of units converters to avoid units reallocation within a // loop m_WSUnit.assign(nThreads, NULL); for (int i = 0; i < nThreads; i++) { m_WSUnit[i] = WSUnit->clone(); } m_singleValueBackground = false; if (bkgWS->getNumberHistograms() == 0) m_singleValueBackground = true; const MantidVec &dataX = bkgWS->dataX(0); const MantidVec &dataY = bkgWS->dataY(0); // const MantidVec& dataE = bkgWS->dataE(0); m_NBg = dataY[0]; m_dtBg = dataX[1] - dataX[0]; // m_ErrSq = dataE[0]*dataE[0]; // needs further clarification m_Efix = this->getEi(sourceWS); }
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; }
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 }
void SaveIsawDetCal::sizeBanks(std::string bankName, int &NCOLS, int &NROWS, double &xsize, double &ysize) { if (bankName.compare("None") == 0) return; 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); NCOLS = RDet->xpixels(); NROWS = RDet->ypixels(); xsize = RDet->xsize(); ysize = RDet->ysize(); } 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); if (children[0]->getName().compare("sixteenpack") == 0) { asmb = boost::dynamic_pointer_cast<const Geometry::ICompAssembly>( children[0]); children.clear(); 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); NROWS = static_cast<int>(grandchildren.size()); NCOLS = static_cast<int>(children.size()); Geometry::IComponent_const_sptr first = children[0]; Geometry::IComponent_const_sptr last = children[NCOLS - 1]; xsize = first->getDistance(*last); first = grandchildren[0]; last = grandchildren[NROWS - 1]; ysize = first->getDistance(*last); } }
size_t MaskPeaksWorkspace::getWkspIndex(const detid2index_map &pixel_to_wi, Geometry::IComponent_const_sptr comp, const int x, const int y) { Geometry::RectangularDetector_const_sptr det = boost::dynamic_pointer_cast<const Geometry::RectangularDetector>(comp); if (det) { if (x >= det->xpixels() || x < 0 || y >= det->ypixels() || y < 0) return EMPTY_INT(); if ((x >= det->xpixels()) || (x < 0) // this check is unnecessary as callers are doing it too || (y >= det->ypixels()) || (y < 0)) // but just to make debugging easier { std::stringstream msg; msg << "Failed to find workspace index for x=" << x << " y=" << y << "(max x=" << det->xpixels() << ", max y=" << det->ypixels() << ")"; throw std::runtime_error(msg.str()); } int pixelID = det->getAtXY(x, y)->getID(); // Find the corresponding workspace index, if any auto wiEntry = pixel_to_wi.find(pixelID); if (wiEntry == pixel_to_wi.end()) { std::stringstream msg; msg << "Failed to find workspace index for x=" << x << " y=" << y; throw std::runtime_error(msg.str()); } return wiEntry->second; } else { std::vector<Geometry::IComponent_const_sptr> children; boost::shared_ptr<const Geometry::ICompAssembly> asmb = boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(comp); 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 if (x - 1 >= NCOLS || x - 1 < 0 || y - 1 >= NROWS || y - 1 < 0) return EMPTY_INT(); std::string bankName = comp->getName(); detid2index_map::const_iterator it = pixel_to_wi.find(findPixelID(bankName, x, y)); if (it == pixel_to_wi.end()) return EMPTY_INT(); return (it->second); } }
/** 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); }
/** 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 << '\n'; } 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); const auto &spectrumInfo = inputWS->spectrumInfo(); 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; if (!spectrumInfo.hasDetectors(i) || spectrumInfo.isMonitor(i)) continue; // if masked detectors state is not used, masked detectors just ignored; bool maskDetector = spectrumInfo.isMasked(i); if (m_getIsMasked) *(pMasksArray + liveDetectorsCount) = maskDetector ? 1 : 0; else if (maskDetector) continue; const auto &spDet = spectrumInfo.detector(i); // calculate the requested values; sp2detMap[i] = liveDetectorsCount; detId[liveDetectorsCount] = int32_t(spDet.getID()); detIDMap[liveDetectorsCount] = i; L2[liveDetectorsCount] = spectrumInfo.l2(i); double polar = spectrumInfo.twoTheta(i); 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, "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"; }
/* * 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; }
/** Get detectors' counts * @brief GetSpiceDataRawCountsFromMD::getDetCounts * @param mdws * @param runnumber :: run number of the detectors having for exporting; -1 for * all run numbers * @param detid :: detector ID for the detectors for exporting; -1 for all * detectors * @param vecX :: x-values as 2theta position of detectors to be exported; * @param vecY :: raw detector's counts * @param formX :: flag to set up vecX */ void GetSpiceDataRawCountsFromMD::getDetCounts( API::IMDEventWorkspace_const_sptr mdws, const int &runnumber, const int &detid, std::vector<double> &vecX, std::vector<double> &vecY, bool formX) { // Get sample and source position if (mdws->getNumExperimentInfo() == 0) throw std::runtime_error( "There is no ExperimentInfo object that has been set to " "input MDEventWorkspace!"); V3D samplepos; V3D sourcepos; if (formX) { ExperimentInfo_const_sptr expinfo = mdws->getExperimentInfo(0); Geometry::IComponent_const_sptr sample = expinfo->getInstrument()->getSample(); samplepos = sample->getPos(); g_log.debug() << "Sample position is " << samplepos.X() << ", " << samplepos.Y() << ", " << samplepos.Z() << "\n"; Geometry::IComponent_const_sptr source = expinfo->getInstrument()->getSource(); sourcepos = source->getPos(); g_log.debug() << "Source position is " << sourcepos.X() << "," << sourcepos.Y() << ", " << sourcepos.Z() << "\n"; vecX.clear(); } vecY.clear(); // Go through all events to find out their positions IMDIterator *mditer = mdws->createIterator(); bool scancell = true; size_t nextindex = 1; while (scancell) { // get the number of events of this cell size_t numev2 = mditer->getNumEvents(); g_log.debug() << "MDWorkspace " << mdws->name() << " Cell " << nextindex - 1 << ": Number of events = " << numev2 << " Does NEXT cell exist = " << mditer->next() << "\n"; // loop over all the events in current cell for (size_t iev = 0; iev < numev2; ++iev) { // filter out the events with uninterrested run numbers and detid // runnumber/detid < 0 indicates that all run number or all detectors will // be taken int thisrunnumber = mditer->getInnerRunIndex(iev); if (runnumber >= 0 && thisrunnumber != runnumber) continue; int thisdetid = mditer->getInnerDetectorID(iev); if (detid >= 0 && thisdetid != detid) continue; // get detector position for 2theta if (formX) { double tempx = mditer->getInnerPosition(iev, 0); double tempy = mditer->getInnerPosition(iev, 1); double tempz = mditer->getInnerPosition(iev, 2); Kernel::V3D detpos(tempx, tempy, tempz); Kernel::V3D v_det_sample = detpos - samplepos; Kernel::V3D v_sample_src = samplepos - sourcepos; double twotheta = v_det_sample.angle(v_sample_src) / M_PI * 180.; vecX.push_back(twotheta); } // add new value to vecPair double signal = mditer->getInnerSignal(iev); vecY.push_back(signal); } // ENDFOR (iev) // Advance to next cell if (mditer->next()) { // advance to next cell mditer->jumpTo(nextindex); ++nextindex; } else { // break the loop scancell = false; } } // ENDOF(while) delete (mditer); return; }