Skip to content
Snippets Groups Projects
LoadAscii2Test.h 18 KiB
Newer Older
#ifndef LOADASCIITEST_H_
#define LOADASCIITEST_H_

#include "cxxtest/TestSuite.h"
Keith Brown's avatar
Keith Brown committed
#include "MantidDataHandling/LoadAscii2.h"
#include "MantidDataHandling/SaveAscii2.h"
#include "MantidAPI/AnalysisDataService.h"
Keith Brown's avatar
Keith Brown committed
#include "MantidDataObjects/Workspace2D.h"
#include <Poco/File.h>
#include <fstream>

Keith Brown's avatar
Keith Brown committed
using namespace Mantid::API;
using namespace Mantid::DataHandling;
using namespace Mantid::Kernel;
using namespace Mantid::DataObjects;

class LoadAscii2Test : public CxxTest::TestSuite
{
public:
Keith Brown's avatar
Keith Brown committed
  static LoadAscii2Test *createSuite() { return new LoadAscii2Test(); }
  static void destroySuite(LoadAscii2Test *suite) { delete suite; }

  LoadAscii2Test()
  {
    m_filename = "LoadAscii2Test";
    m_ext = ".txt";
    m_testno = 0;
Keith Brown's avatar
Keith Brown committed
  }

  ~LoadAscii2Test()
  {
  }

  void testProperties()
  {
Keith Brown's avatar
Keith Brown committed
    LoadAscii2 testLoad;
    TS_ASSERT_EQUALS("LoadAscii", testLoad.name());
    TS_ASSERT_EQUALS(2, testLoad.version());
    TS_ASSERT_EQUALS("DataHandling\\Text", testLoad.category());
  }
Keith Brown's avatar
Keith Brown committed
  //the Poco::File.remove() is always in a TS_ASERT as i need to make sure the loader has released the file.
Keith Brown's avatar
Keith Brown committed
  void testConfidence()
  {
Keith Brown's avatar
Keith Brown committed
    LoadAscii2 testLoad;
    testLoad.initialize();
    m_abspath = writeTestFile(3);
    //descriptor keeps an open handle until destructor call, so the destructor must run before i can remove it
    auto* descriptor = new FileDescriptor(m_abspath);
    TS_ASSERT_EQUALS(10, testLoad.confidence(*descriptor));
    delete descriptor;
    TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
  }

  void test_Three_Column_Example_With_No_Header()
  {
Keith Brown's avatar
Keith Brown committed
    m_abspath = writeTestFile(3,false);
    runTest(3);
    TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
  }

  void test_Three_Column_With_Header_Info()
  {
Keith Brown's avatar
Keith Brown committed
    m_abspath = writeTestFile(3);
    runTest(3);
    TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
  }

  void test_Two_Column_Example_With_No_Header()
  {
Keith Brown's avatar
Keith Brown committed
    m_abspath = writeTestFile(2,false);
    runTest(2);
    TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
  }

  void test_Two_Column_With_Header_Info()
  {
Keith Brown's avatar
Keith Brown committed
    m_abspath = writeTestFile(2);
    runTest(2);
    TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
  }

  void test_Four_Column_Example_With_No_Header()
  {
Keith Brown's avatar
Keith Brown committed
    m_abspath = writeTestFile(4,false);
    runTest(4);
    TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
Keith Brown's avatar
Keith Brown committed
  void test_Four_Column_Example_With_HeaderInfo()
Keith Brown's avatar
Keith Brown committed
    m_abspath = writeTestFile(4);
    runTest(4);
    TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
Keith Brown's avatar
Keith Brown committed
  void test_Four_Column_With_HeaderInfo_CommentChange()
  {
Keith Brown's avatar
Keith Brown committed
    m_abspath = writeTestFile(4,true,"~");
    runTest(4,false, "~");
    TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
  }
Keith Brown's avatar
Keith Brown committed
  void test_Four_Column_With_HeaderInfo_NonScientific()
Keith Brown's avatar
Keith Brown committed
    m_abspath = writeTestFile(4,true,"#", false, 7);
    runTest(4);
    TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
Keith Brown's avatar
Keith Brown committed
  void test_Four_Column_With_Different_Separator()
  {
Keith Brown's avatar
Keith Brown committed
    m_abspath = writeTestFile(4,true,"#", true, 6, "Space");
    runTest(4,true,"#","Space");
    TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
  }

  void test_Custom_Separators()
  {
Keith Brown's avatar
Keith Brown committed
    m_abspath = writeTestFile(4,true,"#", true, 6, "UserDefined", "~");
    runTest(4,false,"#","UserDefined",false,"~");
    TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
  }

  void test_Spacing_Around_Separators()
  {
Keith Brown's avatar
Keith Brown committed
    m_abspath = writeTestFile(4,true,"#", true, 6, "UserDefined", " , "); //space comma space
    //this should work as the load will look for commas and strip out excess spaces
    runTest(4);
    TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
  }

  void test_Double_Spacing_Separators()
  {
Keith Brown's avatar
Keith Brown committed
    m_abspath = writeTestFile(4,true,"#", true, 6, "UserDefined", "  "); //double space
    //this should work as the load will strip out excess spaces
    runTest(4,true,"#","Space");
    TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
  }

  void test_fail_five_columns()
  {
    std::ofstream file(getTestFileName().c_str());
Keith Brown's avatar
Keith Brown committed
    file << std::scientific;
    file << "# X , Y, E, DX, Z" << std::endl;
    for (int i = 0; i < 5; i++)
    {
      file << i << std::endl;
      for (int j = 0; j < 4; j++)
      {
        file << 1.5 * j / 0.9 << "," <<
          (i + 1) * (2. + 4. * (1.5 * j / 0.9)) << "," <<
          1 << "," <<
          0 << "," <<
          (i + 5) * (6. + 3. * (1.7 * j / 0.8)) << std::endl;
      }
    }
    file.unsetf(std::ios_base::floatfield);
    file.close();
    runTest(4,false,"#","CSV",true);//cols doesn't matter here
    TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
  }

  void test_fail_one_column()
  {
    std::ofstream file(getTestFileName().c_str());
Keith Brown's avatar
Keith Brown committed
    file << std::scientific;
    file << "# X" << std::endl;
    for (int i = 0; i < 5; i++)
    {
      file << i << std::endl;
      for (int j = 0; j < 4; j++)
      {
        file << 1.5 * j / 0.9 << std::endl;
      }
    }
    file.unsetf(std::ios_base::floatfield);
    file.close();
    runTest(1,false,"#","CSV",true);//cols doesn't matter here
    TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
  }

  void test_fail_mismatching_bins()
  {
    std::ofstream file(getTestFileName().c_str());
Keith Brown's avatar
Keith Brown committed
    file << std::scientific;
    file << "# X , Y, E, DX" << std::endl;
    for (int i = 0; i < 5; i++)
    {
      file << i << std::endl;
      for (int j = 0; j < 4; j++)
      {
        if (!(i == 3 && j == 2))
        {
          file << 1.5 * j / 0.9 << "," <<
            (i + 1) * (2. + 4. * (1.5 * j / 0.9)) << "," <<
            1 << "," <<
            0 << std::endl;
        }
      }
    }
    file.unsetf(std::ios_base::floatfield);
    file.close();
    runTest(4,false,"#","CSV",true);//cols doesn't matter here
    TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
  }

  void test_fail_mismatching_columns()
  {
    std::ofstream file(getTestFileName().c_str());
Keith Brown's avatar
Keith Brown committed
    file << std::scientific;
    file << "# X , Y, E, DX" << std::endl;
    for (int i = 0; i < 5; i++)
    {
      file << i << std::endl;
      for (int j = 0; j < 4; j++)
      {
        if (!(i == 3 && j == 2))
        {
          file << 1.5 * j / 0.9 << "," <<
            (i + 1) * (2. + 4. * (1.5 * j / 0.9)) << "," <<
            1 << "," <<
            0 << std::endl;
        }
        else
        {
          file << 1.5 * j / 0.9 << "," <<
            (i + 1) * (2. + 4. * (1.5 * j / 0.9)) << "," <<
            1 << std::endl;
        }
      }
    }
    file.unsetf(std::ios_base::floatfield);
    file.close();
    runTest(4,false,"#","CSV",true);//cols doesn't matter here
    TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
  }

  void test_fail_line_start_letter()
  {
    std::ofstream file(getTestFileName().c_str());
Keith Brown's avatar
Keith Brown committed
    file << std::scientific;
    file << "# X , Y, E, DX" << std::endl;
    for (int i = 0; i < 5; i++)
    {
      file << i << std::endl;
      for (int j = 0; j < 4; j++)
      {
        if (!(i == 3 && j == 2))
        {
          file << 1.5 * j / 0.9 << "," <<
            (i + 1) * (2. + 4. * (1.5 * j / 0.9)) << "," <<
            1 << "," <<
            0 << std::endl;
        }
        else
        {
          //used e to make sure it'd not get mistaken for a scientific index
          file << "e" << 1.5 * j / 0.9 << "," <<
            (i + 1) * (2. + 4. * (1.5 * j / 0.9)) << "," <<
            1 << "," <<
            0 << std::endl;
        }
      }
    }
    file.unsetf(std::ios_base::floatfield);
    file.close();
    runTest(4,false,"#","CSV",true);//cols doesn't matter here
    TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
  }

  void test_fail_line_start_noncomment_symbol()
  {
    std::ofstream file(getTestFileName().c_str());
Keith Brown's avatar
Keith Brown committed
    file << std::scientific;
    file << "# X , Y, E, DX" << std::endl;
    for (int i = 0; i < 5; i++)
    {
      file << i << std::endl;
      for (int j = 0; j < 4; j++)
      {
        if (!(i == 3 && j == 2))
        {
          file << 1.5 * j / 0.9 << "," <<
            (i + 1) * (2. + 4. * (1.5 * j / 0.9)) << "," <<
            1 << "," <<
            0 << std::endl;
        }
        else
        {
          file << "@" << 1.5 * j / 0.9 << "," <<
            (i + 1) * (2. + 4. * (1.5 * j / 0.9)) << "," <<
            1 << "," <<
            0 << std::endl;
        }
      }
    }
    file.unsetf(std::ios_base::floatfield);
    file.close();
    runTest(4,false,"#","CSV",true);//cols doesn't matter here
    TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
  }

  void test_fail_line_mixed_letter_number()
  {
    std::ofstream file(getTestFileName().c_str());
Keith Brown's avatar
Keith Brown committed
    file << std::scientific;
    file << "# X , Y, E, DX" << std::endl;
    for (int i = 0; i < 5; i++)
    {
      file << i << std::endl;
      for (int j = 0; j < 4; j++)
      {
        if (!(i == 3 && j == 2))
        {
          file << 1.5 * j / 0.9 << "," <<
            (i + 1) * (2. + 4. * (1.5 * j / 0.9)) << "," <<
            1 << "," <<
            0 << std::endl;
        }
        else
        {
          //used e to make sure it'd not get mistaken for a scientific index
          file << 1.5 * j / 0.9 << "," <<
            (i + 1) * (2. + 4. * (1.5 * j / 0.9)) << "e" << "," <<
            1 << "," <<
            0 << std::endl;
        }
      }
    }
    file.unsetf(std::ios_base::floatfield);
    file.close();
    runTest(4,false,"#","CSV",true);//cols doesn't matter here
    TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
  }

  void test_fail_line_mixed_symbol_number()
  {
    std::ofstream file(getTestFileName().c_str());
Keith Brown's avatar
Keith Brown committed
    file << std::scientific;
    file << "# X , Y, E, DX" << std::endl;
    for (int i = 0; i < 5; i++)
    {
      file << i << std::endl;
      for (int j = 0; j < 4; j++)
      {
        if (!(i == 3 && j == 2))
        {
          file << 1.5 * j / 0.9 << "," <<
            (i + 1) * (2. + 4. * (1.5 * j / 0.9)) << "," <<
            1 << "," <<
            0 << std::endl;
        }
        else
        {
          file << 1.5 * j / 0.9 << "," <<
            (i + 1) * (2. + 4. * (1.5 * j / 0.9)) << "/" << "," <<
            1 << "," <<
            0 << std::endl;
        }
      }
    }
    file.unsetf(std::ios_base::floatfield);
    file.close();
    runTest(4,false,"#","CSV",true);//cols doesn't matter here
    TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
  }

  void test_fail_spectra_ID_inclusion_inconisitant()
  {
    std::ofstream file(getTestFileName().c_str());
Keith Brown's avatar
Keith Brown committed
    file << std::scientific;
    file << "# X , Y, E, DX" << std::endl;
    for (int i = 0; i < 5; i++)
    {
      if (i != 3)
      {
        file << i << std::endl;
      }
      else
      {
        file << std::endl;
      }
      for (int j = 0; j < 4; j++)
      {
        file << 1.5 * j / 0.9 << "," <<
          (i + 1) * (2. + 4. * (1.5 * j / 0.9)) << "," <<
          1 << "," <<
          0 << std::endl;
      }
    }
    file.unsetf(std::ios_base::floatfield);
    file.close();
    runTest(4,false,"#","CSV",true);//cols doesn't matter here
    TS_ASSERT_THROWS_NOTHING(Poco::File(m_abspath).remove());
  }

Keith Brown's avatar
Keith Brown committed
private:
  const std::string getTestFileName() const
  {
    return m_filename + boost::lexical_cast<std::string>(m_testno) + m_ext;
  }
  std::string getAbsPath()
  {
    SaveAscii2 save;
    save.initialize();
    save.setPropertyValue("Filename", getTestFileName());
    return save.getPropertyValue("Filename");
  }
  // Write the test file
Keith Brown's avatar
Keith Brown committed
  std::string writeTestFile(const int cols, const bool header = true, const std::string & comment = "#", const bool scientific = true, const int precision = -1, const std::string & sep = "CSV", const std::string & custsep = "")
Keith Brown's avatar
Keith Brown committed
    SaveAscii2 save;
    save.initialize();
    save.setPropertyValue("Filename", getTestFileName() );
Keith Brown's avatar
Keith Brown committed
    if (cols < 3)
Keith Brown's avatar
Keith Brown committed
      //saveascii2 doens't save 2 column files it has to be made manually
      std::ofstream file(getTestFileName().c_str());
Keith Brown's avatar
Keith Brown committed
      if (scientific)
      {
        file << std::scientific;
      }
      if( header )
      {
Keith Brown's avatar
Keith Brown committed
        file << comment << "X , Y" << std::endl;
Keith Brown's avatar
Keith Brown committed
      }
      for (int i = 0; i < 5; i++)
      {
        file << i << std::endl;
        for (int j = 0; j < 4; j++)
        {
          file << 1.5 * j / 0.9 << "," <<
            (i + 1) * (2. + 4. * (1.5 * j / 0.9)) << std::endl;
        }
      }
      file.unsetf(std::ios_base::floatfield);
Keith Brown's avatar
Keith Brown committed
      file.close();
Keith Brown's avatar
Keith Brown committed
    else
    {
      Mantid::DataObjects::Workspace2D_sptr wsToSave = boost::dynamic_pointer_cast<
        Mantid::DataObjects::Workspace2D>(WorkspaceFactory::Instance().create("Workspace2D", 5, 4, 4));
      for (int i = 0; i < 5; i++)
      {
        std::vector<double>& X = wsToSave->dataX(i);
        std::vector<double>& Y = wsToSave->dataY(i);
        std::vector<double>& E = wsToSave->dataE(i);
        std::vector<double>& DX = wsToSave->dataDx(i);
        for (int j = 0; j < 4; j++)
        {
          X[j] = 1.5 * j / 0.9;
          Y[j] = (i + 1) * (2. + 4. * X[j]);
          E[j] = 1.;
          if (cols == 4)
          {
            DX[j] = 1.;
          }
        }
      }
      const std::string name = "SaveAsciiWS";
      AnalysisDataService::Instance().add(name, wsToSave);
Keith Brown's avatar
Keith Brown committed
      save.initialize();
      save.isInitialized();
      if (precision > -1)
      {
        save.setPropertyValue("Precision", boost::lexical_cast<std::string>(precision));
      }
      save.setPropertyValue("InputWorkspace", name);
      save.setPropertyValue("CommentIndicator", comment);
      save.setPropertyValue("ScientificFormat", boost::lexical_cast<std::string>(scientific));
      save.setPropertyValue("ColumnHeader", boost::lexical_cast<std::string>(header));
      save.setPropertyValue("WriteXError", boost::lexical_cast<std::string>(cols == 4));
Keith Brown's avatar
Keith Brown committed
      save.setPropertyValue("Separator",sep);
      save.setPropertyValue("CustomSeparator", custsep);
Keith Brown's avatar
Keith Brown committed
      save.execute();

      AnalysisDataService::Instance().remove(name);
    }
    return save.getPropertyValue("Filename");
Keith Brown's avatar
Keith Brown committed
  Mantid::API::MatrixWorkspace_sptr runTest(const int cols, const bool dataCheck = true, const std::string & comment = "#", const std::string & sep = "CSV", const bool execThrows = false, const std::string & custsep = "")
Keith Brown's avatar
Keith Brown committed
    using Mantid::DataHandling::LoadAscii2;
    using namespace Mantid::API;

Keith Brown's avatar
Keith Brown committed
    LoadAscii2 loader;
    loader.initialize();
Keith Brown's avatar
Keith Brown committed
    loader.setRethrows(true);
    const std::string outputName(getTestFileName());
Keith Brown's avatar
Keith Brown committed
    TS_ASSERT_THROWS_NOTHING(loader.setPropertyValue("Filename", m_abspath));
    TS_ASSERT_THROWS_NOTHING(loader.setPropertyValue("OutputWorkspace",outputName));
    TS_ASSERT_THROWS_NOTHING(loader.setPropertyValue("Separator", sep));
Keith Brown's avatar
Keith Brown committed
    TS_ASSERT_THROWS_NOTHING(loader.setPropertyValue("CustomSeparator", custsep));
Keith Brown's avatar
Keith Brown committed
    TS_ASSERT_THROWS_NOTHING(loader.setPropertyValue("CommentIndicator", comment));
Keith Brown's avatar
Keith Brown committed
    if (execThrows)
Keith Brown's avatar
Keith Brown committed
      TS_ASSERT_THROWS_ANYTHING(loader.execute());
Keith Brown's avatar
Keith Brown committed
      TS_ASSERT_THROWS_NOTHING(loader.execute());

      TS_ASSERT_EQUALS(loader.isExecuted(), true);

      // Check the workspace
      AnalysisDataServiceImpl &dataStore = AnalysisDataService::Instance();
      if(dataStore.doesExist(outputName))
      {
        TS_ASSERT_EQUALS( dataStore.doesExist(outputName), true);
        Workspace_sptr output;
        TS_ASSERT_THROWS_NOTHING(output = dataStore.retrieve(outputName));
        MatrixWorkspace_sptr outputWS = boost::dynamic_pointer_cast<MatrixWorkspace>(output);
        if(outputWS)
        {
          if( dataCheck )
          {
            checkData(outputWS, cols);
            //Test output
            TS_ASSERT_EQUALS(outputWS->getAxis(0)->unit()->caption(), "Energy");
            TS_ASSERT_EQUALS(outputWS->getAxis(0)->unit()->label(), "meV");
          }
          //Check if filename is saved
          TS_ASSERT_EQUALS(loader.getPropertyValue("Filename"),outputWS->run().getProperty("Filename")->value());
        }
        else
        {
          TS_FAIL(outputName + " does not exist.");
        }
        dataStore.remove(outputName);
        return outputWS;
      }
      else
      {
        TS_FAIL("Cannot retrieve output workspace");
      }
Keith Brown's avatar
Keith Brown committed
    MatrixWorkspace_sptr outputWS;
Keith Brown's avatar
Keith Brown committed
  void checkData(const Mantid::API::MatrixWorkspace_sptr outputWS, const int cols)
Keith Brown's avatar
Keith Brown committed
    TS_ASSERT_EQUALS(outputWS->getNumberHistograms(), 5);
    TS_ASSERT_EQUALS(outputWS->blocksize(), 4);
Keith Brown's avatar
Keith Brown committed
    TS_ASSERT_DELTA(outputWS->readX(0)[0], 0, 1e-6);
    TS_ASSERT_DELTA(outputWS->readY(0)[0], 2, 1e-6);
Keith Brown's avatar
Keith Brown committed
    TS_ASSERT_DELTA(outputWS->readX(0)[1], 1.666667, 1e-6);
    TS_ASSERT_DELTA(outputWS->readY(0)[1], 8.666667, 1e-6);
Keith Brown's avatar
Keith Brown committed
    TS_ASSERT_DELTA(outputWS->readX(1)[2], 3.333333, 1e-6);
    TS_ASSERT_DELTA(outputWS->readY(1)[2], 30.66667, 1e-6);
Keith Brown's avatar
Keith Brown committed
    TS_ASSERT_DELTA(outputWS->readX(3)[3], 5, 1e-6);
    TS_ASSERT_DELTA(outputWS->readY(3)[3], 88, 1e-6);
    if( cols == 3 || cols == 4 )
Keith Brown's avatar
Keith Brown committed
      TS_ASSERT_DELTA(outputWS->readE(0)[0], 1, 1e-6);

      TS_ASSERT_DELTA(outputWS->readE(0)[1], 1, 1e-6);

      TS_ASSERT_DELTA(outputWS->readE(1)[2], 1, 1e-6);

      TS_ASSERT_DELTA(outputWS->readE(3)[3], 1, 1e-6);
Keith Brown's avatar
Keith Brown committed
    else
    {
      TS_ASSERT_DELTA(outputWS->readE(0)[0], 0, 1e-6);
Keith Brown's avatar
Keith Brown committed
      TS_ASSERT_DELTA(outputWS->readE(0)[1], 0, 1e-6);
Keith Brown's avatar
Keith Brown committed
      TS_ASSERT_DELTA(outputWS->readE(1)[2], 0, 1e-6);

      TS_ASSERT_DELTA(outputWS->readE(3)[3], 0, 1e-6);
    }
Keith Brown's avatar
Keith Brown committed
    if( cols == 4 )
    {
      TS_ASSERT_DELTA(outputWS->readDx(0)[0], 1, 1e-6);

      TS_ASSERT_DELTA(outputWS->readDx(0)[1], 1, 1e-6);

      TS_ASSERT_DELTA(outputWS->readDx(1)[2], 1, 1e-6);

      TS_ASSERT_DELTA(outputWS->readDx(3)[3], 1, 1e-6);
    }
Keith Brown's avatar
Keith Brown committed
  }
  std::string m_filename;
  std::string m_abspath;
  std::string m_ext;
  size_t m_testno;
};


#endif //LOADASCIITEST_H_