@@ -5,31 +5,30 @@ namespace Mantid
{
namespace MDEvents
{
// register the class, whith conversion factory
// register the class, whith conversion factory under ModQ name
DECLARE_MD_TRANSFID(MDTransfModQ,ModQ);

const std::string MDTransfModQ::inputUnitID()const
/** method calculates the unigs, the transformation expects input ws to be in. If input ws is in different units,
the WS data will be converted into the units requested on-fly.
*/
const std::string MDTransfModQ::inputUnitID(ConvertToMD::EModes dEmode, API::MatrixWorkspace_const_sptr inWS)const
{
if (emode == ConvertToMD::Elastic){
return "Momentum";
}else{
UNUSED_ARG(inWS);
switch(dEmode)
{
case(ConvertToMD::Elastic): return "Momentum";
case(ConvertToMD::Direct):
case(ConvertToMD::Indir):
return "DeltaE";
default:
throw(std::invalid_argument(" MDTransfModQ::inputUnitID: this class supports only conversion in Elastic and Inelastic energy transfer modes"));
}
}

bool MDTransfModQ::calcMatrixCoord(const double& x,std::vector<coord_t> &Coord)const
{
if(emode == ConvertToMD::Elastic){
return calcMatrixCoordElastic(x,Coord);
}else{
return calcMatrixCoordInelastic(x,Coord);
}
}
/** function returns number of matrix dimensions calculated by this class
* as function of energy analysis mode
*/
unsigned int MDTransfModQ::getNMatrixDimensions(ConvertToMD::EModes mode)const
/** method returns number of matrix dimensions calculated by this class
* as function of energy analysis mode */
unsigned int MDTransfModQ::getNMatrixDimensions(ConvertToMD::EModes mode,API::MatrixWorkspace_const_sptr inWS)const
{
UNUSED_ARG(inWS);
switch(mode)
{
case(ConvertToMD::Direct): return 2;
@@ -39,8 +38,19 @@ unsigned int MDTransfModQ::getNMatrixDimensions(ConvertToMD::EModes mode)const
}
}



bool MDTransfModQ::calcMatrixCoord(const double& x,std::vector<coord_t> &Coord)const
{
if(emode == ConvertToMD::Elastic){
return calcMatrixCoordElastic(x,Coord);
}else{
return calcMatrixCoordInelastic(x,Coord);
}
}

/** Method fills-in all additional properties requested by user and not defined by matrix workspace itselt.
* it fills in nd - (1 or 2 -- depending on emode) values into Coord vector;
* it fills in [nd - (1 or 2 -- depending on emode)] values into Coord vector;
*
*@param Coord -- input-output vector of MD-coordinates
*@param nd -- number of current dimensions
@@ -49,6 +59,15 @@ unsigned int MDTransfModQ::getNMatrixDimensions(ConvertToMD::EModes mode)const
*/
bool MDTransfModQ::calcGenericVariables(std::vector<coord_t> &Coord, size_t nd)
{
// sanity check. If fails, something went fundamentally wrong
if(nMatrixDim+addDimCoordinates.size()!=nd)
{
std::string ERR="Number of matrix dimensions: "+boost::lexical_cast<std::string>(nMatrixDim)+
" plus number of additional dimensions: "+boost::lexical_cast<std::string>(addDimCoordinates.size())+
" not equal to number of workspace dimensions: "+boost::lexical_cast<std::string>(nd);
throw(std::invalid_argument(ERR));
}

// in Elastic case, 1 coordinate (|Q|) came from workspace
// in inelastic 2 coordinates (|Q| dE) came from workspace. All other are defined by properties.
// nMatrixDim is either 1 in elastic case or 2 in inelastic
@@ -166,7 +185,7 @@ void MDTransfModQ::initialize(const MDWSDescription &ConvParams)
" is more or equal then Max Q^2 value: "+boost::lexical_cast<std::string>(dim_max[0]);
throw(std::invalid_argument(ERR));
}

this->addDimCoordinates = ConvParams.getAddCoord();

//************ specific part of the initialization, dependent on emode:
emode = ConvParams.getEMode();
@@ -190,8 +209,9 @@ void MDTransfModQ::initialize(const MDWSDescription &ConvParams)
*@returns -- vector of default dimension ID-s for correspondent energy conversion mode.
The position of each dimID in the vector corresponds to the position of each MD coordinate in the Coord vector
*/
std::vector<std::string> MDTransfModQ::getDefaultDimID(ConvertToMD::EModes dEmode)const
std::vector<std::string> MDTransfModQ::getDefaultDimID(ConvertToMD::EModes dEmode, API::MatrixWorkspace_const_sptr inWS)const
{
UNUSED_ARG(inWS);
std::vector<std::string> default_dim_ID;
switch(dEmode)
{
@@ -220,9 +240,10 @@ std::vector<std::string> MDTransfModQ::getDefaultDimID(ConvertToMD::EModes dEmod
* @param Emode -- energy conversion mode
*
* It is Momentum and DelteE in inelastic modes */
std::vector<std::string> MDTransfModQ::outputUnitID(ConvertToMD::EModes dEmode)const
std::vector<std::string> MDTransfModQ::outputUnitID(ConvertToMD::EModes dEmode, API::MatrixWorkspace_const_sptr inWS)const
{
std::vector<std::string> UnitID = MDTransfModQ::getDefaultDimID(dEmode);
UNUSED_ARG(inWS);
std::vector<std::string> UnitID = MDTransfModQ::getDefaultDimID(dEmode,inWS);
//TODO: is it really momentum transfer, as MomentumTransfer units are seems bound to elastic mode only (at least accorting to Units description on Wiki)?
UnitID[0] = "MomentumTransfer";
return UnitID;
@@ -234,7 +255,6 @@ MDTransfModQ::MDTransfModQ():
pDet(NULL),
nMatrixDim(-1)
{

}

} // End MDAlgorighms namespace
@@ -0,0 +1,125 @@
#include "MantidMDEvents/MDTransfNoQ.h"
//
namespace Mantid
{
namespace MDEvents
{

// register the class, whith conversion factory under NoQ name
DECLARE_MD_TRANSFID(MDTransfNoQ,NoQ);

/** Method fills-in all additional properties requested by user and not defined by matrix workspace itselt.
* it fills in [nd - (1 or 2 -- depending on input ws)] values into the Coord vector;
*
*@param Coord -- input-output vector of MD-coordinates
*@param nd -- number of current dimensions
*
*@returns -- Coord vector with nd-(1 or 2, depending on input ws) values of MD coordinates
*/
bool MDTransfNoQ::calcGenericVariables(std::vector<coord_t> &Coord, size_t nd)
{
// sanity check. If fails, something went fundamentally wrong
if(nMatrixDim+addDimCoordinates.size()!=nd)
{
std::string ERR="Number of matrix dimensions: "+boost::lexical_cast<std::string>(nMatrixDim)+
" plus number of additional dimensions: "+boost::lexical_cast<std::string>(addDimCoordinates.size())+
" not equal to number of workspace dimensions: "+boost::lexical_cast<std::string>(nd);
throw(std::invalid_argument(ERR));
}
// if one axis is numeric, 1 coordinate came from workspace
// if two axis are numeric, two values come from the ws. All other are defined by properties.
unsigned int ic(0);
for(unsigned int i=nMatrixDim;i<nd;i++){
if(addDimCoordinates[ic]<dim_min[i] || addDimCoordinates[ic]>=dim_max[i])return false;
Coord[i]= addDimCoordinates[ic];
ic++;
}
return true;
}
void MDTransfNoQ::initialize(const MDWSDescription &ConvParams)
{

// get pointer to the positions of the detectors
std::vector<Kernel::V3D> const & DetDir = ConvParams.getDetectors()->getDetDir();
pDet = &DetDir[0]; //

// get min and max values defined by the algorithm.
ConvParams.getMinMax(dim_min,dim_max);

nMatrixDim = getNMatrixDimensions(ConvertToMD::Undef,ConvParams.getInWS());
this->addDimCoordinates = ConvParams.getAddCoord();

}

//// SPECIALIZATIONS:
////----------------------------------------------------------------------------------------------------------------------
//// ----> NoQ
//// NoQ,ANY_Mode -- no units conversion. This templates just copies the data into MD events and not doing any momentum transformations
////
//#ifndef EXCLUDE_Q_TRANSFORMATION_NOQ
//template<ConvertToMD::AnalMode MODE,ConvertToMD::CnvrtUnits CONV,ConvertToMD::XCoordType TYPE,ConvertToMD::SampleType SAMPLE>
//struct CoordTransformer<ConvertToMD::NoQ,MODE,CONV,TYPE,SAMPLE>
//{
// inline bool calcGenericVariables(std::vector<coord_t> &Coord, size_t nd)
// {
// // get optional Y axis which can be used in NoQ-kind of algorithms
// pYAxis = pHost->getPAxis(1);
// if(pYAxis){ // two inital properties came from workspace. All are independant; All other dimensions are obtained from properties
// if(!pHost->fillAddProperties(Coord,nd,2))return false;
// }else{ // only one workspace property availible;
// if(!pHost->fillAddProperties(Coord,nd,1))return false;
// }
// //
// pHost->getMinMax(dim_min,dim_max);
// // set up units conversion defined by the host algorithm.
// ConvToMDPreprocDetectors Dummy;
// CONV_UNITS_FROM.setUpConversion(Dummy,"","");
// return true;
// }
//
// inline bool calcYDepCoordinates(std::vector<coord_t> &Coord,size_t i)
// {
// CONV_UNITS_FROM.updateConversion(i);
// if(pYAxis){
// if(Coord[1]<dim_min[1]||Coord[1]>=dim_max[1])return false;
// Coord[1] = (coord_t)(pYAxis->operator()(i));
// }
// return true;
// }
//
// inline bool calc1MatrixCoord(const double& X,std::vector<coord_t> &Coord)const
// {
// if(X<dim_min[0]||X>=dim_max[0])return false;
//
// Coord[0]=(coord_t)X;
// return true;
// }
// // should be actually on ICoordTransformer but there is problem with template-overloaded functions
// inline bool calcMatrixCoord(const MantidVec& X,size_t i,size_t j,std::vector<coord_t> &Coord)const
// {
// UNUSED_ARG(i);
// double X_ev = CONV_UNITS_FROM.getXConverted(X,j);
//
// return calc1MatrixCoord(X_ev,Coord);
// }
// inline bool convertAndCalcMatrixCoord(const double & X,std::vector<coord_t> &Coord)const
// {
// double X_ev = CONV_UNITS_FROM.getXConverted(X);
// return calc1MatrixCoord(X_ev,Coord);
// }
//
// // constructor;
// CoordTransformer():pYAxis(NULL),pHost(NULL){}
//
// inline void setUpTransf(IConvertToMDEventsWS *pConv){
// pHost = pConv;
// }
//private:
//// class which would convert units
// UnitsConverter<CONV,TYPE> CONV_UNITS_FROM;
//};

//
} // End MDAlgorighms namespace
} // End Mantid namespace

@@ -55,6 +55,7 @@ void MDWSDescription::setDetectors(const ConvToMDPreprocDet &det_loc)
void MDWSDescription::buildFromMatrixWS(const API::MatrixWorkspace_const_sptr &pWS,const std::string &QMode,const std::string dEMode,
const std::vector<std::string> &dimProperyNames,size_t maxNdims)
{
inWS = pWS;
// fill additional dimensions values, defined by workspace properties;
this->fillAddProperties(pWS,dimProperyNames,AddCoord);

@@ -68,7 +69,7 @@ void MDWSDescription::buildFromMatrixWS(const API::MatrixWorkspace_const_sptr &p
MDTransfInterface* pQtransf = MDTransfFactory::Instance().create(QMode).get();

// get number of dimensions this Q transformation generates from the workspace.
unsigned int nMatrixDim = pQtransf->getNMatrixDimensions(emode);
unsigned int nMatrixDim = pQtransf->getNMatrixDimensions(emode,inWS);

// number of MD ws dimensions is the sum of n-matrix dimensions and dimensions coming from additional coordinates
nDims = nMatrixDim + (unsigned int)AddCoord.size();
@@ -86,8 +87,8 @@ void MDWSDescription::buildFromMatrixWS(const API::MatrixWorkspace_const_sptr &p

//*********** fill in dimension id-s, dimension units and dimension names
// get default dim ID-s. TODO: it should be possibility to owerride it later;
std::vector<std::string> MatrDimID = pQtransf->getDefaultDimID(emode);
std::vector<std::string> MatrUnitID = pQtransf->outputUnitID(emode);
std::vector<std::string> MatrDimID = pQtransf->getDefaultDimID(emode,inWS);
std::vector<std::string> MatrUnitID = pQtransf->outputUnitID(emode,inWS);
for(unsigned int i=0;i<nDims;i++)
{
if(i<nMatrixDim){
@@ -102,7 +103,7 @@ void MDWSDescription::buildFromMatrixWS(const API::MatrixWorkspace_const_sptr &p
}

// get input energy
this->Ei = getEi(pWS);
this->Ei = getEi(inWS);
// in direct or indirect mode input ws has to have input energy
if(emode==ConvertToMD::Direct||emode==ConvertToMD::Indir){
if(isNaN(Ei))throw(std::invalid_argument("Input neutron's energy has to be defined in inelastic mode "));
@@ -116,11 +117,11 @@ void MDWSDescription::buildFromMatrixWS(const API::MatrixWorkspace_const_sptr &p
this->pLatt.reset();
}
//Set up goniometer. Empty ws's goniometer returns unit transformation matrix
this->GoniomMatr = pWS->run().getGoniometer().getR();
this->GoniomMatr = inWS->run().getGoniometer().getR();

// check if the detector information is still present in MD workspace
detInfoLost = false;
API::NumericAxis *pYAxis = dynamic_cast<API::NumericAxis *>(pWS->getAxis(1));
API::NumericAxis *pYAxis = dynamic_cast<API::NumericAxis *>(inWS->getAxis(1));
if(pYAxis){
// if this is numeric axis, then the detector's information has been lost:
detInfoLost=true;
@@ -238,6 +239,7 @@ void MDWSDescription::compareDescriptions(MDEvents::MDWSDescription &NewMDWorks
*/
void MDWSDescription::setUpMissingParameters(const MDEvents::MDWSDescription &SourceMDWSDescr)
{
this->inWS = SourceMDWSDescr.inWS;
this->emode = SourceMDWSDescr.emode;
this->Ei = SourceMDWSDescr.Ei;
this->AlgID = SourceMDWSDescr.AlgID;