Skip to content

Commit

Permalink
refs #4201 More unit tests and some bug fixing
Browse files Browse the repository at this point in the history
Native Conversion for MD event workspaces, which do not involve dynamic rebinning enabled
  • Loading branch information
abuts committed Jan 9, 2012
1 parent 38ec346 commit a0c1397
Show file tree
Hide file tree
Showing 12 changed files with 179 additions and 87 deletions.
1 change: 1 addition & 0 deletions Code/Mantid/Framework/MDAlgorithms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ set ( TEST_FILES
test/BooleanBinaryOperationMDTest.h
test/ConvertToQ3DdETest.h
test/ConvertToMDEventsTest.h
test/ConvertToMDEventsUnitsConvTest.h
test/ConvertEventsToMDEventsTest.h
test/DivideMDTest.h
test/EqualToMDTest.h
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ struct COORD_TRANSFORMER<NoQ,MODE,CONV,Type>: public ICOORD_TRANSFORMER<NoQ,MODE
inline bool ConvertAndCalcMatrixCoord(const double & X,std::vector<coord_t> &Coord)const
{
double X_ev = CONV_UNITS_FROM.getXConverted(X);
return calcMatrixCoord(X_ev,Coord);
return calc1MatrixCoord(X_ev,Coord);
}

// constructor;
Expand Down Expand Up @@ -275,7 +275,7 @@ struct COORD_TRANSFORMER<modQ,MODE,CONV,Type>: public ICOORD_TRANSFORMER<modQ,MO
inline bool ConvertAndCalcMatrixCoord(const double & X,std::vector<coord_t> &Coord)const
{
double X_ev = CONV_UNITS_FROM.getXConverted(X);
return calcMatrixCoord(X_ev,Coord);
return calc1MatrixCoord(X_ev,Coord);
}
// constructor;
COORD_TRANSFORMER(){}
Expand Down Expand Up @@ -356,7 +356,7 @@ struct COORD_TRANSFORMER<modQ,Elastic,CONV,Type>: public ICOORD_TRANSFORMER<modQ
inline bool ConvertAndCalcMatrixCoord(const double & X,std::vector<coord_t> &Coord)const
{
double X_ev = CONV_UNITS_FROM.getXConverted(X);
return calcMatrixCoord(X_ev,Coord);
return calc1MatrixCoord(X_ev,Coord);
}

// constructor;
Expand Down Expand Up @@ -441,7 +441,7 @@ struct COORD_TRANSFORMER<Q3D,MODE,CONV,Type>: public ICOORD_TRANSFORMER<Q3D,MODE
inline bool ConvertAndCalcMatrixCoord(const double & X,std::vector<coord_t> &Coord)const
{
double X_ev = CONV_UNITS_FROM.getXConverted(X);
return calcMatrixCoord(X_ev,Coord);
return calc1MatrixCoord(X_ev,Coord);
}

COORD_TRANSFORMER(){}
Expand Down Expand Up @@ -516,7 +516,7 @@ struct COORD_TRANSFORMER<Q3D,Elastic,CONV,Type>: public ICOORD_TRANSFORMER<Q3D,E
inline bool ConvertAndCalcMatrixCoord(const double & X,std::vector<coord_t> &Coord)const
{
double X_ev = CONV_UNITS_FROM.getXConverted(X);
return calcMatrixCoord(X_ev,Coord);
return calc1MatrixCoord(X_ev,Coord);
}

COORD_TRANSFORMER(){}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,15 @@ struct PreprocessedDetectors{
std::vector<double> L2;
std::vector<double> TwoTheta;
std::vector<int32_t> det_id; // the detector ID;
std::vector<size_t> detIDMap;
std::vector<size_t> detIDMap; // stores spectra index which corresponds to a valid detector index;
std::vector<size_t> spec2detMap; //stores detector index which corresponds to the workspace index;
//
bool is_defined(void)const{return det_dir.size()>0;}
bool is_defined(size_t new_size)const{return det_dir.size()==new_size;}
std::vector<double>const & getL2()const{return L2;}
std::vector<double>const & getTwoTheta()const{return TwoTheta;}
std::vector<size_t>const & getDetIDMap()const{return detIDMap;}
std::vector<size_t>const & getSpec2DetMap()const{return spec2detMap;}
std::vector<Kernel::V3D>const & getDetDir()const{return det_dir;}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "MantidMDAlgorithms/IConvertToMDEventsMethods.h"
#include "MantidMDAlgorithms/ConvertToMDEventsDetInfo.h"
#include "MantidMDAlgorithms/ConvertToMDEventsCoordTransf.h"
#include <vector>

namespace Mantid
{
Expand Down Expand Up @@ -63,8 +64,10 @@ class ConvertToMDEvensEventWSAutoRebin: public IConvertToMDEventsMethods
friend struct COORD_TRANSFORMER;
// the instanciation of the class which does the transformation itself
COORD_TRANSFORMER<Q,MODE,ConvFromTOF,Histohram> trn;
// the pointer to underlying event workspace
DataObjects::EventWorkspace_const_sptr pEventWS;
//
virtual size_t conversionChunk(size_t){};
virtual size_t conversionChunk(size_t){return 0;}
public:
size_t setUPConversion(Mantid::API::MatrixWorkspace_sptr pWS2D, const PreprocessedDetectors &detLoc,
const MDEvents::MDWSDescription &WSD, boost::shared_ptr<MDEvents::MDEventWSWrapper> inWSWrapper)
Expand All @@ -74,13 +77,21 @@ class ConvertToMDEvensEventWSAutoRebin: public IConvertToMDEventsMethods
// initiate the templated class which does the conversion of workspace data into MD WS coordinates;
trn.setUP(this);

pEventWS = boost::static_pointer_cast<const DataObjects::EventWorkspace>(inWS2D);
if(!pEventWS.get()){
throw(std::logic_error(" ConvertToMDEvensEventWSAutoRebin should work with defined event workspace"));
}

return numSpec;
}

void runConversion(API::Progress *pProg)
{
DataObjects::EventWorkspace_const_sptr pEventWS = boost::static_pointer_cast<const DataObjects::EventWorkspace>(inWS2D);


// get box controller which will deal with box splitting
Mantid::API::BoxController_sptr bc = pWSWrapper->pWorkspace()->getBoxController();
size_t lastNumBoxes = bc->getTotalNumMDBoxes();

// counder for the number of events
size_t n_added_events(0);

Expand Down Expand Up @@ -109,7 +120,7 @@ class ConvertToMDEvensEventWSAutoRebin: public IConvertToMDEventsMethods
for (size_t wi=0; wi < nValidSpectra; wi++)
{
size_t iSpec = pDetLoc->detIDMap[wi];
int32_t det_id = pDetLoc->det_id[wi];
int32_t det_id = pDetLoc->det_id[wi];

const DataObjects::EventList & el = pEventWS->getEventList(iSpec);
//size_t numEvents = el.getNumberEvents();
Expand All @@ -118,7 +129,9 @@ class ConvertToMDEvensEventWSAutoRebin: public IConvertToMDEventsMethods
const MantidVec& X = el.dataX();
const MantidVec& Signal = el.dataY();
const MantidVec& Error = el.dataE();
if(!trn.calcYDepCoordinates(Coord,ic))continue; // skip y outsize of the range;

// calculate the coordinatew which depend on detector position only
if(!trn.calcYDepCoordinates(Coord,wi))continue; // skip y outsize of the range;

//=> START INTERNAL LOOP OVER THE "TIME"
for (size_t j = 0; j < Signal.size(); ++j)
Expand All @@ -127,7 +140,7 @@ class ConvertToMDEvensEventWSAutoRebin: public IConvertToMDEventsMethods
if(Signal[j]<FLT_EPSILON)continue;


if(!trn.calcMatrixCoord(X,iSpec,j,Coord))continue; // skip ND outside the range
if(!trn.calcMatrixCoord(X,i,j,Coord))continue; // skip ND outside the range
// ADD RESULTING EVENTS TO THE WORKSPACE
float ErrSq = float(Error[j]*Error[j]);

Expand All @@ -141,6 +154,7 @@ class ConvertToMDEvensEventWSAutoRebin: public IConvertToMDEventsMethods
n_added_events++;
if(n_added_events>=buf_size){
pWSWrapper->addMDData(sig_err,run_index,det_ids,allCoord,n_added_events);
pWSWrapper->pWorkspace()->splitAllIfNeeded(NULL);

n_added_events=0;
pProg->report(wi);
Expand All @@ -151,12 +165,13 @@ class ConvertToMDEvensEventWSAutoRebin: public IConvertToMDEventsMethods

if(n_added_events>0){
pWSWrapper->addMDData(sig_err,run_index,det_ids,allCoord,n_added_events);
pWSWrapper->pWorkspace()->splitAllIfNeeded(NULL);

n_added_events=0;
}

pWSWrapper->pWorkspace()->refreshCache();
pWSWrapper->pWorkspace()->getBox()->refreshCentroid(NULL);
pWSWrapper->refreshCentroid();
pProg->report();
}

Expand All @@ -173,7 +188,9 @@ class ConvertToMDEvensEventWS: public IConvertToMDEventsMethods
friend struct COORD_TRANSFORMER;
// the instanciation of the class which does the transformation itself
COORD_TRANSFORMER<Q,MODE,ConvFromTOF,Axis> trn;
// vector to keep generic part of event workspaces
// the pointer to underlying event workspace
DataObjects::EventWorkspace_sptr pEventWS;
// vector to keep generic part of event coordinates
std::vector<coord_t> Coord;
// index of current run(workspace) for MD WS combining
uint16_t runIndex;
Expand All @@ -188,16 +205,23 @@ class ConvertToMDEvensEventWS: public IConvertToMDEventsMethods
// allocate space for single MDEvent coordinates with common coordinates which would propagate everywhere
Coord.resize(this->n_dims);

pEventWS = boost::dynamic_pointer_cast<DataObjects::EventWorkspace>(inWS2D);
if(!pEventWS.get()){
throw(std::logic_error(" ConvertToMDEvensEventWS should work with defined event workspace"));
}

return numSpec;
}

void runConversion(API::Progress *pProg)
{
// amount of work
const size_t numSpec = inWS2D->getNumberHistograms();
// Get the box controller
Mantid::API::BoxController_sptr bc = pWSWrapper->pWorkspace()->getBoxController();
size_t lastNumBoxes = bc->getTotalNumMDBoxes();


const size_t specSize = this->inWS2D->blocksize();

size_t nValidSpectra = this->pDetLoc->det_id.size();
// copy experiment info into target workspace
API::ExperimentInfo_sptr ExperimentInfo(inWS2D->cloneExperimentInfo());
Expand All @@ -208,12 +232,11 @@ class ConvertToMDEvensEventWS: public IConvertToMDEventsMethods
// if any property dimension is outside of the data range requested, the job is done;
if(!trn.calcGenericVariables(Coord,this->n_dims))return;

size_t lastNumBoxes = this->pWSWrapper->getBoxController()->getTotalNumMDBoxes();

size_t eventsAdded = 0;
for (size_t wi=0; wi < inWS2D->getNumberHistograms(); wi++)
for (size_t wi=0; wi <nValidSpectra; wi++)
{
size_t iSpec = this->pDetLoc->detIDMap[wi];
int32_t det_id = this->pDetLoc->det_id[wi];

eventsAdded += this->conversionChunk(iSpec);
// Give this task to the scheduler
Expand All @@ -226,7 +249,7 @@ class ConvertToMDEvensEventWS: public IConvertToMDEventsMethods
// tp.joinAll();
// Now do all the splitting tasks
//ws->splitAllIfNeeded(ts);
ws->splitAllIfNeeded(NULL);
pWSWrapper->pWorkspace()->splitAllIfNeeded(NULL);
//if (ts->size() > 0) tp.joinAll();

// Count the new # of boxes.
Expand All @@ -241,16 +264,14 @@ class ConvertToMDEvensEventWS: public IConvertToMDEventsMethods
pWSWrapper->pWorkspace()->splitAllIfNeeded(NULL);
// Recount totals at the end.
pWSWrapper->pWorkspace()->refreshCache();
pWSWrapper->pWorkspace()->getBox()->refreshCentroid(NULL);
pWSWrapper->refreshCentroid();
}
private:
//
virtual size_t conversionChunk(size_t workspaceIndex)
{

Events::EventList & el = this->inWS2D->getEventList(workspaceIndex);
{

switch (el.getEventType())
switch (this->pEventWS->getEventList(workspaceIndex).getEventType())
{
case TOF:
return this->convertEventList<TofEvent>(workspaceIndex);
Expand All @@ -262,24 +283,32 @@ class ConvertToMDEvensEventWS: public IConvertToMDEventsMethods
throw std::runtime_error("EventList had an unexpected data type!");
}
};
// internal function to convert event list:

template <class T>
size_t convertEventList(size_t workspaceIndex)
{
std::vector<coord_t> locCoord(this->Coord);
if(!trn.calcYDepCoordinates(locCoord,workspaceIndex))return; // s

EventList & el = this->inWS2D->getEventList(workspaceIndex);
size_t numEvents = el.getNumberEvents();
uint16_t runIndexLoc = this->runIndex;

// allocate temporary buffer for MD Events data
std::vector<coord_t> allCoord(0); // MD events coordinates buffer
allCoord.reserve(this->n_dims*numEvents);

std::vector<float> sig_err.reserve(2*numEvents); // array for signal and error.
std::vector<uint16_t> run_index.reserve(numEvents); // Buffer run index for each event
std::vector<uint32_t> det_ids.reserve(numEvents); // Buffer of det Id-s for each event
// std::vector<coord_t> locCoord(this->Coord);
// if(!trn.calcYDepCoordinates(locCoord,workspaceIndex))return; // s
//
EventList & el = this->pEventWS->getEventList(workspaceIndex);
size_t numEvents = el.getNumberEvents();
size_t detNum = this->pDetLoc->spec2detMap[workspaceIndex];
uint32_t detID = this->pDetLoc->det_id[detNum];
uint16_t runIndexLoc = this->runIndex;

std::vector<coord_t>locCoord(this->Coord);
// set up unit conversion and calculate up all coordinates, which depend on spectra index only
if(!trn.calcYDepCoordinates(locCoord,detNum))return 0; // skip if any y outsize of the range of interest;
//
// // allocate temporary buffers for MD Events data
// // MD events coordinates buffer
std::vector<coord_t> allCoord;
std::vector<float> sig_err; // array for signal and error.
std::vector<uint16_t> run_index; // Buffer run index for each event
std::vector<uint32_t> det_ids; // Buffer of det Id-s for each event

allCoord.reserve(this->n_dims*numEvents); sig_err.reserve(2*numEvents);
run_index.reserve(numEvents); det_ids.reserve(numEvents);

// This little dance makes the getting vector of events more general (since you can't overload by return type).
typename std::vector<T> * events_ptr;
Expand All @@ -293,14 +322,14 @@ class ConvertToMDEvensEventWS: public IConvertToMDEventsMethods
for (; it != it_end; it++)
{
double tof=it->tof();
if(!trn.calc1MatrixCoord(tof,locCoord))continue; // skip ND outside the range
if(!trn.ConvertAndCalcMatrixCoord(tof,locCoord))continue; // skip ND outside the range

sig_err.push_back(float(it->weight());
sig_err.push_back(float(it->errorSquared());
run_index.push_back(runIndexLoc);
det_ids.push_back(det_id);
allCoord.insert(allCoord.end(),locCoord.begin(),locCoord.end());
}
sig_err.push_back(float(it->weight()));
sig_err.push_back(float(it->errorSquared()));
run_index.push_back(runIndexLoc);
det_ids.push_back(detID);
allCoord.insert(allCoord.end(),locCoord.begin(),locCoord.end());
}

// // Clear out the EventList to save memory
// if (ClearInputWorkspace)
Expand All @@ -313,12 +342,12 @@ class ConvertToMDEvensEventWS: public IConvertToMDEventsMethods
// MemoryManager::Instance().releaseFreeMemoryIfAccumulated(memoryCleared, (size_t)2e8);
// }
//
// // Add them to the MDEW
size_t n_added_events = run_index.size();
pWSWrapper->addMDData(sig_err,run_index,det_ids,allCoord,n_added_events);
// Add them to the MDEW
size_t n_added_events = run_index.size();
pWSWrapper->addMDData(sig_err,run_index,det_ids,allCoord,n_added_events);

return n_added_events;
}
return n_added_events;
}

};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class ConvertToMDEvensHistoWS: public IConvertToMDEventsMethods
// the instanciation of the class which does the transformation itself
COORD_TRANSFORMER<Q,MODE,CONV,Histohram> trn;
// not yet parallel
virtual void conversionChunk(size_t job_ID){}
virtual size_t conversionChunk(size_t job_ID){return 0;}
public:
size_t setUPConversion(Mantid::API::MatrixWorkspace_sptr pWS2D, const PreprocessedDetectors &detLoc,
const MDEvents::MDWSDescription &WSD, boost::shared_ptr<MDEvents::MDEventWSWrapper> inWSWrapper)
Expand Down Expand Up @@ -115,16 +115,16 @@ class ConvertToMDEvensHistoWS: public IConvertToMDEventsMethods
const MantidVec& Signal = inWS2D->readY(iSpctr);
const MantidVec& Error = inWS2D->readE(iSpctr);


if(!trn.calcYDepCoordinates(Coord,ic))continue; // skip y outsize of the range;
// calculate the coordinates which depend on detector posision
if(!trn.calcYDepCoordinates(Coord,i))continue; // skip y outsize of the range;

//=> START INTERNAL LOOP OVER THE "TIME"
for (size_t j = 0; j < specSize; ++j)
{
// drop emtpy events
if(Signal[j]<FLT_EPSILON)continue;

if(!trn.calcMatrixCoord(X,iSpec,j,Coord))continue; // skip ND outside the range
if(!trn.calcMatrixCoord(X,i,j,Coord))continue; // skip ND outside the range
// ADD RESULTING EVENTS TO THE WORKSPACE
float ErrSq = float(Error[j]*Error[j]);

Expand All @@ -137,10 +137,11 @@ class ConvertToMDEvensHistoWS: public IConvertToMDEventsMethods

n_added_events++;
if(n_added_events>=buf_size){
pWSWrapper->addMDData(sig_err,run_index,det_ids,allCoord,n_added_events);

n_added_events=0;
pProg->report(i);
pWSWrapper->addMDData(sig_err,run_index,det_ids,allCoord,n_added_events);
pWSWrapper->pWorkspace()->splitAllIfNeeded(NULL);

n_added_events=0;
pProg->report(i);
}

} // end spectra loop
Expand All @@ -149,12 +150,12 @@ class ConvertToMDEvensHistoWS: public IConvertToMDEventsMethods

if(n_added_events>0){
pWSWrapper->addMDData(sig_err,run_index,det_ids,allCoord,n_added_events);

pWSWrapper->pWorkspace()->splitAllIfNeeded(NULL);
n_added_events=0;
}

pWSWrapper->pWorkspace()->refreshCache();
pWSWrapper->pWorkspace()->getBox()->refreshCentroid(NULL);
pWSWrapper->refreshCentroid();
pProg->report();
}
};
Expand Down

0 comments on commit a0c1397

Please sign in to comment.