/** * Setup the filebackend for the output workspace. It assumes that the * box controller has already been initialized * @param filebackPath :: Path to the file used for backend storage * @param outputWS :: Workspace on which to set the file back end */ void ConvertToMD::setupFileBackend( std::string filebackPath, Mantid::API::IMDEventWorkspace_sptr outputWS) { using DataObjects::BoxControllerNeXusIO; auto savemd = this->createChildAlgorithm("SaveMD", 0.01, 0.05, true); savemd->setProperty("InputWorkspace", outputWS); savemd->setPropertyValue("Filename", filebackPath); savemd->setProperty("UpdateFileBackEnd", false); savemd->setProperty("MakeFileBacked", false); savemd->executeAsChildAlg(); // create file-backed box controller auto boxControllerMem = outputWS->getBoxController(); auto boxControllerIO = boost::make_shared<BoxControllerNeXusIO>(boxControllerMem.get()); boxControllerMem->setFileBacked(boxControllerIO, filebackPath); outputWS->setFileBacked(); boxControllerMem->getFileIO()->setWriteBufferSize(1000000); }
/** Perform the merging, but clone the initial workspace and use the same splitting * as its structure is equivalent to the partial box structures. * * @param ws :: first MDEventWorkspace in the list to merge to. * @param outputFile :: the name of the output file where file-based workspace should be saved */ void MergeMDFiles::doExecByCloning(Mantid::API::IMDEventWorkspace_sptr ws,const std::string &outputFile) { m_OutIWS = ws; m_MDEventType = ws->getEventTypeName(); // Run the tasks in parallel? TODO: enable //bool Parallel = this->getProperty("Parallel"); // Fix the box controller settings in the output workspace so that it splits normally BoxController_sptr bc = ws->getBoxController(); // set up internal variables characterizing the workspace. m_nDims = static_cast<int>(bc->getNDims()); // Fix the max depth to something bigger. bc->setMaxDepth(20); bc->setSplitThreshold(5000); auto saver = boost::shared_ptr<API::IBoxControllerIO>(new MDEvents::BoxControllerNeXusIO(bc.get())); saver->setDataType(sizeof(coord_t),m_MDEventType); if(m_fileBasedTargetWS) { bc->setFileBacked(saver,outputFile); // Complete the file-back-end creation. g_log.notice() << "Setting cache to 400 MB write." << std::endl; bc->getFileIO()->setWriteBufferSize(400000000/m_OutIWS->sizeofEvent()); } /* else { saver->openFile(outputFile,"w"); }*/ // Init box structure used for memory/file space calculations m_BoxStruct.initFlatStructure(ws,outputFile); // First, load all the box data and experiment info and calculate file positions of the target workspace this->loadBoxData(); size_t numBoxes = m_BoxStruct.getNBoxes(); // Progress report based on events processed. this->prog = new Progress(this, 0.1, 0.9, size_t(numBoxes)); prog->setNotifyStep(0.1); // For tracking progress //uint64_t totalEventsInTasks = 0; // Prepare thread pool CPUTimer overallTime; ThreadSchedulerFIFO * ts = new ThreadSchedulerFIFO(); ThreadPool tp(ts); Kernel::DiskBuffer *DiskBuf(NULL); if(m_fileBasedTargetWS) { DiskBuf = bc->getFileIO(); } this->totalLoaded = 0; std::vector<API::IMDNode *> &boxes = m_BoxStruct.getBoxes(); for(size_t ib=0;ib<numBoxes;ib++) { auto box = boxes[ib]; if(!box->isBox())continue; // load all contributed events into current box; this->loadEventsFromSubBoxes(boxes[ib]); if(DiskBuf) { if(box->getDataInMemorySize()>0) { // data position has been already precalculated box->getISaveable()->save(); box->clearDataFromMemory(); //Kernel::ISaveable *Saver = box->getISaveable(); //DiskBuf->toWrite(Saver); } } //else //{ size_t ID = box->getID(); // uint64_t filePosition = targetEventIndexes[2*ID]; // box->saveAt(saver.get(), filePosition); //} // //if (!Parallel) //{ // // Run the task serially only // task->run(); // delete task; //} //else //{ // // Enqueue to run in parallel (at the joinAll() call below). // ts->push(task); //} prog->reportIncrement(ib,"Loading and merging box data"); } if(DiskBuf) { DiskBuf->flushCache(); bc->getFileIO()->flushData(); } //// Run any final tasks //tp.joinAll(); g_log.information() << overallTime << " to do all the adding." << std::endl; // Close any open file handle clearEventLoaders(); // Finish things up this->finalizeOutput(outputFile); }