Commit f9ffc7db authored by Janik Zikovsky's avatar Janik Zikovsky
Browse files

Refs #3203. Refs #3380: Removing more calls to spectraMap()

parent d367d132
......@@ -122,6 +122,7 @@ namespace Mantid
void getIndicesFromSpectra(const std::vector<specid_t>& spectraList, std::vector<size_t>& indexList) const;
size_t getIndexFromSpectrumNumber(const specid_t specNo) const;
void getIndicesFromDetectorIDs(const std::vector<detid_t>& detIdList, std::vector<size_t>& indexList) const;
void getSpectraFromDetectorIDs(const std::vector<detid_t>& detIdList, std::vector<specid_t>& spectraList) const;
/// Get the footprint in memory in bytes.
virtual size_t getMemorySize() const;
......
......@@ -262,11 +262,6 @@ void IFunctionMW::setMatrixWorkspace(boost::shared_ptr<const API::MatrixWorkspac
const Geometry::ParameterMap& paramMap = m_workspace->instrumentParameters();
// // in some tests where workspace a created on the fly a spectra to detector map
// // is for convenience not created.
// if ( !(m_workspace->spectraMap().nElements()) )
// return;
Geometry::IDetector_sptr det = m_workspace->getDetector(wi);
// if det is a detector groupworkspace then take as the detector
......
......@@ -352,7 +352,8 @@ namespace Mantid
buildNearestNeighbours(comp);
}
// Find the spectrum number
std::vector<specid_t> spectra = m_spectraMap->getSpectra(std::vector<detid_t>(1, comp->getID()));
std::vector<specid_t> spectra;
this->getSpectraFromDetectorIDs(std::vector<detid_t>(1, comp->getID()), spectra);
if(spectra.empty())
{
throw Kernel::Exception::NotFoundError("MatrixWorkspace::getNeighbours - Cannot find spectrum number for detector", comp->getID());
......@@ -592,6 +593,42 @@ namespace Mantid
}
//---------------------------------------------------------------------------------------
/** Converts a list of detector IDs to the corresponding spectrum numbers. Might be slow!
*
* @param detIdList :: The list of detector IDs required
* @param spectraList :: Returns a reference to the vector of spectrum numbers.
* 0 for not-found detectors
*/
void MatrixWorkspace::getSpectraFromDetectorIDs(const std::vector<detid_t>& detIdList, std::vector<specid_t>& spectraList) const
{
std::vector<detid_t>::const_iterator it_start = detIdList.begin();
std::vector<detid_t>::const_iterator it_end = detIdList.end();
spectraList.clear();
// Try every detector in the list
std::vector<detid_t>::const_iterator it;
for (it = it_start; it != it_end; it++)
{
bool foundDet = false;
specid_t foundSpecNum = 0;
// Go through every histogram
for (size_t i=0; i<this->getNumberHistograms(); i++)
{
if (this->getSpectrum(i)->hasDetectorID(*it))
{
foundDet = true;
foundSpecNum = this->getSpectrum(i)->getSpectrumNo();
break;
}
}
if (foundDet)
spectraList.push_back(foundSpecNum);
} // for each detector ID in the list
}
//---------------------------------------------------------------------------------------
......
......@@ -135,25 +135,47 @@ void GetEi::getGeometry(API::MatrixWorkspace_const_sptr WS, specid_t mon0Spec, s
const IObjComponent_sptr source = WS->getInstrument()->getSource();
// retrieve a pointer to the first detector and get its distance
std::vector<detid_t> dets = WS->spectraMap().getDetectors(mon0Spec);
size_t monWI = 0;
try
{
monWI = WS->getIndexFromSpectrumNumber(mon0Spec);
}
catch (std::runtime_error & e)
{
g_log.error() << "Could not find the workspace index for the monitor at spectrum " << mon0Spec << "\n";
g_log.error() << "Error retrieving data for the first monitor" << std::endl;
throw std::bad_cast();
}
const std::set<detid_t> & dets = WS->getSpectrum(monWI)->getDetectorIDs();
if ( dets.size() != 1 )
{
g_log.error() << "The detector for spectrum number " << mon0Spec << " was either not found or is a group, grouped monitors are not supported by this algorithm\n";
g_log.error() << "Error retrieving data for the first monitor" << std::endl;
throw std::bad_cast();
}
IDetector_sptr det = WS->getInstrument()->getDetector(dets[0]);
IDetector_sptr det = WS->getInstrument()->getDetector(*dets.begin());
monitor0Dist = det->getDistance(*(source.get()));
// repeat for the second detector
dets = WS->spectraMap().getDetectors(mon1Spec);
if ( dets.size() != 1 )
try
{
monWI = WS->getIndexFromSpectrumNumber(mon0Spec);
}
catch (std::runtime_error & e)
{
g_log.error() << "Could not find the workspace index for the monitor at spectrum " << mon0Spec << "\n";
g_log.error() << "Error retrieving data for the second monitor\n";
throw std::bad_cast();
}
const std::set<detid_t> & dets2 = WS->getSpectrum(monWI)->getDetectorIDs();
if ( dets2.size() != 1 )
{
g_log.error() << "The detector for spectrum number " << mon1Spec << " was either not found or is a group, grouped monitors are not supported by this algorithm\n";
g_log.error() << "Error retrieving data for the second monitor\n";
throw std::bad_cast();
}
det = WS->getInstrument()->getDetector(dets[0]);
det = WS->getInstrument()->getDetector(*dets2.begin());
monitor1Dist = det->getDistance(*(source.get()));
}
/** Converts detector IDs to spectra indexes
......
......@@ -231,10 +231,6 @@ double RemoveLowResTOF::calcTofMin(const size_t workspaceIndex)
const std::set<detid_t> & detSet = m_inputWS->getSpectrum(workspaceIndex)->getDetectorIDs();
detNumbers.assign(detSet.begin(), detSet.end());
// const specid_t spec = m_inputWS->getAxis(1)->spectraNo(workspaceIndex);
// std::vector<detid_t> detNumbers = m_inputWS->spectraMap().getDetectors(spec);
std::map<detid_t,double> offsets; // just an empty offsets map
double dspmap = Instrument::calcConversion(m_L1, beamline, beamline_norm, samplePos,
m_instrument, detNumbers, offsets, false);
......
......@@ -78,8 +78,6 @@ void SpatialGrouping::exec()
int gridSize = getProperty("GridSize");
size_t nNeighbours = ( gridSize * gridSize ) - 1;
const Mantid::Geometry::ISpectraDetectorMap & smap = inputWorkspace->spectraMap();
// Make a map key = spectrum number, value = detector at that spectrum
m_detectors.clear();
for (size_t i=0; i<inputWorkspace->getNumberHistograms(); i++)
......@@ -183,8 +181,10 @@ void SpatialGrouping::exec()
xml << "<group name=\"group" << grpID++ << "\"><detids val=\"" << (*grpIt)[0];
for ( size_t i = 1; i < (*grpIt).size(); i++ )
{
std::vector<detid_t> detIds = smap.getDetectors((*grpIt)[i]);
for ( std::vector<detid_t>::iterator it = detIds.begin(); it != detIds.end(); ++it )
//The following lines replace: std::vector<detid_t> detIds = smap.getDetectors((*grpIt)[i]);
size_t workspaceIndex = inputWorkspace->getIndexFromSpectrumNumber((*grpIt)[i]);
const std::set<detid_t> & detIds = inputWorkspace->getSpectrum(workspaceIndex)->getDetectorIDs();
for ( std::set<detid_t>::const_iterator it = detIds.begin(); it != detIds.end(); ++it )
{
xml << "," << (*it);
}
......
......@@ -50,14 +50,6 @@ public:
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("StartWorkspaceIndex","1") );
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("EndWorkspaceIndex","3") );
size_t nspecEntries(0);
const Mantid::Geometry::ISpectraDetectorMap & specMap_in = inputSpace->spectraMap();
// Spectra at workspace index 1 is masked
for( int i = 2; i < 4; ++i )
{
nspecEntries += specMap_in.ndet(i);
}
TS_ASSERT_THROWS_NOTHING( alg.execute());
TS_ASSERT( alg.isExecuted() );
......@@ -87,7 +79,7 @@ public:
// Check the detectors mapped to the single spectra
const ISpectrum * spec = output2D->getSpectrum(0);
TS_ASSERT_EQUALS( spec->getSpectrumNo(), 1);
TS_ASSERT_EQUALS( spec->getDetectorIDs().size(), nspecEntries);
TS_ASSERT_EQUALS( spec->getDetectorIDs().size(), 2);
TS_ASSERT( spec->hasDetectorID(3) );
TS_ASSERT( spec->hasDetectorID(4) );
}
......@@ -107,15 +99,6 @@ public:
// Check setting of invalid property value causes failure
TS_ASSERT_THROWS( alg2.setPropertyValue("StartWorkspaceIndex","-1"), std::invalid_argument) ;
size_t nspecEntries(0);
const size_t nHist(inputSpace->getNumberHistograms());
const Geometry::ISpectraDetectorMap & specMap_in = inputSpace->spectraMap();
// Spectra at workspace index 1 is masked, 8 & 9 are monitors
for( size_t i = 1; i < nHist-2; ++i )
{
nspecEntries += specMap_in.ndet(static_cast<specid_t>(i));
}
TS_ASSERT_THROWS_NOTHING( alg2.execute());
TS_ASSERT( alg2.isExecuted() );
......@@ -148,7 +131,8 @@ public:
// Check the detectors mapped to the single spectra
const ISpectrum * spec = output2D->getSpectrum(0);
TS_ASSERT_EQUALS( spec->getSpectrumNo(), 0);
TS_ASSERT_EQUALS( spec->getDetectorIDs().size(), nspecEntries);
// Spectra at workspace index 1 is masked, 8 & 9 are monitors
TS_ASSERT_EQUALS( spec->getDetectorIDs().size(), 7);
TS_ASSERT( spec->hasDetectorID(1) );
TS_ASSERT( spec->hasDetectorID(3) );
TS_ASSERT( spec->hasDetectorID(4) );
......
......@@ -85,11 +85,10 @@ void GroupDetectors::exec()
WS->getIndicesFromSpectra(spectraList,indexList);
}// End dealing with spectraList
else if ( ! detectorList.empty() )
{// Dealing with DetectorList
//convert from detectors to spectra numbers
std::vector<specid_t> mySpectraList = WS->spectraMap().getSpectra(detectorList);
//then from spectra numbers to indices
WS->getIndicesFromSpectra(mySpectraList,indexList);
{
// Dealing with DetectorList
//convert from detectors to workspace indices
WS->getIndicesFromDetectorIDs(detectorList, indexList);
}
if ( indexList.size() == 0 )
......@@ -104,13 +103,6 @@ void GroupDetectors::exec()
ISpectrum * firstSpectrum = WS->getSpectrum(firstIndex);
setProperty("ResultIndex",firstIndex);
const Geometry::ISpectraDetectorMap & inputSpectra = WS->spectraMap();
API::SpectraDetectorMap *groupedMap = dynamic_cast<API::SpectraDetectorMap*>(inputSpectra.clone());
if( !groupedMap )
{
throw std::invalid_argument("Input workspace with a 1:1 spectra-detector map is not supported "
"by this algorithm.");
}
// loop over the spectra to group
Progress progress(this, 0.0, 1.0, static_cast<int>(indexList.size()-1));
......@@ -122,7 +114,6 @@ void GroupDetectors::exec()
// Add the current detector to belong to the first spectrum
firstSpectrum->addDetectorIDs(spec->getDetectorIDs());
//groupedMap->remap(spectraAxis->spectraNo(currentIndex), firstSpectrum);
// Add up all the Y spectra and store the result in the first one
// Need to keep the next 3 lines inside loop for now until ManagedWorkspace mru-list works properly
......@@ -146,11 +137,9 @@ void GroupDetectors::exec()
spec->clearDetectorIDs();
progress.report();
}
g_log.information() << "Testing " << groupedMap->nElements() << "\n";
// Replace the old map
WS->generateSpectraMap();
// WS->replaceSpectraMap(groupedMap);
}
} // namespace DataHandling
......
......@@ -195,10 +195,8 @@ void GroupDetectors2::getGroups(API::MatrixWorkspace_const_sptr workspace,
{// go thorugh the rest of the properties in order of decreasing presidence, abort when we get the data we need ignore the rest
if ( ! detectorList.empty() )
{
// we are going to group on the basis of detector IDs, convert from detectors to spectra numbers
std::vector<specid_t> mySpectraList = workspace->spectraMap().getSpectra(detectorList);
//then from spectra numbers to indices
workspace->getIndicesFromSpectra( mySpectraList, m_GroupSpecInds[0]);
// we are going to group on the basis of detector IDs, convert from detectors to workspace indices
workspace->getIndicesFromDetectorIDs( detectorList, m_GroupSpecInds[0]);
g_log.debug() << "Found " << m_GroupSpecInds[0].size() << " spectra indices from the list of " << detectorList.size() << " detectors\n";
}
else if ( ! indexList.empty() )
......
......@@ -510,7 +510,8 @@ void LoadDetectorInfo::adjustXs(const std::vector<detid_t> &detIDs, const std::v
{
// getting spectra numbers from detector IDs is hard because the map works the other way, getting index numbers from spectra numbers has the same problem and we are about to do both
// function adds zero if it can't find a detector into the new, probably large, multimap of detectorIDs to spectra numbers
std::vector<specid_t> spectraList = m_workspace->spectraMap().getSpectra(detIDs);
std::vector<specid_t> spectraList;
m_workspace->getSpectraFromDetectorIDs(detIDs, spectraList);
// allow spectra number to spectra index look ups
spec2index_map specs2index;
......@@ -561,12 +562,12 @@ void LoadDetectorInfo::adjustXs(const double detectorOffset)
MantidVecPtr newXs;
for ( int specInd = 0; specInd < m_numHists; ++specInd )
{// check if we dealing with a monitor as these are dealt by a different function
const specid_t specNum = m_workspace->getAxis(1)->spectraNo(specInd);
const std::vector<detid_t> dets = m_workspace->spectraMap().getDetectors(specNum);
{
// check if we dealing with a monitor as these are dealt by a different function
const std::set<detid_t> & dets = m_workspace->getSpectrum(size_t(specInd))->getDetectorIDs();
if ( dets.size() > 0 )
{// is it in the monitors list
if ( m_monitors.find(dets[0]) == m_monitors.end() )
if ( m_monitors.find(*dets.begin()) == m_monitors.end() )
{// it's not a monitor, it's a regular detector
if ( (*newXs).empty() )
{// we don't have any cached values from doing the offsetting previously, do the calculation
......@@ -649,13 +650,14 @@ void LoadDetectorInfo::adjustXsCommon(const std::vector<float> &offsets, const s
// and then move on to the next detector in the loop
continue;
}
const size_t specIndex = specs2index[spectraList[j]];
// check if we dealing with a monitor as these are dealt by a different function
const std::vector<detid_t> dets =
m_workspace->spectraMap().getDetectors(spectraList[j]);
const std::set<detid_t> & dets = m_workspace->getSpectrum(specIndex)->getDetectorIDs();
if ( dets.size() > 0 )
{// is it in the monitors list
if ( m_monitors.find(dets[0]) == m_monitors.end() )
if ( m_monitors.find(*dets.begin()) == m_monitors.end() )
{// it's not a monitor, it's a regular detector
if ( offsets[j] != cachedOffSet )
{
......@@ -705,12 +707,13 @@ void LoadDetectorInfo::adjustXsUnCommon(const std::vector<float> &offsets, const
continue;
}
const size_t specIndex = specs2index[spectraList[j]];
// check if we dealing with a monitor as these are dealt by a different function
const std::vector<detid_t> dets =
m_workspace->spectraMap().getDetectors(spectraList[j]);
const std::set<detid_t> & dets = m_workspace->getSpectrum(specIndex)->getDetectorIDs();
if ( dets.size() > 0 )
{// is it in the monitors list
if ( m_monitors.find(dets[0]) == m_monitors.end() )
if ( m_monitors.find(*dets.begin()) == m_monitors.end() )
{// it's not a monitor, it's a regular detector
MantidVec &Xbins = m_workspace->dataX(specIndex);
std::transform(Xbins.begin(), Xbins.end(), Xbins.begin(),
......
......@@ -657,19 +657,6 @@ API::Workspace_sptr LoadNexusProcessed::loadEntry(NXRoot & root, const std::stri
loadNonSpectraAxis(local_workspace, wksp_cls);
}
// // Handle the detectors back from the spectra map for event workspaces
// if (isEvent)
// {
// EventWorkspace_sptr ew = boost::dynamic_pointer_cast<EventWorkspace>(local_workspace);
// for (std::size_t wi=0; wi<local_workspace->getNumberHistograms(); wi++)
// {
// std::vector<detid_t> dets = local_workspace->spectraMap().getDetectors(static_cast<specid_t>(wi));
// EventList & el = ew->getEventList(wi);
// el.clearDetectorIDs();
// el.addDetectorIDs(dets);
// }
// }
progress(progressStart+0.15*progressRange,"Reading the workspace history...");
try
{
......
......@@ -444,9 +444,14 @@ namespace Mantid
{
if (!m_monitordetectorList.empty())
{
// Old way to get the spectra # for these detectors
const Geometry::ISpectraDetectorMap& specdetMap = localWorkspace->spectraMap();
//get the monitor spectrum list from SpectraDetectorMap
std::vector<specid_t> specList = specdetMap.getSpectra(m_monitordetectorList);
// //get the monitor spectrum list from SpectraDetectorMap
// std::vector<specid_t> specList;
// localWorkspace->getSpectraFromDetectorIDs(m_monitordetectorList, specList);
// remove duplicates by calling sort & unique algorithms
sort(specList.begin(), specList.end(), std::less<int>());
std::vector<specid_t>::iterator uEnd;
......
......@@ -91,10 +91,8 @@ void MaskDetectors::exec()
}// End dealing with spectraList
else if ( ! detectorList.empty() )
{
// Convert from detectors to spectra numbers
std::vector<specid_t> mySpectraList = WS->spectraMap().getSpectra(detectorList);
//then from spectra numbers to indices
fillIndexListFromSpectra(indexList,mySpectraList,WS);
// Convert from detectors to workspace indexes
WS->getIndicesFromDetectorIDs(detectorList, indexList);
}
// If we have a workspace that could contain masking,copy that in too
if( prevMasking )
......
......@@ -13,11 +13,13 @@
#include <cxxtest/TestSuite.h>
#include <iostream>
#include <Poco/File.h>
#include "MantidGeometry/IDTypes.h"
using namespace Mantid::NeXus;
using namespace Mantid::Kernel;
using namespace Mantid::DataObjects;
using namespace Mantid::API;
using Mantid::detid_t;
class LoadNexusProcessedTest : public CxxTest::TestSuite
{
......@@ -391,6 +393,7 @@ public:
{
const EventList & el = ws->getEventList(wi);
TS_ASSERT_EQUALS( el.getEventType(), type );
TS_ASSERT( el.hasDetectorID(detid_t(wi+1)*10) );
}
TS_ASSERT_EQUALS( ws->getEventList(0).getNumberEvents(), 300 );
TS_ASSERT_EQUALS( ws->getEventList(1).getNumberEvents(), 100 );
......
......@@ -764,7 +764,7 @@ public:
TS_ASSERT(output2D);
if (!output2D) return;
// Should be 6 for selected input
// Should be 3 for selected input
TS_ASSERT_EQUALS( output2D->getNumberHistograms(), 3);
// Check two X vectors are the same
......
......@@ -333,8 +333,7 @@ public:
//The spectra map should take each workspace index and point to the right pixel id: 5,15,25, etc.
for (int wi=0; wi<static_cast<int>(uneven->getNumberHistograms()); wi++)
{
specid_t specNo = uneven->getAxis(1)->spectraNo(wi);
TS_ASSERT_EQUALS( uneven->spectraMap().getDetectors(specNo)[0], 5 + wi*10);
TS_ASSERT_EQUALS( *uneven->getSpectrum(wi)->getDetectorIDs().begin(), 5 + wi*10);
}
//Workspace index 0 is at pixelid 5 and has 5 events
......
......@@ -30,8 +30,6 @@ public:
TS_ASSERT_EQUALS( ws->getNumberHistograms(), 100);
TS_ASSERT_EQUALS( ws->blocksize(), 1);
TS_ASSERT_THROWS_NOTHING( ws->spectraMap());
}
void test_constructor_from_Instrument()
......@@ -43,8 +41,7 @@ public:
TS_ASSERT_EQUALS( ws->getNumberHistograms(), 45);
TS_ASSERT_EQUALS( ws->blocksize(), 1);
TS_ASSERT_EQUALS( ws->getInstrument()->getName(), "basic"); // Name of the test instrument
TS_ASSERT_EQUALS( ws->spectraMap().nElements(), 45);
std::vector<detid_t> dets = ws->spectraMap().getDetectors(1);
const std::set<detid_t> & dets = ws->getSpectrum(0)->getDetectorIDs();
TS_ASSERT_EQUALS(dets.size(), 1);
TS_ASSERT_EQUALS( ws->getDetectorID(0), 1);
......
......@@ -61,7 +61,7 @@ public:
TS_ASSERT_EQUALS( inWS->readE(0)[i], outWS->readE(0)[i] );
}
TS_ASSERT( outWS->spectraMap().nElements() == 0 );
//TS_ASSERT( outWS->spectraMap().nElements() == 0 );
TS_ASSERT_EQUALS( inWS->getBaseInstrument(), outWS->getBaseInstrument() );
}
......
......@@ -1361,11 +1361,14 @@ using namespace DataObjects;
bool NexusFileIO::writeNexusProcessedSpectraMap(const API::MatrixWorkspace_const_sptr& localWorkspace,
const std::vector<int>& spec) const
{
// Count the total number of detectors
std::size_t nDetectors = 0;
for (size_t i=0; i<spec.size(); i++)
{
size_t wi = size_t(spec[i]); // Workspace index
nDetectors += localWorkspace->getSpectrum(wi)->getDetectorIDs().size();
}
const Geometry::ISpectraDetectorMap& spectraMap=localWorkspace->spectraMap();
API::Axis *spectraAxis = localWorkspace->getAxis(1);
const std::size_t nDetectors = spectraMap.nElements();
if(nDetectors<1)
{
// No data in spectraMap to write
......@@ -1401,15 +1404,21 @@ using namespace DataObjects;
// get data from map into Nexus Muon format
for(int i=0;i<numberSpec;i++)
{
// Workspace index
int si = spec[i];
spectra[i] = int32_t(spectraAxis->spectraNo(si));
const int ndet1=static_cast<int>(spectraMap.ndet(spectra[i]));
// Spectrum there
const ISpectrum * spectrum = localWorkspace->getSpectrum(si);
spectra[i] = int32_t(spectrum->getSpectrumNo());
// The detectors in this spectrum
const std::set<detid_t> & detectorgroup = spectrum->getDetectorIDs();
const int ndet1=static_cast<int>( detectorgroup.size() );
detector_index[i+1]= int32_t(detector_index[i]+ndet1); // points to start of detector list for the next spectrum
detector_count[i]= int32_t(ndet1);
ndet += ndet1;
const std::vector<detid_t> detectorgroup = spectraMap.getDetectors(spectra[i]);
std::vector<detid_t>::const_iterator it;
std::set<detid_t>::const_iterator it;
for (it=detectorgroup.begin();it!=detectorgroup.end();it++)
{
detector_list[id++]=int32_t(*it);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment