本文整理汇总了C++中typenameMDEventWorkspace::getBox方法的典型用法代码示例。如果您正苦于以下问题:C++ typenameMDEventWorkspace::getBox方法的具体用法?C++ typenameMDEventWorkspace::getBox怎么用?C++ typenameMDEventWorkspace::getBox使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类typenameMDEventWorkspace
的用法示例。
在下文中一共展示了typenameMDEventWorkspace::getBox方法的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: doMinus
void MinusMD::doMinus(typename MDEventWorkspace<MDE, nd>::sptr ws)
{
typename MDEventWorkspace<MDE, nd>::sptr ws1 = ws;
typename MDEventWorkspace<MDE, nd>::sptr ws2 = boost::dynamic_pointer_cast<MDEventWorkspace<MDE, nd> >(m_operand_event);
if (!ws1 || !ws2)
throw std::runtime_error("Incompatible workspace types passed to MinusMD.");
MDBoxBase<MDE,nd> * box1 = ws1->getBox();
MDBoxBase<MDE,nd> * box2 = ws2->getBox();
Progress prog(this, 0.0, 0.4, box2->getBoxController()->getTotalNumMDBoxes());
// How many events you started with
size_t initial_numEvents = ws1->getNPoints();
// Make a leaf-only iterator through all boxes with events in the RHS workspace
MDBoxIterator<MDE,nd> it2(box2, 1000, true);
do
{
MDBox<MDE,nd> * box = dynamic_cast<MDBox<MDE,nd> *>(it2.getBox());
if (box)
{
// Copy the events from WS2 and add them into WS1
const std::vector<MDE> & events = box->getConstEvents();
// Perform a copy while flipping the signal
std::vector<MDE> eventsCopy;
eventsCopy.reserve(events.size());
for (auto it = events.begin(); it != events.end(); it++)
{
MDE eventCopy(*it);
eventCopy.setSignal( -eventCopy.getSignal());
eventsCopy.push_back(eventCopy);
}
// Add events, with bounds checking
box1->addEvents(eventsCopy);
box->releaseEvents();
}
prog.report("Adding Events");
} while (it2.next());
this->progress(0.41, "Splitting Boxes");
Progress * prog2 = new Progress(this, 0.4, 0.9, 100);
ThreadScheduler * ts = new ThreadSchedulerFIFO();
ThreadPool tp(ts, 0, prog2);
ws1->splitAllIfNeeded(ts);
prog2->resetNumSteps( ts->size(), 0.4, 0.6);
tp.joinAll();
this->progress(0.95, "Refreshing cache");
ws1->refreshCache();
// Set a marker that the file-back-end needs updating if the # of events changed.
if (ws1->getNPoints() != initial_numEvents)
ws1->setFileNeedsUpdating(true);
}
示例2: execEventScalar
void MultiplyMD::execEventScalar(typename MDEventWorkspace<MDE, nd>::sptr ws)
{
// Get the scalar multiplying
float scalar = float(m_rhs_scalar->dataY(0)[0]);
float scalarError = float(m_rhs_scalar->dataE(0)[0]);
float scalarRelativeErrorSquared = (scalarError * scalarError) / (scalar * scalar);
// Get all the MDBoxes contained
MDBoxBase<MDE,nd> * parentBox = ws->getBox();
std::vector<API::IMDNode *> boxes;
parentBox->getBoxes(boxes, 1000, true);
bool fileBackedTarget(false);
Kernel::DiskBuffer *dbuff(NULL);
if(ws->isFileBacked())
{
fileBackedTarget = true;
dbuff = ws->getBoxController()->getFileIO();
}
for (size_t i=0; i<boxes.size(); i++)
{
MDBox<MDE,nd> * box = dynamic_cast<MDBox<MDE,nd> *>(boxes[i]);
if (box)
{
typename std::vector<MDE> & events = box->getEvents();
size_t ic(events.size());
typename std::vector<MDE>::iterator it = events.begin();
typename std::vector<MDE>::iterator it_end = events.end();
for (; it != it_end; it++)
{
// Multiply weight by a scalar, propagating error
float oldSignal = it->getSignal();
float signal = oldSignal * scalar;
float errorSquared = signal * signal * (it->getErrorSquared() / (oldSignal * oldSignal) + scalarRelativeErrorSquared);
it->setSignal(signal);
it->setErrorSquared(errorSquared);
}
box->releaseEvents();
if(fileBackedTarget && ic>0)
{
Kernel::ISaveable *const pSaver(box->getISaveable());
dbuff->toWrite(pSaver);
}
}
}
// Recalculate the totals
ws->refreshCache();
// Mark file-backed workspace as dirty
ws->setFileNeedsUpdating(true);
}
示例3: integrate
void CentroidPeaksMD::integrate(typename MDEventWorkspace<MDE, nd>::sptr ws) {
if (nd != 3)
throw std::invalid_argument("For now, we expect the input MDEventWorkspace "
"to have 3 dimensions only.");
/// Peak workspace to centroid
Mantid::DataObjects::PeaksWorkspace_sptr inPeakWS =
getProperty("PeaksWorkspace");
/// Output peaks workspace, create if needed
Mantid::DataObjects::PeaksWorkspace_sptr peakWS =
getProperty("OutputWorkspace");
if (peakWS != inPeakWS)
peakWS.reset(inPeakWS->clone().release());
std::string CoordinatesToUseStr = getPropertyValue("CoordinatesToUse");
int CoordinatesToUse = ws->getSpecialCoordinateSystem();
if (CoordinatesToUse == 1 && CoordinatesToUseStr != "Q (lab frame)")
g_log.warning() << "Warning: used Q (lab frame) coordinates for MD "
"workspace, not CoordinatesToUse from input "
<< std::endl;
else if (CoordinatesToUse == 2 && CoordinatesToUseStr != "Q (sample frame)")
g_log.warning() << "Warning: used Q (sample frame) coordinates for MD "
"workspace, not CoordinatesToUse from input "
<< std::endl;
else if (CoordinatesToUse == 3 && CoordinatesToUseStr != "HKL")
g_log.warning() << "Warning: used HKL coordinates for MD workspace, not "
"CoordinatesToUse from input " << std::endl;
/// Radius to use around peaks
double PeakRadius = getProperty("PeakRadius");
// cppcheck-suppress syntaxError
PRAGMA_OMP(parallel for schedule(dynamic, 10) )
for (int i = 0; i < int(peakWS->getNumberPeaks()); ++i) {
// Get a direct ref to that peak.
IPeak &p = peakWS->getPeak(i);
double detectorDistance = p.getL2();
// Get the peak center as a position in the dimensions of the workspace
V3D pos;
if (CoordinatesToUse == 1) //"Q (lab frame)"
pos = p.getQLabFrame();
else if (CoordinatesToUse == 2) //"Q (sample frame)"
pos = p.getQSampleFrame();
else if (CoordinatesToUse == 3) //"HKL"
pos = p.getHKL();
// Build the sphere transformation
bool dimensionsUsed[nd];
coord_t center[nd];
for (size_t d = 0; d < nd; ++d) {
dimensionsUsed[d] = true; // Use all dimensions
center[d] = static_cast<coord_t>(pos[d]);
}
CoordTransformDistance sphere(nd, center, dimensionsUsed);
// Initialize the centroid to 0.0
signal_t signal = 0;
coord_t centroid[nd];
for (size_t d = 0; d < nd; d++)
centroid[d] = 0.0;
// Perform centroid
ws->getBox()->centroidSphere(
sphere, static_cast<coord_t>(PeakRadius * PeakRadius), centroid,
signal);
// Normalize by signal
if (signal != 0.0) {
for (size_t d = 0; d < nd; d++)
centroid[d] /= static_cast<coord_t>(signal);
V3D vecCentroid(centroid[0], centroid[1], centroid[2]);
// Save it back in the peak object, in the dimension specified.
if (CoordinatesToUse == 1) //"Q (lab frame)"
{
p.setQLabFrame(vecCentroid, detectorDistance);
p.findDetector();
} else if (CoordinatesToUse == 2) //"Q (sample frame)"
{
p.setQSampleFrame(vecCentroid, detectorDistance);
p.findDetector();
} else if (CoordinatesToUse == 3) //"HKL"
{
p.setHKL(vecCentroid);
}
g_log.information() << "Peak " << i << " at " << pos << ": signal "
<< signal << ", centroid " << vecCentroid << " in "
<< CoordinatesToUse << std::endl;
} else {
g_log.information() << "Peak " << i << " at " << pos
<< " had no signal, and could not be centroided."
<< std::endl;
}
}
// Save the output
//.........这里部分代码省略.........
示例4: slice
void SliceMD::slice(typename MDEventWorkspace<MDE, nd>::sptr ws) {
// Create the ouput workspace
typename MDEventWorkspace<OMDE, ond>::sptr outWS(
new MDEventWorkspace<OMDE, ond>());
for (size_t od = 0; od < m_binDimensions.size(); od++) {
outWS->addDimension(m_binDimensions[od]);
}
outWS->setCoordinateSystem(ws->getSpecialCoordinateSystem());
outWS->initialize();
// Copy settings from the original box controller
BoxController_sptr bc = ws->getBoxController();
// store wrute buffer size for the future
// uint64_t writeBufSize =
// bc->getFileIO()getDiskBuffer().getWriteBufferSize();
// and disable write buffer (if any) for input MD Events for this algorithm
// purposes;
// bc->setCacheParameters(1,0);
BoxController_sptr obc = outWS->getBoxController();
// Use the "number of bins" as the "split into" parameter
for (size_t od = 0; od < m_binDimensions.size(); od++)
obc->setSplitInto(od, m_binDimensions[od]->getNBins());
obc->setSplitThreshold(bc->getSplitThreshold());
bool bTakeDepthFromInputWorkspace =
getProperty("TakeMaxRecursionDepthFromInput");
int tempDepth = getProperty("MaxRecursionDepth");
size_t maxDepth =
bTakeDepthFromInputWorkspace ? bc->getMaxDepth() : size_t(tempDepth);
obc->setMaxDepth(maxDepth);
// size_t outputSize = writeBufSize;
// obc->setCacheParameters(sizeof(OMDE),outputSize);
obc->resetNumBoxes();
// Perform the first box splitting
outWS->splitBox();
size_t lastNumBoxes = obc->getTotalNumMDBoxes();
// --- File back end ? ----------------
std::string filename = getProperty("OutputFilename");
if (!filename.empty()) {
// First save to the NXS file
g_log.notice() << "Running SaveMD to create file back-end" << std::endl;
IAlgorithm_sptr alg = createChildAlgorithm("SaveMD");
alg->setPropertyValue("Filename", filename);
alg->setProperty("InputWorkspace", outWS);
alg->setProperty("MakeFileBacked", true);
alg->executeAsChildAlg();
if (!obc->isFileBacked())
throw std::runtime_error("SliceMD with file-backed output: Can not set "
"up file-backed output workspace ");
auto IOptr = obc->getFileIO();
size_t outBufSize = IOptr->getWriteBufferSize();
// the buffer size for resulting workspace; reasonable size is at least 10
// data chunk sizes (nice to verify)
if (outBufSize < 10 * IOptr->getDataChunk()) {
outBufSize = 10 * IOptr->getDataChunk();
IOptr->setWriteBufferSize(outBufSize);
}
}
// Function defining which events (in the input dimensions) to place in the
// output
MDImplicitFunction *function = this->getImplicitFunctionForChunk(NULL, NULL);
std::vector<API::IMDNode *> boxes;
// Leaf-only; no depth limit; with the implicit function passed to it.
ws->getBox()->getBoxes(boxes, 1000, true, function);
// Sort boxes by file position IF file backed. This reduces seeking time,
// hopefully.
bool fileBackedWS = bc->isFileBacked();
if (fileBackedWS)
API::IMDNode::sortObjByID(boxes);
Progress *prog = new Progress(this, 0.0, 1.0, boxes.size());
// The root of the output workspace
MDBoxBase<OMDE, ond> *outRootBox = outWS->getBox();
// if target workspace has events, we should count them as added
uint64_t totalAdded = outWS->getNEvents();
uint64_t numSinceSplit = 0;
// Go through every box for this chunk.
// PARALLEL_FOR_IF( !bc->isFileBacked() )
for (int i = 0; i < int(boxes.size()); i++) {
MDBox<MDE, nd> *box = dynamic_cast<MDBox<MDE, nd> *>(boxes[i]);
// Perform the binning in this separate method.
if (box) {
// An array to hold the rotated/transformed coordinates
coord_t outCenter[ond];
const std::vector<MDE> &events = box->getConstEvents();
typename std::vector<MDE>::const_iterator it = events.begin();
//.........这里部分代码省略.........
示例5: binByIterating
void BinMD::binByIterating(typename MDEventWorkspace<MDE, nd>::sptr ws) {
BoxController_sptr bc = ws->getBoxController();
// store exisiting write buffer size for the future
// uint64_t writeBufSize =bc->getDiskBuffer().getWriteBufferSize();
// and disable write buffer (if any) for input MD Events for this algorithm
// purposes;
// bc->setCacheParameters(1,0);
// Cache some data to speed up accessing them a bit
indexMultiplier = new size_t[m_outD];
for (size_t d = 0; d < m_outD; d++) {
if (d > 0)
indexMultiplier[d] = outWS->getIndexMultiplier()[d - 1];
else
indexMultiplier[d] = 1;
}
signals = outWS->getSignalArray();
errors = outWS->getErrorSquaredArray();
numEvents = outWS->getNumEventsArray();
// Start with signal/error/numEvents at 0.0
outWS->setTo(0.0, 0.0, 0.0);
// The dimension (in the output workspace) along which we chunk for parallel
// processing
// TODO: Find the smartest dimension to chunk against
size_t chunkDimension = 0;
// How many bins (in that dimension) per chunk.
// Try to split it so each core will get 2 tasks:
int chunkNumBins = int(m_binDimensions[chunkDimension]->getNBins() /
(PARALLEL_GET_MAX_THREADS * 2));
if (chunkNumBins < 1)
chunkNumBins = 1;
// Do we actually do it in parallel?
bool doParallel = getProperty("Parallel");
// Not if file-backed!
if (bc->isFileBacked())
doParallel = false;
if (!doParallel)
chunkNumBins = int(m_binDimensions[chunkDimension]->getNBins());
// Total number of steps
size_t progNumSteps = 0;
if (prog)
prog->setNotifyStep(0.1);
if (prog)
prog->resetNumSteps(100, 0.00, 1.0);
// Run the chunks in parallel. There is no overlap in the output workspace so
// it is thread safe to write to it..
// cppcheck-suppress syntaxError
PRAGMA_OMP( parallel for schedule(dynamic,1) if (doParallel) )
for (int chunk = 0;
chunk < int(m_binDimensions[chunkDimension]->getNBins());
chunk += chunkNumBins) {
PARALLEL_START_INTERUPT_REGION
// Region of interest for this chunk.
std::vector<size_t> chunkMin(m_outD);
std::vector<size_t> chunkMax(m_outD);
for (size_t bd = 0; bd < m_outD; bd++) {
// Same limits in the other dimensions
chunkMin[bd] = 0;
chunkMax[bd] = m_binDimensions[bd]->getNBins();
}
// Parcel out a chunk in that single dimension dimension
chunkMin[chunkDimension] = size_t(chunk);
if (size_t(chunk + chunkNumBins) >
m_binDimensions[chunkDimension]->getNBins())
chunkMax[chunkDimension] = m_binDimensions[chunkDimension]->getNBins();
else
chunkMax[chunkDimension] = size_t(chunk + chunkNumBins);
// Build an implicit function (it needs to be in the space of the
// MDEventWorkspace)
MDImplicitFunction *function =
this->getImplicitFunctionForChunk(chunkMin.data(), chunkMax.data());
// Use getBoxes() to get an array with a pointer to each box
std::vector<API::IMDNode *> boxes;
// Leaf-only; no depth limit; with the implicit function passed to it.
ws->getBox()->getBoxes(boxes, 1000, true, function);
// Sort boxes by file position IF file backed. This reduces seeking time,
// hopefully.
if (bc->isFileBacked())
API::IMDNode::sortObjByID(boxes);
// For progress reporting, the # of boxes
if (prog) {
PARALLEL_CRITICAL(BinMD_progress) {
g_log.debug() << "Chunk " << chunk << ": found " << boxes.size()
<< " boxes within the implicit function.\n";
progNumSteps += boxes.size();
prog->setNumSteps(progNumSteps);
}
}
// Go through every box for this chunk.
//.........这里部分代码省略.........
示例6: compareMDWorkspaces
void CompareMDWorkspaces::compareMDWorkspaces(
typename MDEventWorkspace<MDE, nd>::sptr ws) {
typename MDEventWorkspace<MDE, nd>::sptr ws1 = ws;
typename MDEventWorkspace<MDE, nd>::sptr ws2 =
boost::dynamic_pointer_cast<MDEventWorkspace<MDE, nd>>(inWS2);
if (!ws1 || !ws2)
throw std::runtime_error("Incompatible workspace types passed to PlusMD.");
std::vector<API::IMDNode *> boxes1;
std::vector<API::IMDNode *> boxes2;
ws1->getBox()->getBoxes(boxes1, 1000, false);
ws2->getBox()->getBoxes(boxes2, 1000, false);
this->compare(boxes1.size(), boxes2.size(),
"Workspaces do not have the same number of boxes");
for (size_t j = 0; j < boxes1.size(); j++) {
API::IMDNode *box1 = boxes1[j];
API::IMDNode *box2 = boxes2[j];
if (m_CompareBoxID)
this->compare(box1->getID(), box2->getID(), "Boxes have different ID");
else {
if (box1->getID() != box2->getID())
g_log.debug() << " Boxes N: " << j << " have box ID: " << box1->getID()
<< " and " << box2->getID() << " correspondingly\n";
}
this->compare(size_t(box1->getDepth()), size_t(box2->getDepth()),
"Boxes are at a different depth");
this->compare(box1->getNumChildren(), box2->getNumChildren(),
"Boxes do not have the same number of children");
for (size_t i = 0; i < box1->getNumChildren(); i++) {
if (m_CompareBoxID)
this->compare(box1->getChild(i)->getID(), box2->getChild(i)->getID(),
"Child of boxes do not match IDs");
else {
if (box1->getID() != box2->getID())
g_log.debug() << " Boxes N: " << j << " children N: " << i
<< " have box ID: " << box1->getChild(i)->getID()
<< " and " << box2->getChild(i)->getID()
<< " correspondingly\n";
}
}
for (size_t d = 0; d < nd; d++) {
this->compareTol(box1->getExtents(d).getMin(),
box2->getExtents(d).getMin(),
"Extents of box do not match");
this->compareTol(box1->getExtents(d).getMax(),
box2->getExtents(d).getMax(),
"Extents of box do not match");
}
this->compareTol(box1->getInverseVolume(), box2->getInverseVolume(),
"Box inverse volume does not match");
this->compareTol(box1->getSignal(), box2->getSignal(),
"Box signal does not match");
this->compareTol(box1->getErrorSquared(), box2->getErrorSquared(),
"Box error squared does not match");
if (m_CheckEvents)
this->compare(box1->getNPoints(), box2->getNPoints(),
"Number of points in box does not match");
// Are both MDGridBoxes ?
MDGridBox<MDE, nd> *gridbox1 = dynamic_cast<MDGridBox<MDE, nd> *>(box1);
MDGridBox<MDE, nd> *gridbox2 = dynamic_cast<MDGridBox<MDE, nd> *>(box2);
if (gridbox1 && gridbox2) {
for (size_t d = 0; d < nd; d++)
this->compareTol(gridbox1->getBoxSize(d), gridbox2->getBoxSize(d),
"Box sizes do not match");
}
// Are both MDBoxes (with events)
MDBox<MDE, nd> *mdbox1 = dynamic_cast<MDBox<MDE, nd> *>(box1);
MDBox<MDE, nd> *mdbox2 = dynamic_cast<MDBox<MDE, nd> *>(box2);
if (mdbox1 && mdbox2) {
if (m_CheckEvents) {
const std::vector<MDE> &events1 = mdbox1->getConstEvents();
const std::vector<MDE> &events2 = mdbox2->getConstEvents();
try {
this->compare(events1.size(), events2.size(),
"Box event vectors are not the same length");
if (events1.size() == events2.size() && events1.size() > 2) {
// Check first and last event
for (size_t i = 0; i < events1.size(); i++) {
for (size_t d = 0; d < nd; d++) {
this->compareTol(events1[i].getCenter(d),
events2[i].getCenter(d),
"Event center does not match");
}
this->compareTol(events1[i].getSignal(), events2[i].getSignal(),
"Event signal does not match");
this->compareTol(events1[i].getErrorSquared(),
events2[i].getErrorSquared(),
"Event error does not match");
}
}
} catch (CompareFailsException &) {
//.........这里部分代码省略.........
示例7: findPeaks
void FindPeaksMD::findPeaks(typename MDEventWorkspace<MDE, nd>::sptr ws)
{
if (nd < 3)
throw std::invalid_argument("Workspace must have at least 3 dimensions.");
progress(0.01, "Refreshing Centroids");
// TODO: This might be slow, progress report?
// Make sure all centroids are fresh
ws->getBox()->refreshCentroid();
typedef IMDBox<MDE,nd>* boxPtr;
if (ws->getNumExperimentInfo() == 0)
throw std::runtime_error("No instrument was found in the MDEventWorkspace. Cannot find peaks.");
// TODO: Do we need to pick a different instrument info?
ExperimentInfo_sptr ei = ws->getExperimentInfo(0);
// Instrument associated with workspace
Geometry::Instrument_const_sptr inst = ei->getInstrument();
// Find the run number
int runNumber = ei->getRunNumber();
// Check that the workspace dimensions are in Q-sample-frame or Q-lab-frame.
eDimensionType dimType;
std::string dim0 = ws->getDimension(0)->getName();
if (dim0 == "H")
{
dimType = HKL;
throw std::runtime_error("Cannot find peaks in a workspace that is already in HKL space.");
}
else if (dim0 == "Q_lab_x")
{
dimType = QLAB;
}
else if (dim0 == "Q_sample_x")
dimType = QSAMPLE;
else
throw std::runtime_error("Unexpected dimensions: need either Q_lab_x or Q_sample_x.");
// Find the goniometer rotation matrix
Mantid::Kernel::Matrix<double> goniometer(3,3, true); // Default IDENTITY matrix
try
{
goniometer = ei->mutableRun().getGoniometerMatrix();
}
catch (std::exception & e)
{
g_log.warning() << "Error finding goniometer matrix. It will not be set in the peaks found." << std::endl;
g_log.warning() << e.what() << std::endl;
}
/// Arbitrary scaling factor for density to make more manageable numbers, especially for older file formats.
signal_t densityScalingFactor = 1e-6;
// Calculate a threshold below which a box is too diffuse to be considered a peak.
signal_t thresholdDensity = 0.0;
thresholdDensity = ws->getBox()->getSignalNormalized() * DensityThresholdFactor * densityScalingFactor;
g_log.notice() << "Threshold signal density: " << thresholdDensity << std::endl;
// We will fill this vector with pointers to all the boxes (up to a given depth)
typename std::vector<boxPtr> boxes;
// Get all the MDboxes
progress(0.10, "Getting Boxes");
ws->getBox()->getBoxes(boxes, 1000, true);
// TODO: Here keep only the boxes > e.g. 3 * mean.
typedef std::pair<double, boxPtr> dens_box;
// Map that will sort the boxes by increasing density. The key = density; value = box *.
typename std::multimap<double, boxPtr> sortedBoxes;
progress(0.20, "Sorting Boxes by Density");
typename std::vector<boxPtr>::iterator it1;
typename std::vector<boxPtr>::iterator it1_end = boxes.end();
for (it1 = boxes.begin(); it1 != it1_end; it1++)
{
boxPtr box = *it1;
double density = box->getSignalNormalized() * densityScalingFactor;
// Skip any boxes with too small a signal density.
if (density > thresholdDensity)
sortedBoxes.insert(dens_box(density,box));
}
// List of chosen possible peak boxes.
std::vector<boxPtr> peakBoxes;
prog = new Progress(this, 0.30, 0.95, MaxPeaks);
int64_t numBoxesFound = 0;
// Now we go (backwards) through the map
// e.g. from highest density down to lowest density.
typename std::multimap<double, boxPtr>::reverse_iterator it2;
typename std::multimap<double, boxPtr>::reverse_iterator it2_end = sortedBoxes.rend();
for (it2 = sortedBoxes.rbegin(); it2 != it2_end; it2++)
{
//.........这里部分代码省略.........
示例8: doCreate
void vtkMDHexFactory::doCreate(
typename MDEventWorkspace<MDE, nd>::sptr ws) const {
bool VERBOSE = true;
CPUTimer tim;
// Acquire a scoped read-only lock to the workspace (prevent segfault from
// algos modifying ws)
ReadLock lock(*ws);
// First we get all the boxes, up to the given depth; with or wo the slice
// function
std::vector<API::IMDNode *> boxes;
if (this->slice)
ws->getBox()->getBoxes(boxes, m_maxDepth, true,
this->sliceImplicitFunction.get());
else
ws->getBox()->getBoxes(boxes, m_maxDepth, true);
vtkIdType numBoxes = boxes.size();
vtkIdType imageSizeActual = 0;
if (VERBOSE)
std::cout << tim << " to retrieve the " << numBoxes
<< " boxes down to depth " << m_maxDepth << '\n';
// Create 8 points per box.
vtkNew<vtkPoints> points;
vtkFloatArray *pointsArray = vtkFloatArray::FastDownCast(points->GetData());
float *pointsPtr = pointsArray->WritePointer(0, numBoxes * 8 * 3);
// One scalar per box
vtkNew<vtkFloatArray> signals;
signals->SetName(ScalarName.c_str());
signals->SetNumberOfComponents(1);
float *signalsPtr = signals->WritePointer(0, numBoxes);
// To cache the signal
std::vector<float> signalCache(numBoxes, 0);
// True for boxes that we will use
// We do not use vector<bool> here because of the parallelization below
// Simultaneous access to different elements of vector<bool> is not safe
auto useBox = Mantid::Kernel::make_unique<bool[]>(numBoxes);
memset(useBox.get(), 0, sizeof(bool) * numBoxes);
// Create the data set (will outlive this object - output of create)
auto visualDataSet = vtkSmartPointer<vtkUnstructuredGrid>::New();
this->dataSet = visualDataSet;
visualDataSet->Allocate(numBoxes);
vtkNew<vtkIdList> hexPointList;
hexPointList->SetNumberOfIds(8);
auto hexPointList_ptr = hexPointList->WritePointer(0, 8);
NormFuncIMDNodePtr normFunction =
makeMDEventNormalizationFunction(m_normalizationOption, ws.get());
// This can be parallelized
// cppcheck-suppress syntaxError
PRAGMA_OMP( parallel for schedule (dynamic) )
for (int ii = 0; ii < int(boxes.size()); ii++) {
// Get the box here
size_t i = static_cast<size_t>(ii);
API::IMDNode *box = boxes[i];
Mantid::signal_t signal_normalized = (box->*normFunction)();
if (std::isfinite(signal_normalized)) {
// Cache the signal and using of it
signalCache[i] = static_cast<float>(signal_normalized);
useBox[i] = true;
// Get the coordinates.
size_t numVertexes = 0;
std::unique_ptr<coord_t[]> coords;
// If slicing down to 3D, specify which dimensions to keep.
if (this->slice) {
coords = std::unique_ptr<coord_t[]>(
box->getVertexesArray(numVertexes, 3, this->sliceMask.get()));
} else {
coords =
std::unique_ptr<coord_t[]>(box->getVertexesArray(numVertexes));
}
if (numVertexes == 8) {
std::copy_n(coords.get(), 24, std::next(pointsPtr, i * 24));
}
} else {
useBox[i] = false;
}
} // For each box
if (VERBOSE)
std::cout << tim << " to create the necessary points.\n";
// Add points
visualDataSet->SetPoints(points.GetPointer());
for (size_t i = 0; i < boxes.size(); i++) {
if (useBox[i]) {
// The bare point ID
vtkIdType pointId = i * 8;
//.........这里部分代码省略.........
示例9: doPlus
void PlusMD::doPlus(typename MDEventWorkspace<MDE, nd>::sptr ws)
{
typename MDEventWorkspace<MDE, nd>::sptr ws1 = ws;
typename MDEventWorkspace<MDE, nd>::sptr ws2 = boost::dynamic_pointer_cast<MDEventWorkspace<MDE, nd> >(m_operand_event);
if (!ws1 || !ws2)
throw std::runtime_error("Incompatible workspace types passed to PlusMD.");
MDBoxBase<MDE,nd> * box1 = ws1->getBox();
MDBoxBase<MDE,nd> * box2 = ws2->getBox();
Progress prog(this, 0.0, 0.4, box2->getBoxController()->getTotalNumMDBoxes());
// How many events you started with
size_t initial_numEvents = ws1->getNPoints();
// Make a leaf-only iterator through all boxes with events in the RHS workspace
MDBoxIterator<MDE,nd> it2(box2, 1000, true);
do
{
MDBox<MDE,nd> * box = dynamic_cast<MDBox<MDE,nd> *>(it2.getBox());
if (box)
{
// Copy the events from WS2 and add them into WS1
const std::vector<MDE> & events = box->getConstEvents();
// Add events, with bounds checking
box1->addEvents(events);
box->releaseEvents();
}
prog.report("Adding Events");
} while (it2.next());
this->progress(0.41, "Splitting Boxes");
Progress * prog2 = new Progress(this, 0.4, 0.9, 100);
ThreadScheduler * ts = new ThreadSchedulerFIFO();
ThreadPool tp(ts, 0, prog2);
ws1->splitAllIfNeeded(ts);
prog2->resetNumSteps( ts->size(), 0.4, 0.6);
tp.joinAll();
// // Now we need to save all the data that was not saved before.
// if (ws1->isFileBacked())
// {
// // Flush anything else in the to-write buffer
// BoxController_sptr bc = ws1->getBoxController();
//
// prog.resetNumSteps(bc->getTotalNumMDBoxes(), 0.6, 1.0);
// MDBoxIterator<MDE,nd> it1(box1, 1000, true);
// while (true)
// {
// MDBox<MDE,nd> * box = dynamic_cast<MDBox<MDE,nd> *>(it1.getBox());
// if (box)
// {
// // Something was maybe added to this box
// if (box->getEventVectorSize() > 0)
// {
// // By getting the events, this will merge the newly added and the cached events.
// box->getEvents();
// // The MRU to-write cache will optimize writes by reducing seek times
// box->releaseEvents();
// }
// }
// prog.report("Saving");
// if (!it1.next()) break;
// }
// //bc->getDiskBuffer().flushCache();
// // Flush the data writes to disk.
// box1->flushData();
// }
this->progress(0.95, "Refreshing cache");
ws1->refreshCache();
// Set a marker that the file-back-end needs updating if the # of events changed.
if (ws1->getNPoints() != initial_numEvents)
ws1->setFileNeedsUpdating(true);
}
示例10: do_centerpointBin
void BinToMDHistoWorkspace::do_centerpointBin(typename MDEventWorkspace<MDE, nd>::sptr ws)
{
bool DODEBUG = true;
CPUTimer tim;
// Number of output binning dimensions found
size_t outD = binDimensions.size();
//Since the costs are not known ahead of time, use a simple FIFO buffer.
ThreadScheduler * ts = new ThreadSchedulerFIFO();
// Create the threadpool with: all CPUs, a progress reporter
ThreadPool tp(ts, 0, prog);
// Big efficiency gain is obtained by grouping a few bins per task.
size_t binsPerTask = 100;
// For progress reporting, the approx # of tasks
if (prog)
prog->setNumSteps( int(outWS->getNPoints()/100) );
// The root-level box.
IMDBox<MDE,nd> * rootBox = ws->getBox();
// This is the limit to loop over in each dimension
size_t * index_max = new size_t[outD];
for (size_t bd=0; bd<outD; bd++) index_max[bd] = binDimensions[bd]->getNBins();
// Cache a calculation to convert indices x,y,z,t into a linear index.
size_t * index_maker = new size_t[outD];
Utils::NestedForLoop::SetUpIndexMaker(outD, index_maker, index_max);
int numPoints = int(outWS->getNPoints());
// Run in OpenMP with dynamic scheduling and a smallish chunk size (binsPerTask)
// Right now, not parallel for file-backed systems.
bool fileBacked = (ws->getBoxController()->getFile() != NULL);
PRAGMA_OMP(parallel for schedule(dynamic, binsPerTask) if (!fileBacked) )
for (int i=0; i < numPoints; i++)
{
PARALLEL_START_INTERUPT_REGION
size_t linear_index = size_t(i);
// nd >= outD in all cases so this is safe.
size_t index[nd];
// Get the index at each dimension for this bin.
Utils::NestedForLoop::GetIndicesFromLinearIndex(outD, linear_index, index_maker, index_max, index);
// Construct the bin and its coordinates
MDBin<MDE,nd> bin;
for (size_t bd=0; bd<outD; bd++)
{
// Index in this binning dimension (i_x, i_y, etc.)
size_t idx = index[bd];
// Dimension in the MDEventWorkspace
size_t d = dimensionToBinFrom[bd];
// Corresponding extents
bin.m_min[d] = binDimensions[bd]->getX(idx);
bin.m_max[d] = binDimensions[bd]->getX(idx+1);
}
bin.m_index = linear_index;
bool dimensionsUsed[nd];
for (size_t d=0; d<nd; d++)
dimensionsUsed[d] = (d<3);
// Check if the bin is in the ImplicitFunction (if any)
bool binContained = true;
if (implicitFunction)
{
binContained = implicitFunction->isPointContained(bin.m_min); //TODO. Correct argument passed to this method?
}
if (binContained)
{
// Array of bools set to true when a dimension is fully contained (binary splitting only)
bool fullyContained[nd];
for (size_t d=0; d<nd; d++)
fullyContained[d] = false;
// This will recursively bin into the sub grids
rootBox->centerpointBin(bin, fullyContained);
// Save the data into the dense histogram
outWS->setSignalAt(linear_index, bin.m_signal);
outWS->setErrorAt(linear_index, bin.m_errorSquared);
}
// Report progress but not too often.
if (((linear_index % 100) == 0) && prog ) prog->report();
PARALLEL_END_INTERUPT_REGION
} // (for each linear index)
PARALLEL_CHECK_INTERUPT_REGION
if (DODEBUG) std::cout << tim << " to run the openmp loop.\n";
delete [] index_max;
//.........这里部分代码省略.........
示例11: binByIterating
void BinToMDHistoWorkspace::binByIterating(typename MDEventWorkspace<MDE, nd>::sptr ws)
{
BoxController_sptr bc = ws->getBoxController();
// Start with signal at 0.0
outWS->setTo(0.0, 0.0);
// Cache some data to speed up accessing them a bit
indexMultiplier = new size_t[outD];
for (size_t d=0; d<outD; d++)
{
if (d > 0)
indexMultiplier[d] = outWS->getIndexMultiplier()[d-1];
else
indexMultiplier[d] = 1;
}
signals = outWS->getSignalArray();
errors = outWS->getErrorSquaredArray();
// The dimension (in the output workspace) along which we chunk for parallel processing
// TODO: Find the smartest dimension to chunk against
size_t chunkDimension = 0;
// How many bins (in that dimension) per chunk.
// Try to split it so each core will get 2 tasks:
int chunkNumBins = int(binDimensions[chunkDimension]->getNBins() / (Mantid::Kernel::ThreadPool::getNumPhysicalCores() * 2));
if (chunkNumBins < 1) chunkNumBins = 1;
// Do we actually do it in parallel?
bool doParallel = getProperty("Parallel");
// Not if file-backed!
if (bc->isFileBacked()) doParallel = false;
if (!doParallel)
chunkNumBins = int(binDimensions[chunkDimension]->getNBins());
// Total number of steps
size_t progNumSteps = 0;
if (prog) prog->setNotifyStep(0.1);
if (prog) prog->resetNumSteps(100, 0.00, 1.0);
// Run the chunks in parallel. There is no overlap in the output workspace so it is
// thread safe to write to it..
PRAGMA_OMP( parallel for schedule(dynamic,1) if (doParallel) )
for(int chunk=0; chunk < int(binDimensions[chunkDimension]->getNBins()); chunk += chunkNumBins)
{
PARALLEL_START_INTERUPT_REGION
// Region of interest for this chunk.
size_t * chunkMin = new size_t[outD];
size_t * chunkMax = new size_t[outD];
for (size_t bd=0; bd<outD; bd++)
{
// Same limits in the other dimensions
chunkMin[bd] = 0;
chunkMax[bd] = binDimensions[bd]->getNBins();
}
// Parcel out a chunk in that single dimension dimension
chunkMin[chunkDimension] = size_t(chunk);
if (size_t(chunk+chunkNumBins) > binDimensions[chunkDimension]->getNBins())
chunkMax[chunkDimension] = binDimensions[chunkDimension]->getNBins();
else
chunkMax[chunkDimension] = size_t(chunk+chunkNumBins);
// Build an implicit function (it needs to be in the space of the MDEventWorkspace)
MDImplicitFunction * function = this->getImplicitFunctionForChunk(chunkMin, chunkMax);
// Use getBoxes() to get an array with a pointer to each box
std::vector<IMDBox<MDE,nd>*> boxes;
// Leaf-only; no depth limit; with the implicit function passed to it.
ws->getBox()->getBoxes(boxes, 1000, true, function);
// Sort boxes by file position IF file backed. This reduces seeking time, hopefully.
if (bc->isFileBacked())
IMDBox<MDE, nd>::sortBoxesByFilePos(boxes);
// For progress reporting, the # of boxes
if (prog)
{
PARALLEL_CRITICAL(BinToMDHistoWorkspace_progress)
{
std::cout << "Chunk " << chunk << ": found " << boxes.size() << " boxes within the implicit function." << std::endl;
progNumSteps += boxes.size();
prog->setNumSteps( progNumSteps );
}
}
// Go through every box for this chunk.
for (size_t i=0; i<boxes.size(); i++)
{
MDBox<MDE,nd> * box = dynamic_cast<MDBox<MDE,nd> *>(boxes[i]);
// Perform the binning in this separate method.
if (box)
this->binMDBox(box, chunkMin, chunkMax);
// Progress reporting
if (prog) prog->report();
}// for each box in the vector
PARALLEL_END_INTERUPT_REGION
} // for each chunk in parallel
PARALLEL_CHECK_INTERUPT_REGION
//.........这里部分代码省略.........
示例12: integrate
void CentroidPeaksMD::integrate(typename MDEventWorkspace<MDE, nd>::sptr ws)
{
if (nd != 3)
throw std::invalid_argument("For now, we expect the input MDEventWorkspace to have 3 dimensions only.");
/// Peak workspace to centroid
Mantid::DataObjects::PeaksWorkspace_sptr inPeakWS = getProperty("PeaksWorkspace");
/// Output peaks workspace, create if needed
Mantid::DataObjects::PeaksWorkspace_sptr peakWS = getProperty("OutputWorkspace");
if (peakWS != inPeakWS)
peakWS = inPeakWS->clone();
/// Value of the CoordinatesToUse property.
std::string CoordinatesToUse = getPropertyValue("CoordinatesToUse");
// TODO: Confirm that the coordinates requested match those in the MDEventWorkspace
/// Radius to use around peaks
double PeakRadius = getProperty("PeakRadius");
PRAGMA_OMP(parallel for schedule(dynamic, 10) )
for (int i=0; i < int(peakWS->getNumberPeaks()); ++i)
{
// Get a direct ref to that peak.
IPeak & p = peakWS->getPeak(i);
double detectorDistance = p.getL2();
// Get the peak center as a position in the dimensions of the workspace
V3D pos;
if (CoordinatesToUse == "Q (lab frame)")
pos = p.getQLabFrame();
else if (CoordinatesToUse == "Q (sample frame)")
pos = p.getQSampleFrame();
else if (CoordinatesToUse == "HKL")
pos = p.getHKL();
// Build the sphere transformation
bool dimensionsUsed[nd];
coord_t center[nd];
for (size_t d=0; d<nd; ++d)
{
dimensionsUsed[d] = true; // Use all dimensions
center[d] = pos[d];
}
CoordTransformDistance sphere(nd, center, dimensionsUsed);
// Initialize the centroid to 0.0
signal_t signal = 0;
coord_t centroid[nd];
for (size_t d=0; d<nd; d++)
centroid[d] = 0.0;
// Perform centroid
ws->getBox()->centroidSphere(sphere, PeakRadius*PeakRadius, centroid, signal);
// Normalize by signal
if (signal != 0.0)
{
for (size_t d=0; d<nd; d++)
centroid[d] /= signal;
V3D vecCentroid(centroid[0], centroid[1], centroid[2]);
// Save it back in the peak object, in the dimension specified.
if (CoordinatesToUse == "Q (lab frame)")
{
p.setQLabFrame( vecCentroid, detectorDistance);
p.findDetector();
}
else if (CoordinatesToUse == "Q (sample frame)")
{
p.setQSampleFrame( vecCentroid, detectorDistance);
p.findDetector();
}
else if (CoordinatesToUse == "HKL")
{
p.setHKL( vecCentroid );
}
g_log.information() << "Peak " << i << " at " << pos << ": signal "
<< signal << ", centroid " << vecCentroid
<< " in " << CoordinatesToUse
<< std::endl;
}
else
{
g_log.information() << "Peak " << i << " at " << pos << " had no signal, and could not be centroided."
<< std::endl;
}
}
// Save the output
setProperty("OutputWorkspace", peakWS);
}