Skip to content

Commit

Permalink
refs #4201 Finished separating MDWventWS factory and conversion code
Browse files Browse the repository at this point in the history
  • Loading branch information
abuts committed Jan 2, 2012
1 parent 3763b81 commit d233f21
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,28 +50,33 @@ ConvertToMDEvents::processQND(API::IMDEventWorkspace *const piWS)
const size_t numSpec = inWS2D->getNumberHistograms();
// progress reporter
pProg = std::auto_ptr<API::Progress>(new API::Progress(this,0.0,1.0,numSpec));




// initiate the class which is does the conversion of workspace data into MD WS coordinates;
COORD_TRANSFORMER<Q,MODE,CONV> trn(this);
// one of the dimensions has to be X-ws dimension -> need to add check for that;

// copy experiment info into target workspace
API::ExperimentInfo_sptr ExperimentInfo(inWS2D->cloneExperimentInfo());
uint16_t runIndex = this->pWSWrapper->workspace->addExperimentInfo(ExperimentInfo);
// run index;
uint16_t runIndex = this->pWSWrapper->pWorkspace()->addExperimentInfo(ExperimentInfo);
// number of dimesnions
size_t n_dims = this->pWSWrapper->nDimensions();


const size_t specSize = this->inWS2D->blocksize();
size_t nValidSpectra = det_loc.det_id.size();

// take at least bufSize for efficiency
size_t buf_size = ((specSize>SPLIT_LEVEL)?specSize:SPLIT_LEVEL);
std::vector<coord_t> Coord(nd*buf_size);
std::vector<coord_t> allCoord(n_dims*buf_size);
std::vector<coord_t> Coord(n_dims);
std::vector<float> sig_err(2*buf_size);
std::vector<uint16_t> run_index(buf_size);
std::vector<uint32_t> det_id(buf_size);
std::vector<uint32_t> det_ids(buf_size);


if(!trn.calcGenericVariables(Coord,nd))return; // if any property dimension is outside of the data range requested
if(!trn.calcGenericVariables(Coord,n_dims))return; // if any property dimension is outside of the data range requested
//External loop over the spectra:
for (int64_t i = 0; i < int64_t(nValidSpectra); ++i)
{
Expand All @@ -95,19 +100,25 @@ ConvertToMDEvents::processQND(API::IMDEventWorkspace *const piWS)
// ADD RESULTING EVENTS TO THE WORKSPACE
float ErrSq = float(Error[j]*Error[j]);

//pWs->addEvent(MDEvents::MDEvent<nd>(float(Signal[j]),ErrSq,runIndex,det_id,&Coord[0]));
// coppy all data into data buffer for future transformation into events;
sig_err[2*n_added_events+0]=float(Signal[j]);
sig_err[2*n_added_events+1]=ErrSq;
run_index[n_added_events] = runIndex;
det_ids[n_added_events] = det_id;
allCoord.insert(allCoord.end(),Coord.begin(),Coord.end());

n_added_events++;
} // end spectra loop
if(n_added_events>SPLIT_LEVEL){
pWSWrapper->addMDData(sig_err,run_index,det_id,Coord,n_added_events);
pWSWrapper->addMDData(sig_err,run_index,det_ids,allCoord,n_added_events);

n_added_events=0;
pProg->report(i);
}
} // end detectors loop;


// pWs->refreshCache();
pWSWrapper->refreshCache();
pProg->report();

}
Expand Down
16 changes: 7 additions & 9 deletions Code/Mantid/Framework/MDAlgorithms/src/ConvertToMDEvents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ void ConvertToMDEvents::exec(){
setProperty("OutputWorkspace", boost::dynamic_pointer_cast<IMDEventWorkspace>(spws));

// free the algorithm from the responsibility for the workspace to allow it to be deleted if necessary
pWSWrapper->release_workspace();
pWSWrapper->releaseWorkspace();
return;

}
Expand Down Expand Up @@ -574,9 +574,9 @@ ConvertToMDEvents::parseQMode(const std::string &Q_mode_req,const Strings &ws_di
return Q_MODE_ID;
}

/** function processes the input arguments and tries to establish what algorithm should be deployed;
/** function processes the input arguments and tries to establish what subalgorithm should be deployed;
*
* @param inWS -- input workspace (2D or Events)
* @param inWS -- input workspace (2D or Events)
* @param Q_mode_req -- what to do with Q-dimensions e.g. calculate either mod|Q| or Q3D;
* @param dE_mode_req -- desirable dE analysis mode (elastic, direct/indirect)
* @param dim_requested -- vector of other dimension names requested by the algorithm
Expand Down Expand Up @@ -631,24 +631,22 @@ ConvertToMDEvents::identifyTheAlg(API::MatrixWorkspace_const_sptr inWS,const std
convert_log.error()<<"Algorithm with ID:"<<the_algID<<" should produce at least 3 dimensions and it requested to provie just:"<<nDims<<" dims \n";
throw(std::logic_error("can not parse input parameters propertly"));
}
// we have currenlty instanciated only 8 input dimensions. See algorithm constructor to change that.
if(nDims>8){
convert_log.error()<<"Can not currently produce more then 8 dimesnions, requested: "<<nDims<<std::endl;
// we have currenlty instanciated only N input dimensions. See algorithm constructor to change that.
if(nDims>pWSWrapper->getMaxNDim()){
convert_log.error()<<"Can not currently deal with more then: "<<pWSWrapper->getMaxNDim()<< " dimesnions, but requested: "<<nDims<<std::endl;
throw(std::invalid_argument(" Too many dimensions requested "));
}

// any inelastic mode or unit conversion involing TOF needs Ei to be among the input workspace properties
int emode = getEMode(this);
if((emode == 1)||(emode == 2)||(the_algID.find("TOD")!=std::string::npos))
if((emode == 1)||(emode == 2)||(the_algID.find("TOF")!=std::string::npos))
{
if(!inWS->run().hasProperty("Ei")){
convert_log.error()<<" Conversion sub-algorithm with ID: "<<the_algID<<" needs input energy to be present among run properties\n";
throw(std::invalid_argument(" Needs Input energy to be present "));
}
}

//TODO: temporary, we will redefine the algorithm ID not to depend on dimension number in a future
the_algID = the_algID+boost::lexical_cast<std::string>(nDims);
this->n_activated_dimensions = nDims;

return the_algID;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ class DLLExport MDEventWSWrapper
public:
MDEventWSWrapper();
virtual ~MDEventWSWrapper(){};
/// get maximal number of dimensions, allowed for the algorithm and embedded in algorithm during compilation time.
static size_t getMaxNDim(){return MAX_N_DIM;}

/// get number of dimensions, for the workspace, currently accessed by the algorithm.
size_t nDimensions()const;
/** function creates empty MD event workspace with given parameters (workspace factory) and stores internal pointer to this workspace for further usage */
API::IMDEventWorkspace_sptr createEmptyMDWS(size_t n_dim, const Strings &targ_dim_names,const Strings &targ_dim_units,
Expand All @@ -64,9 +67,11 @@ class DLLExport MDEventWSWrapper
//****> the methods below provide the equivalent of vftable for MDEvent workspace write interface.
// It should probably be moved to that interface if no substantial performance loss is identified (and seems there are no)
/// to access to splitBox method of multidimensional workspace
void splitBox();
void splitBox(){boxSplitter[n_dimensions](this);}
/** returns the MDevent ws box controller for access and modifications */
Mantid::API::BoxController_sptr getBoxController(){return workspace->getBoxController();}
/// refresh cash on md event workspace
void refreshCache(){ cashRefresher[n_dimensions](this);}
private:
/// maximal nuber of dimensions, currently supported by the class;
static const int MAX_N_DIM=8;
Expand Down Expand Up @@ -101,6 +106,9 @@ class DLLExport MDEventWSWrapper
std::vector<fpVoidMethod> mdEvSummator;
/// vecor holding pointers to the box splitting code
std::vector<fpVoidMethod> boxSplitter;
/// vecor holding pointers to the box splitting code
std::vector<fpVoidMethod> cashRefresher;

/// helper function to create empty MDEventWorkspace with nd dimensions
template<size_t nd>
void createEmptyEventWS(void)
Expand Down Expand Up @@ -159,6 +167,16 @@ class DLLExport MDEventWSWrapper
}
pWs->splitBox();
}
/// template to access refresh cash method on MD workspace
template<size_t nd>
void refresh_Cache(){
MDEvents::MDEventWorkspace<MDEvents::MDEvent<nd>,nd> *const pWs = dynamic_cast<MDEvents::MDEventWorkspace<MDEvents::MDEvent<nd>,nd> *>(this->workspace.get());
if(!pWs){
g_log.error()<<"MDEventWSWrapper: can not cast worspace pointer into pointer to proper target workspace\n";
throw(std::bad_cast());
}
pWs->refreshCache();
}

/// function called if the workspace has not been initated;
void throwNotInitiatedError();
Expand Down
14 changes: 10 additions & 4 deletions Code/Mantid/Framework/MDEvents/src/MDEventWSWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ MDEventWSWrapper::createEmptyMDWS(size_t n_dim, const Strings &targ_dim_names,co

return workspace;
}

/// method adds the data to the workspace which was initiated before;
void
MDEventWSWrapper::addMDData(std::vector<float> &sig_err,std::vector<uint16_t> &run_index,std::vector<uint32_t> &det_id,std::vector<coord_t> &Coord,size_t data_size)
Expand Down Expand Up @@ -95,20 +96,24 @@ class LOOP{
fpVoidMethod fp1 = &MDEventWSWrapper::add_MDData<i>;
pH->mdEvSummator[i] = fp1;

// pure vftable definition
// vftable definition
fpVoidMethod fp2 = &MDEventWSWrapper::split_Box<i>;
pH->boxSplitter[i] = fp2;

fpVoidMethod fp3 = &MDEventWSWrapper::refresh_Cache<i>;
pH->cashRefresher[i] = fp3;

}
};
template<>
class LOOP<0>{
public:
static inline void EXEC(MDEventWSWrapper *pH){
fpVoidMethod fp = &MDEventWSWrapper::throwNotInitiatedError;
pH->wsCreator[0] = fp;
pH->mdEvSummator[0]= fp;
pH->boxSplitter[0] = fp;
pH->wsCreator[0] = fp;
pH->mdEvSummator[0] = fp;
pH->boxSplitter[0] = fp;
pH->cashRefresher[0]= fp;
}
};

Expand All @@ -117,6 +122,7 @@ MDEventWSWrapper::MDEventWSWrapper():n_dimensions(0)
wsCreator.resize(MAX_N_DIM+1);
mdEvSummator.resize(MAX_N_DIM+1);
boxSplitter.resize(MAX_N_DIM+1);
cashRefresher.resize(MAX_N_DIM+1);
LOOP<MAX_N_DIM>::EXEC(this);
}

Expand Down

0 comments on commit d233f21

Please sign in to comment.