Skip to content
Snippets Groups Projects
SaveAscii.cpp 4.94 KiB
Newer Older
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidDataHandling/SaveAscii.h"
#include "MantidKernel/UnitFactory.h"
#include "MantidKernel/ArrayProperty.h"

#include <set>
#include <fstream>
#include <boost/tokenizer.hpp>

namespace Mantid
{
  namespace DataHandling
  {
    // Register the algorithm into the algorithm factory
    DECLARE_ALGORITHM(SaveAscii)
    
    /// Sets documentation strings for this algorithm
    void SaveAscii::initDocs()
    {
      this->setWikiSummary("Saves a 2D [[workspace]] to a Ascii file. ");
      this->setOptionalMessage("Saves a 2D workspace to a Ascii file.");
    }
    

    using namespace Kernel;
    using namespace API;

    // Initialise the logger
    Logger& SaveAscii::g_log = Logger::get("SaveAscii");

    /// Initialisation method.
    void SaveAscii::init()
    {
      std::vector<std::string> exts;
      exts.push_back(".dat");
      exts.push_back(".txt");
      exts.push_back(".csv");
      declareProperty(new FileProperty("Filename", "", FileProperty::Save, exts),
		      "A comma separated Ascii file that will be created");
      declareProperty(new WorkspaceProperty<>("Workspace",
        "",Direction::Input), "The name of the workspace that will be saved.");

      BoundedValidator<int> *mustBePositive = new BoundedValidator<int>();
      mustBePositive->setLower(1);
      declareProperty("WorkspaceIndexMin", 1, mustBePositive);
      declareProperty("WorkspaceIndexMax", EMPTY_INT(), mustBePositive->clone());
      declareProperty(new ArrayProperty<int>("SpectrumList"));
      declareProperty("Precision", EMPTY_INT(), mustBePositive->clone());
    }

    /** 
     *   Executes the algorithm.
     */
    void SaveAscii::exec()
    {
        // Get the workspace
        MatrixWorkspace_const_sptr ws = getProperty("Workspace");
Doucet, Mathieu's avatar
Doucet, Mathieu committed
        int nSpectra = static_cast<int>(ws->getNumberHistograms());
        int nBins = static_cast<int>(ws->blocksize());

        // Get the properties
        std::vector<int> spec_list = getProperty("SpectrumList");
        int spec_min = getProperty("WorkspaceIndexMin");
        int spec_max = getProperty("WorkspaceIndexMax");

        // Create an spectra index list for output

        // Add spectra interval into the index list
        if (spec_max != EMPTY_INT() && spec_min != EMPTY_INT())
        {
            if (spec_min >= nSpectra || spec_max >= nSpectra || spec_min > spec_max)
                throw std::invalid_argument("Inconsistent spectra interval");
            for(int spec=spec_min;spec<=spec_max;spec++)
                    idx.insert(spec);
        }

        // Add spectra list into the index list
        if (!spec_list.empty())
            for(size_t i=0;i<spec_list.size();i++)
                if (spec_list[i] >= nSpectra) throw std::invalid_argument("Inconsistent spectra list");
                else
                    idx.insert(spec_list[i]);

        if (!idx.empty()) nSpectra = static_cast<int>(idx.size());

        if (nBins == 0 || nSpectra == 0) throw std::runtime_error("Trying to save an empty workspace");

        std::string filename = getProperty("Filename");
        std::ofstream file(filename.c_str());

        if (!file)
        {
          g_log.error("Unable to create file: " + filename);
          throw Exception::FileError("Unable to create file: " , filename);
        }

        // Write the column captions
        file << "X";
        if (idx.empty())
            for(int spec=0;spec<nSpectra;spec++)
            {
                file << " , Y" << spec << " , E" << spec;
            }
        else
            for(std::set<int>::const_iterator spec=idx.begin();spec!=idx.end();spec++)
            {
                file << " , Y" << *spec << " , E" << *spec;
            }
        file << '\n';

        bool isHistogram = ws->isHistogramData();

        // Set the number precision
        int prec = getProperty("Precision");
        if (prec != EMPTY_INT()) file.precision(prec);

        Progress progress(this,0,1,nBins);
        for(int bin=0;bin<nBins;bin++)
        {
            if (isHistogram) // bin centres
            {
                file << ( ws->readX(0)[bin] + ws->readX(0)[bin+1] )/2;
            }
            else // data points
            {
                file << ws->readX(0)[bin];
            }

            if (idx.empty())
                for(int spec=0;spec<nSpectra;spec++)
                {
                    file << " , " << ws->readY(spec)[bin] << " , " << ws->readE(spec)[bin];
                }
            else
                for(std::set<int>::const_iterator spec=idx.begin();spec!=idx.end();spec++)
                {
                    file << " , " << ws->readY(*spec)[bin] << " , " << ws->readE(*spec)[bin];
                }
            file << '\n';
            progress.report();
        }

    }

  } // namespace DataHandling
} // namespace Mantid