void SaveNexusProcessed::doExec(Workspace_sptr inputWorkspace, Mantid::NeXus::NexusFileIO_sptr &nexusFile, const bool keepFile, optional_size_t entryNumber) { // TODO: Remove? NXMEnableErrorReporting(); // Retrieve the filename from the properties m_filename = getPropertyValue("Filename"); // m_entryname = getPropertyValue("EntryName"); m_title = getPropertyValue("Title"); // Do we prserve events? bool PreserveEvents = getProperty("PreserveEvents"); MatrixWorkspace_const_sptr matrixWorkspace = boost::dynamic_pointer_cast<const MatrixWorkspace>(inputWorkspace); ITableWorkspace_const_sptr tableWorkspace = boost::dynamic_pointer_cast<const ITableWorkspace>(inputWorkspace); PeaksWorkspace_const_sptr peaksWorkspace = boost::dynamic_pointer_cast<const PeaksWorkspace>(inputWorkspace); OffsetsWorkspace_const_sptr offsetsWorkspace = boost::dynamic_pointer_cast<const OffsetsWorkspace>(inputWorkspace); if (peaksWorkspace) g_log.debug("We have a peaks workspace"); // check if inputWorkspace is something we know how to save if (!matrixWorkspace && !tableWorkspace) { // get the workspace name for the error message std::string name = getProperty("InputWorkspace"); // md workspaces should be saved using SaveMD if (bool(boost::dynamic_pointer_cast<const IMDEventWorkspace>( inputWorkspace)) || bool(boost::dynamic_pointer_cast<const IMDHistoWorkspace>( inputWorkspace))) g_log.warning() << name << " can be saved using SaveMD\n"; // standard error message std::stringstream msg; msg << "Workspace \"" << name << "\" not saved because it is not of a type we can presently save."; throw std::runtime_error(msg.str()); } m_eventWorkspace = boost::dynamic_pointer_cast<const EventWorkspace>(matrixWorkspace); const std::string workspaceID = inputWorkspace->id(); if ((workspaceID.find("Workspace2D") == std::string::npos) && (workspaceID.find("RebinnedOutput") == std::string::npos) && !m_eventWorkspace && !tableWorkspace && !offsetsWorkspace) throw Exception::NotImplementedError( "SaveNexusProcessed passed invalid workspaces. Must be Workspace2D, " "EventWorkspace, ITableWorkspace, or OffsetsWorkspace."); // Create progress object for initial part - depends on whether events are // processed if (PreserveEvents && m_eventWorkspace) { m_timeProgInit = 0.07; // Events processed 0.05 to 1.0 } else { m_timeProgInit = 1.0; // All work is done in the initial part } Progress prog_init(this, 0.0, m_timeProgInit, 7); // If no title's been given, use the workspace title field if (m_title.empty()) m_title = inputWorkspace->getTitle(); // get the workspace name to write to file std::string wsName = inputWorkspace->getName(); // If we don't want to append then remove the file if it already exists bool append_to_file = getProperty("Append"); if (!append_to_file && !keepFile) { Poco::File file(m_filename); if (file.exists()) file.remove(); } nexusFile->resetProgress(&prog_init); nexusFile->openNexusWrite(m_filename, entryNumber); // Equivalent C++ API handle auto cppFile = new ::NeXus::File(nexusFile->fileID); prog_init.reportIncrement(1, "Opening file"); if (nexusFile->writeNexusProcessedHeader(m_title, wsName) != 0) throw Exception::FileError("Failed to write to file", m_filename); prog_init.reportIncrement(1, "Writing header"); // write instrument data, if present and writer enabled if (matrixWorkspace) { // Save the instrument names, ParameterMap, sample, run matrixWorkspace->saveExperimentInfoNexus(cppFile); prog_init.reportIncrement(1, "Writing sample and instrument"); // check if all X() are in fact the same array const bool uniformSpectra = API::WorkspaceHelpers::commonBoundaries(*matrixWorkspace); // Retrieve the workspace indices (from params) std::vector<int> spec; this->getSpectrumList(spec, matrixWorkspace); prog_init.reportIncrement(1, "Writing data"); // Write out the data (2D or event) if (m_eventWorkspace && PreserveEvents) { this->execEvent(nexusFile.get(), uniformSpectra, spec); } else if (offsetsWorkspace) { g_log.warning() << "Writing SpecialWorkspace2D ID=" << workspaceID << "\n"; nexusFile->writeNexusProcessedData2D(matrixWorkspace, uniformSpectra, spec, "offsets_workspace", true); } else { nexusFile->writeNexusProcessedData2D(matrixWorkspace, uniformSpectra, spec, "workspace", true); } cppFile->openGroup("instrument", "NXinstrument"); matrixWorkspace->saveSpectraMapNexus(cppFile, spec, ::NeXus::LZW); cppFile->closeGroup(); } // finish matrix workspace specifics if (peaksWorkspace) { // Save the instrument names, ParameterMap, sample, run peaksWorkspace->saveExperimentInfoNexus(cppFile); prog_init.reportIncrement(1, "Writing sample and instrument"); } // peaks workspace specifics if (peaksWorkspace) { // g_log.information("Peaks Workspace saving to Nexus would be done"); // int pNum = peaksWorkspace->getNumberPeaks(); peaksWorkspace->saveNexus(cppFile); } // finish peaks workspace specifics else if (tableWorkspace) // Table workspace specifics { nexusFile->writeNexusTableWorkspace(tableWorkspace, "table_workspace"); } // finish table workspace specifics // Switch to the Cpp API for the algorithm history if (trackingHistory()) { m_history->fillAlgorithmHistory( this, Mantid::Kernel::DateAndTime::getCurrentTime(), 0, Algorithm::g_execCount); if (!isChild()) { inputWorkspace->history().addHistory(m_history); } // this is a child algorithm, but we still want to keep the history. else if (isRecordingHistoryForChild() && m_parentHistory) { m_parentHistory->addChildHistory(m_history); } } inputWorkspace->history().saveNexus(cppFile); nexusFile->closeGroup(); }
/** Executes the algorithm. * * @throw runtime_error Thrown if algorithm cannot execute */ void SaveNexusProcessed::exec() { //TODO: Remove? NXMEnableErrorReporting(); Workspace_sptr inputWorkspace = getProperty("InputWorkspace"); // Retrieve the filename from the properties m_filename = getPropertyValue("Filename"); //m_entryname = getPropertyValue("EntryName"); m_title = getPropertyValue("Title"); // Do we prserve events? bool PreserveEvents = getProperty("PreserveEvents"); MatrixWorkspace_const_sptr matrixWorkspace = boost::dynamic_pointer_cast<const MatrixWorkspace>(inputWorkspace); ITableWorkspace_const_sptr tableWorkspace = boost::dynamic_pointer_cast<const ITableWorkspace>(inputWorkspace); PeaksWorkspace_const_sptr peaksWorkspace = boost::dynamic_pointer_cast<const PeaksWorkspace>(inputWorkspace); OffsetsWorkspace_const_sptr offsetsWorkspace = boost::dynamic_pointer_cast<const OffsetsWorkspace>(inputWorkspace); if(peaksWorkspace) g_log.debug("We have a peaks workspace"); // check if inputWorkspace is something we know how to save if (!matrixWorkspace && !tableWorkspace) { g_log.debug() << "Workspace " << m_title << " not saved because it is not of a type we can presently save.\n"; return; } m_eventWorkspace = boost::dynamic_pointer_cast<const EventWorkspace>(matrixWorkspace); const std::string workspaceID = inputWorkspace->id(); if ((workspaceID.find("Workspace2D") == std::string::npos) && (workspaceID.find("RebinnedOutput") == std::string::npos) && !m_eventWorkspace && !tableWorkspace && !offsetsWorkspace) throw Exception::NotImplementedError("SaveNexusProcessed passed invalid workspaces. Must be Workspace2D, EventWorkspace, ITableWorkspace, or OffsetsWorkspace."); // Create progress object for initial part - depends on whether events are processed if( PreserveEvents && m_eventWorkspace) { m_timeProgInit = 0.07; // Events processed 0.05 to 1.0 } else { m_timeProgInit = 1.0; // All work is done in the initial part } Progress prog_init(this, 0.0, m_timeProgInit, 7); // If no title's been given, use the workspace title field if (m_title.empty()) m_title = inputWorkspace->getTitle(); // If we don't want to append then remove the file if it already exists bool append_to_file = getProperty("Append"); if( !append_to_file ) { Poco::File file(m_filename); if( file.exists() ) file.remove(); } // Then immediately open the file Mantid::NeXus::NexusFileIO *nexusFile= new Mantid::NeXus::NexusFileIO( &prog_init ); nexusFile->openNexusWrite( m_filename ); // Equivalent C++ API handle ::NeXus::File * cppFile = new ::NeXus::File(nexusFile->fileID); prog_init.reportIncrement(1, "Opening file"); if( nexusFile->writeNexusProcessedHeader( m_title ) != 0 ) throw Exception::FileError("Failed to write to file", m_filename); prog_init.reportIncrement(1, "Writing header"); // write instrument data, if present and writer enabled if (matrixWorkspace) { // Save the instrument names, ParameterMap, sample, run matrixWorkspace->saveExperimentInfoNexus(cppFile); prog_init.reportIncrement(1, "Writing sample and instrument"); // check if all X() are in fact the same array const bool uniformSpectra = API::WorkspaceHelpers::commonBoundaries(matrixWorkspace); // Retrieve the workspace indices (from params) std::vector<int> spec; this->getSpectrumList(spec, matrixWorkspace); prog_init.reportIncrement(1, "Writing data"); // Write out the data (2D or event) if (m_eventWorkspace && PreserveEvents) { this->execEvent(nexusFile,uniformSpectra,spec); } else if (offsetsWorkspace) { g_log.warning() << "Writing SpecialWorkspace2D ID=" << workspaceID << "\n"; nexusFile->writeNexusProcessedData2D(matrixWorkspace,uniformSpectra,spec, "offsets_workspace", true); } else { nexusFile->writeNexusProcessedData2D(matrixWorkspace,uniformSpectra,spec, "workspace", true); } // MW 27/10/10 - don't try and save the spectra-detector map if there isn't one if ( matrixWorkspace->getAxis(1)->isSpectra() ) { cppFile->openGroup("instrument", "NXinstrument"); matrixWorkspace->saveSpectraMapNexus(cppFile, spec, ::NeXus::LZW); cppFile->closeGroup(); } } // finish matrix workspace specifics if (peaksWorkspace) { // Save the instrument names, ParameterMap, sample, run peaksWorkspace->saveExperimentInfoNexus(cppFile); prog_init.reportIncrement(1, "Writing sample and instrument"); } // peaks workspace specifics if (peaksWorkspace) { // g_log.information("Peaks Workspace saving to Nexus would be done"); // int pNum = peaksWorkspace->getNumberPeaks(); peaksWorkspace->saveNexus( cppFile ); } // finish peaks workspace specifics else if (tableWorkspace) // Table workspace specifics { nexusFile->writeNexusTableWorkspace(tableWorkspace,"table_workspace"); } // finish table workspace specifics // Switch to the Cpp API for the algorithm history inputWorkspace->getHistory().saveNexus(cppFile); nexusFile->closeNexusFile(); delete nexusFile; return; }
/** Executes the algorithm. */ void CombinePeaksWorkspaces::exec() { PeaksWorkspace_const_sptr LHSWorkspace = getProperty("LHSWorkspace"); PeaksWorkspace_const_sptr RHSWorkspace = getProperty("RHSWorkspace"); const bool CombineMatchingPeaks = getProperty("CombineMatchingPeaks"); // Warn if not the same instrument, sample if ( LHSWorkspace->getInstrument()->getName() != RHSWorkspace->getInstrument()->getName() ) { g_log.warning("The two input workspaces do not appear to come from data take on the same instrument"); } if ( LHSWorkspace->sample().getName() != RHSWorkspace->sample().getName() ) { g_log.warning("The two input workspaces do not appear to relate to the same sample"); } // Copy the first workspace to our output workspace PeaksWorkspace_sptr output(LHSWorkspace->clone()); // Get hold of the peaks in the second workspace auto & rhsPeaks = RHSWorkspace->getPeaks(); Progress progress(this, 0, 1, rhsPeaks.size()); // If not checking for matching peaks, then it's easy... if ( ! CombineMatchingPeaks ) { // Loop over the peaks in the second workspace, appending each one to the output for ( size_t i = 0; i < rhsPeaks.size(); ++i ) { output->addPeak(rhsPeaks[i]); progress.report(); } } else // Check for matching peaks { const double Tolerance = getProperty("Tolerance"); // Get hold of the peaks in the first workspace as we'll need to examine them auto & lhsPeaks = LHSWorkspace->getPeaks(); // Loop over the peaks in the second workspace, appending ones that don't match any in first workspace for ( size_t i = 0; i < rhsPeaks.size(); ++i ) { const Peak& currentPeak = rhsPeaks[i]; // Now have to go through the first workspace checking for matches // Not doing anything clever as peaks workspace are typically not large - just a linear search bool match = false; for ( size_t j = 0; j < lhsPeaks.size(); ++j ) { const V3D deltaQ = currentPeak.getQSampleFrame() - lhsPeaks[j].getQSampleFrame(); if ( deltaQ.nullVector(Tolerance) ) // Using a V3D method that does the job { match = true; break; } } // Only add the peak if there was no match if ( ! match ) output->addPeak(currentPeak); progress.report(); } } setProperty("OutputWorkspace", output); }