Skip to content

Commit

Permalink
Refs #4939 added tests, using MDEvent instead of MDLeanEvent
Browse files Browse the repository at this point in the history
  • Loading branch information
Janik Zikovsky committed Mar 8, 2012
1 parent 0d739ab commit 7deeed1
Show file tree
Hide file tree
Showing 4 changed files with 238 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@

#include "MantidKernel/System.h"
#include "MantidAPI/Algorithm.h"
#include "MantidMDEvents/BoxControllerSettingsAlgorithm.h"
#include "MantidDataObjects/EventWorkspace.h"
#include "MantidGeometry/Instrument/RectangularDetector.h"
#include "MantidMDEvents/BoxControllerSettingsAlgorithm.h"
#include "MantidMDEvents/MDEventWorkspace.h"
#include "MantidMDEvents/MDLeanEvent.h"

using Mantid::MDEvents::MDLeanEvent;

namespace Mantid
{
namespace MDAlgorithms
Expand Down Expand Up @@ -56,9 +55,12 @@ namespace MDAlgorithms
void init();
void exec();

std::map<int, Geometry::RectangularDetector_const_sptr> getBanks();

template <class T, class MDE, size_t nd>
void convertEventList(boost::shared_ptr<Mantid::MDEvents::MDEventWorkspace<MDE, nd>> outWS,
size_t workspaceIndex, coord_t x, coord_t y, coord_t bankNum);
size_t workspaceIndex, coord_t x, coord_t y, coord_t bankNum,
uint16_t runIndex, int32_t detectorID);

/// The input event workspace
Mantid::DataObjects::EventWorkspace_sptr in_ws;
Expand Down
144 changes: 101 additions & 43 deletions Code/Mantid/Framework/MDAlgorithms/src/ConvertToDetectorFaceMD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,13 @@ namespace MDAlgorithms
* @param x :: x-coordinate for all output events
* @param y :: y-coordinate for all output events
* @param bankNum :: coordinate for the 4th dimension (optional)
* @param detectorID :: detectorID for this event list
* @param runIndex :: index of the run, starting at 0
*/
template <class T, class MDE, size_t nd>
void ConvertToDetectorFaceMD::convertEventList(boost::shared_ptr<Mantid::MDEvents::MDEventWorkspace<MDE, nd>> outWS,
size_t workspaceIndex, coord_t x, coord_t y, coord_t bankNum)
size_t workspaceIndex, coord_t x, coord_t y, coord_t bankNum,
uint16_t runIndex, int32_t detectorID)
{
EventList & el = in_ws->getEventList(workspaceIndex);

Expand All @@ -118,21 +121,86 @@ namespace MDAlgorithms
if (nd == 3)
{
coord_t center[3] = {x, y, tof};
out_events.push_back( MDE(float(it->weight()), float(it->errorSquared()), center) );
out_events.push_back( MDE(float(it->weight()), float(it->errorSquared()), runIndex, detectorID, center) );
}
else if (nd == 4)
{
coord_t center[4] = {x, y, tof, bankNum};
out_events.push_back( MDE(float(it->weight()), float(it->errorSquared()), center) );
out_events.push_back( MDE(float(it->weight()), float(it->errorSquared()), runIndex, detectorID, center) );
}
//TODO: 4D
}

// Add them to the MDEW
outWS->addEvents(out_events);
}



//----------------------------------------------------------------------------------------------
/** Get the list of banks, given the settings
*
* @return map with key = bank number; value = pointer to the rectangular detector
*/
std::map<int, RectangularDetector_const_sptr> ConvertToDetectorFaceMD::getBanks()
{
Instrument_const_sptr inst = in_ws->getInstrument();

std::vector<int> bankNums = this->getProperty("BankNumbers");
std::sort(bankNums.begin(), bankNums.end());

std::map<int, RectangularDetector_const_sptr> banks;

if (bankNums.empty())
{
// --- Find all rectangular detectors ----
// Get all children
std::vector<IComponent_const_sptr> comps;
inst->getChildren(comps, true);

for (size_t i=0; i<comps.size(); i++)
{
// Retrieve it
RectangularDetector_const_sptr det = boost::dynamic_pointer_cast<const RectangularDetector>(comps[i]);
if (det)
{
std::string name = det->getName();
if (name.size() < 5) continue;
std::string bank = name.substr(4,name.size()-4);
int bankNum;
if (Mantid::Kernel::Strings::convert(bank, bankNum))
banks[bankNum] = det;
g_log.debug() << "Found bank " << bank << "." << std::endl;
}
}
}
else
{
// -- Find detectors using the numbers given ---
for (auto bankNum = bankNums.begin(); bankNum != bankNums.end(); bankNum++)
{
std::string bankName = "bank" + Mantid::Kernel::Strings::toString(*bankNum);
IComponent_const_sptr comp = inst->getComponentByName(bankName);
RectangularDetector_const_sptr det = boost::dynamic_pointer_cast<const RectangularDetector>(comp);
if (det)
banks[*bankNum] = det;
}
}

for (auto bank = banks.begin(); bank != banks.end(); bank++)
{
RectangularDetector_const_sptr det = bank->second;
// Track the largest detector
if (det->xpixels() > m_numXPixels) m_numXPixels = det->xpixels();
if (det->ypixels() > m_numYPixels) m_numYPixels = det->ypixels();
}

if (banks.size() == 0)
throw std::runtime_error("No RectangularDetectors with a name like 'bankXX' found in the instrument.");

return banks;
}


//----------------------------------------------------------------------------------------------
/** Execute the algorithm.
*/
Expand All @@ -148,35 +216,21 @@ namespace MDAlgorithms
// Fill the map, throw if there are grouped pixels.
in_ws->getDetectorIDToWorkspaceIndexVector(m_detID_to_WI, m_detID_to_WI_offset, true);

std::vector<int> bankNums = this->getProperty("BankNumbers");
std::sort(bankNums.begin(), bankNums.end());
Instrument_const_sptr inst = in_ws->getInstrument();

std::map<int, RectangularDetector_const_sptr> banks;
for (auto bankNum = bankNums.begin(); bankNum != bankNums.end(); bankNum++)
{
std::string bankName = "bank" + Mantid::Kernel::Strings::toString(*bankNum);
IComponent_const_sptr comp = inst->getComponentByName(bankName);
RectangularDetector_const_sptr det = boost::dynamic_pointer_cast<const RectangularDetector>(comp);
if (det)
{
// Track the largest detector
if (det->xpixels() > m_numXPixels) m_numXPixels = det->xpixels();
if (det->ypixels() > m_numYPixels) m_numYPixels = det->ypixels();
banks[*bankNum] = det;
}
}
// Get the map of the banks we'll display
std::map<int, RectangularDetector_const_sptr> banks = this->getBanks();

// Find the size in the TOF dimension
double tof_min, tof_max;
Axis * ax0 = in_ws->getAxis(0);
in_ws->getXMinMax(tof_min, tof_max);
if (ax0->getValue(0) < tof_min) tof_min = ax0->getValue(0);
if (ax0->getValue(ax0->length()-1) > tof_max) tof_max = ax0->getValue(ax0->length()-1);

// ------------------ Build all the dimensions ----------------------------
MDHistoDimension_sptr dimX(new MDHistoDimension("x", "x", "pixel",
static_cast<coord_t>(0), static_cast<coord_t>(m_numXPixels), m_numXPixels));
MDHistoDimension_sptr dimY(new MDHistoDimension("y", "y", "pixel",
static_cast<coord_t>(0), static_cast<coord_t>(m_numYPixels), m_numYPixels));
Axis * ax0 = in_ws->getAxis(0);
std::string TOFname = ax0->title();
if (TOFname.empty()) TOFname = ax0->unit()->unitID();
MDHistoDimension_sptr dimTOF(new MDHistoDimension(TOFname, TOFname, ax0->unit()->label(),
Expand All @@ -187,29 +241,35 @@ namespace MDAlgorithms
dims.push_back(dimY);
dims.push_back(dimTOF);

if (bankNums.size() > 1)
if (banks.size() > 1)
{
int min = bankNums.front();
int max = bankNums.back()+1;
MDHistoDimension_sptr dimBanks(new MDHistoDimension("bank", "bank", "Bank Number",
int min = banks.begin()->first;
int max = banks.rbegin()->first+1;
MDHistoDimension_sptr dimBanks(new MDHistoDimension("bank", "bank", "number",
static_cast<coord_t>( min ), static_cast<coord_t>( max ), max-min));
dims.push_back(dimBanks);
}

// Create the workspace with the right number of dimensions
// --------- Create the workspace with the right number of dimensions ----------
size_t nd = dims.size();
IMDEventWorkspace_sptr outWS = MDEventFactory::CreateMDWorkspace(nd, "MDLeanEvent");
IMDEventWorkspace_sptr outWS = MDEventFactory::CreateMDWorkspace(nd, "MDEvent");
outWS->initGeometry(dims);
outWS->initialize();
this->setBoxController(outWS->getBoxController());
outWS->splitBox();

MDEventWorkspace3Lean::sptr outWS3 = boost::dynamic_pointer_cast<MDEventWorkspace3Lean>(outWS);
MDEventWorkspace4Lean::sptr outWS4 = boost::dynamic_pointer_cast<MDEventWorkspace4Lean>(outWS);
MDEventWorkspace3::sptr outWS3 = boost::dynamic_pointer_cast<MDEventWorkspace3>(outWS);
MDEventWorkspace4::sptr outWS4 = boost::dynamic_pointer_cast<MDEventWorkspace4>(outWS);

// Copy ExperimentInfo (instrument, run, sample) to the output WS
ExperimentInfo_sptr ei(in_ws->cloneExperimentInfo());
uint16_t runIndex = outWS->addExperimentInfo(ei);

for (auto bankNum = bankNums.begin(); bankNum != bankNums.end(); bankNum++)
// ---------------- Convert each bank --------------------------------------
for (auto it = banks.begin(); it != banks.end(); it++)
{
RectangularDetector_const_sptr det = banks[*bankNum];
int bankNum = it->first;
RectangularDetector_const_sptr det = it->second;
for (int x=0; x<det->xpixels(); x++)
for (int y=0; y<det->ypixels(); y++)
{
Expand All @@ -221,7 +281,7 @@ namespace MDAlgorithms

coord_t xPos = static_cast<coord_t>(x);
coord_t yPos = static_cast<coord_t>(y);
coord_t bankPos = static_cast<coord_t>(*bankNum);
coord_t bankPos = static_cast<coord_t>(bankNum);

EventList & el = in_ws->getEventList(wi);

Expand All @@ -231,31 +291,29 @@ namespace MDAlgorithms
{
case TOF:
if (nd==3)
this->convertEventList<TofEvent, MDLeanEvent<3>, 3>(outWS3, wi, xPos, yPos, bankPos);
this->convertEventList<TofEvent, MDEvent<3>, 3>(outWS3, wi, xPos, yPos, bankPos, runIndex, detID);
else if (nd==4)
this->convertEventList<TofEvent, MDLeanEvent<4>, 4>(outWS4, wi, xPos, yPos, bankPos);
this->convertEventList<TofEvent, MDEvent<4>, 4>(outWS4, wi, xPos, yPos, bankPos, runIndex, detID);
break;
case WEIGHTED:
if (nd==3)
this->convertEventList<WeightedEvent, MDLeanEvent<3>, 3>(outWS3, wi, xPos, yPos, bankPos);
this->convertEventList<WeightedEvent, MDEvent<3>, 3>(outWS3, wi, xPos, yPos, bankPos, runIndex, detID);
else if (nd==4)
this->convertEventList<WeightedEvent, MDLeanEvent<4>, 4>(outWS4, wi, xPos, yPos, bankPos);
this->convertEventList<WeightedEvent, MDEvent<4>, 4>(outWS4, wi, xPos, yPos, bankPos, runIndex, detID);
break;
case WEIGHTED_NOTIME:
if (nd==3)
this->convertEventList<WeightedEventNoTime, MDLeanEvent<3>, 3>(outWS3, wi, xPos, yPos, bankPos);
this->convertEventList<WeightedEventNoTime, MDEvent<3>, 3>(outWS3, wi, xPos, yPos, bankPos, runIndex, detID);
else if (nd==4)
this->convertEventList<WeightedEventNoTime, MDLeanEvent<4>, 4>(outWS4, wi, xPos, yPos, bankPos);
this->convertEventList<WeightedEventNoTime, MDEvent<4>, 4>(outWS4, wi, xPos, yPos, bankPos, runIndex, detID);
break;
default:
throw std::runtime_error("EventList had an unexpected data type!");
}

}

}

// Create the thread pool that will run all of these.
// ---------------------- Perform all box splitting ---------------
ThreadScheduler * ts = new ThreadSchedulerLargestCost();
ThreadPool tp(ts);
outWS->splitAllIfNeeded(ts);
Expand Down

0 comments on commit 7deeed1

Please sign in to comment.