Skip to content

Commit

Permalink
Initial development version. refs #6651
Browse files Browse the repository at this point in the history
Early development of algorithm - hasn't been tested.
Doesn't have any unit tests yet.
Fixed typo in ConvertUnits.
  • Loading branch information
stuartcampbell committed Mar 3, 2013
1 parent 7b532fe commit 6d7fcbd
Show file tree
Hide file tree
Showing 5 changed files with 340 additions and 1 deletion.
3 changes: 3 additions & 0 deletions Code/Mantid/Framework/Algorithms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ set ( SRC_FILES
src/CalculateTransmission.cpp
src/CalculateTransmissionBeamSpreader.cpp
src/CalculateZscore.cpp
src/CalibrateToElasticLine.cpp
src/CaltoDspacemap.cpp
src/ChangeBinOffset.cpp
src/ChangeLogTime.cpp
Expand Down Expand Up @@ -232,6 +233,7 @@ set ( INC_FILES
inc/MantidAlgorithms/CalculateTransmission.h
inc/MantidAlgorithms/CalculateTransmissionBeamSpreader.h
inc/MantidAlgorithms/CalculateZscore.h
inc/MantidAlgorithms/CalibrateToElasticLine.h
inc/MantidAlgorithms/CaltoDspacemap.h
inc/MantidAlgorithms/ChangeBinOffset.h
inc/MantidAlgorithms/ChangeLogTime.h
Expand Down Expand Up @@ -451,6 +453,7 @@ set ( TEST_FILES
CalculateTransmissionBeamSpreaderTest.h
CalculateTransmissionTest.h
CalculateZscoreTest.h
CalibrateToElasticLineTest.h
ChainedOperatorTest.h
ChangeBinOffsetTest.h
ChangeLogTimeTest.h
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#ifndef MANTID_ALGORITHMS_CALIBRATETOELASTICLINE_H_
#define MANTID_ALGORITHMS_CALIBRATETOELASTICLINE_H_

#include "MantidKernel/System.h"
#include "MantidAPI/Algorithm.h"

namespace Mantid
{
namespace Algorithms
{

/** CalibrateToElasticLine : TODO: DESCRIPTION
Copyright © 2013 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
This file is part of Mantid.
Mantid is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
Mantid is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
File change history is stored at: <https://github.com/mantidproject/mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class DLLExport CalibrateToElasticLine : public API::Algorithm
{
public:
CalibrateToElasticLine();
virtual ~CalibrateToElasticLine();

virtual const std::string name() const;
virtual int version() const;
virtual const std::string category() const;

private:
virtual void initDocs();
void init();
void exec();


};


} // namespace Algorithms
} // namespace Mantid

#endif /* MANTID_ALGORITHMS_CALIBRATETOELASTICLINE_H_ */
218 changes: 218 additions & 0 deletions Code/Mantid/Framework/Algorithms/src/CalibrateToElasticLine.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
/*WIKI*
TODO: Enter a full wiki-markup description of your algorithm here. You can then use the Build/wiki_maker.py script to generate your full wiki page.
*WIKI*/

#include <fstream>
#include <iostream>

#include "MantidAlgorithms/CalibrateToElasticLine.h"
#include "MantidAPI/WorkspaceProperty.h"
#include "MantidAPI/WorkspaceValidators.h"
#include "MantidAPI/FileProperty.h"
#include "MantidKernel/FileValidator.h"
#include "MantidGeometry/Instrument/ComponentHelper.h"
#include "MantidGeometry/Instrument/ParameterMap.h"


namespace Mantid
{
namespace Algorithms
{

// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(CalibrateToElasticLine)



//----------------------------------------------------------------------------------------------
/** Constructor
*/
CalibrateToElasticLine::CalibrateToElasticLine()
{
}

//----------------------------------------------------------------------------------------------
/** Destructor
*/
CalibrateToElasticLine::~CalibrateToElasticLine()
{
}


//----------------------------------------------------------------------------------------------
/// Algorithm's name for identification. @see Algorithm::name
const std::string CalibrateToElasticLine::name() const { return "CalibrateToElasticLine";};

/// Algorithm's version for identification. @see Algorithm::version
int CalibrateToElasticLine::version() const { return 1;};

/// Algorithm's category for identification. @see Algorithm::category
const std::string CalibrateToElasticLine::category() const { return "Calibration";}

//----------------------------------------------------------------------------------------------
/// Sets documentation strings for this algorithm
void CalibrateToElasticLine::initDocs()
{
this->setWikiSummary("TODO: Enter a quick description of your algorithm.");
this->setOptionalMessage("TODO: Enter a quick description of your algorithm.");
}

//----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties.
*/
void CalibrateToElasticLine::init()
{

this->declareProperty(new API::WorkspaceProperty<API::MatrixWorkspace>("InputWorkspace","",Kernel::Direction::Input,
boost::make_shared<API::WorkspaceUnitValidator>("TOF")),
"Name of the input workspace.");
this->declareProperty(new API::WorkspaceProperty<API::MatrixWorkspace>("OutputWorkspace","",Kernel::Direction::Output),
"Name of the output workspace, can be the same as the input.");

this->declareProperty(new API::FileProperty("ElasticPositionsFilename", "", API::FileProperty::OptionalLoad, ".dat"),
"Path to a file containing the elastic line positions in tof");
}

//----------------------------------------------------------------------------------------------
/** Execute the algorithm
*/
void CalibrateToElasticLine::exec()
{
// Get the workspaces
API::MatrixWorkspace_const_sptr inputWS = this->getProperty("InputWorkspace");
API::MatrixWorkspace_sptr outputWS = this->getProperty("OutputWorkspace");

// Get the filename of the elastic positions file
std::string filename = this->getProperty("ElasticPositionsFilename");

// Lets load the file
g_log.debug() << "Reading elastic estimate data from " << filename << std::endl;
std::ifstream infile(filename);
std::string lineData;

// Some vectors to store the contents in
std::vector<int> detectorId;
std::vector<double> peakCentre;
//std::vector<double> peakHeight;
//std::vector<int> numberOfEvents;
//std::vector<int> bankNumber;

const int headers_to_skip = 1; // lines to skip on reading
const int max_num_of_char_in_a_line = 512;// Maximum number of characters expected in a single line in the header
for (int i = 0; i < headers_to_skip; ++i) {
infile.ignore(max_num_of_char_in_a_line,'\n');
}

while(getline(infile, lineData))
{
// Some temporary variables
int id;
double centre;
// maybe not need the next variables
//int events, bank;
//double height;

std::stringstream lineStream(lineData);

lineStream >> id;
lineStream >> centre;

//infile >> id >> centre; // >> height >> events >> bank;

//std::cout << "ID=" << id << ", TOF=" << centre << std::endl;

detectorId.push_back(id);
peakCentre.push_back(centre);
//peakHeight.push_back(height);
//numberOfEvents.push_back(events);
//bankNumber.push_back(bank);

}

for(std::vector<int>::size_type j = 0; j < 10; ++j)
{
g_log.warning() << detectorId[j] << "\n";
}

// for(vector<float>::size_type j = 0; j < volt2_array.size(); ++j)
// cout << volt2_array[j] << '\n';


// Check if the input and output workspaces are the same
if (outputWS != inputWS)
{
// If not the same, create a new workspace for the output
outputWS = API::WorkspaceFactory::Instance().create(inputWS);
}


Geometry::Instrument_const_sptr inst = outputWS->getInstrument();

Geometry::ParameterMap& pmap = outputWS->instrumentParameters();

// Get the number of spectra
const std::size_t numberOfChannels = inputWS->blocksize();
const int numberOfSpectra = static_cast<int>(inputWS->size() / numberOfChannels);


// Get L1
Geometry::IObjComponent_const_sptr source = inst->getSource();
Geometry::IObjComponent_const_sptr sample = inst->getSample();
if (source == NULL)
{
throw Kernel::Exception::InstrumentDefinitionError("Cannot determine source.");
}
if (sample == NULL)
{
throw Kernel::Exception::InstrumentDefinitionError("Cannot determine sample.");
}
double l1 = 0.0;
try
{
l1 = source->getDistance(*sample);
g_log.debug() << "Incident Flight Path (L1) = " << l1 << std::endl;
}
catch (Kernel::Exception::NotFoundError &)
{
g_log.error() << "Cannot calculate incident flight path (L1).";
throw Kernel::Exception::InstrumentDefinitionError("Cannot calculate incident flight path (L1)", outputWS->getTitle());
}

// TODO: Initialise the progress bar
// API::Progress prog(this, 0.0, 1.0, numberOfSpectra);

// Loop over the spectra
// for (int i = 0; i < numberOfSpectra; ++i)
for (std::vector<int>::size_type i=0; i < detectorId.size(); ++i)
//for (int i = 0; i < 10; ++i)
{
Geometry::IDetector_const_sptr det = outputWS->getDetectorByID(detectorId[i]);
if (!det->isMonitor())
{
// Get secondary flight path (L2)
double l2 = det->getDistance(*sample);
// Get scattering angle (radians)
double twoTheta = det->getTwoTheta(sample->getPos(),
Kernel::V3D(0.0,0.0,1.0)*Geometry::rad2deg);

// Now let's work out what energy is required for this TOF
double ltotal = l1+l2;
double factor = ((PhysicalConstants::NeutronMass / 2.0) * (ltotal*ltotal))
/ (PhysicalConstants::meV * 1e-12);
double energy = factor / (peakCentre[i]*peakCentre[i]);

g_log.warning() << "det(" << i << ") = " << det->getFullName() << std::endl;
g_log.warning() << " Ef = " << det->getNumberParameter("Efixed").at(0) << std::endl;

pmap.addDouble(det.get(), "Efixed", energy);

g_log.warning() << " Ef = " << det->getNumberParameter("Efixed").at(0) << std::endl;


}
}

}

} // namespace Algorithms
} // namespace Mantid
2 changes: 1 addition & 1 deletion Code/Mantid/Framework/Algorithms/src/ConvertUnits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ void ConvertUnits::convertViaTOF(Kernel::Unit_const_sptr fromUnit, API::MatrixWo
IObjComponent_const_sptr sample = instrument->getSample();
if ( source == NULL || sample == NULL )
{
throw Exception::InstrumentDefinitionError("Instrubment not sufficiently defined: failed to get source and/or sample");
throw Exception::InstrumentDefinitionError("Instrument not sufficiently defined: failed to get source and/or sample");
}
double l1;
try
Expand Down
62 changes: 62 additions & 0 deletions Code/Mantid/Framework/Algorithms/test/CalibrateToElasticLineTest.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#ifndef MANTID_ALGORITHMS_CALIBRATETOELASTICLINETEST_H_
#define MANTID_ALGORITHMS_CALIBRATETOELASTICLINETEST_H_

#include <cxxtest/TestSuite.h>

#include "MantidAPI/AnalysisDataService.h"
#include "MantidAPI/Workspace.h"
#include "MantidAlgorithms/CalibrateToElasticLine.h"

using Mantid::Algorithms::CalibrateToElasticLine;

class CalibrateToElasticLineTest : public CxxTest::TestSuite
{
public:
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static CalibrateToElasticLineTest *createSuite() { return new CalibrateToElasticLineTest(); }
static void destroySuite( CalibrateToElasticLineTest *suite ) { delete suite; }


void test_Init()
{
CalibrateToElasticLine alg;
TS_ASSERT_THROWS_NOTHING( alg.initialize() )
TS_ASSERT( alg.isInitialized() )
}

void test_exec()
{
// Name of the output workspace.
std::string outWSName("CalibrateToElasticLineTest_OutputWS");

CalibrateToElasticLine alg;
TS_ASSERT_THROWS_NOTHING( alg.initialize() )
TS_ASSERT( alg.isInitialized() )
// TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("InputWorkspace", ) );
// TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", outWSName) );
// TS_ASSERT_THROWS_NOTHING( alg.execute(); );
// TS_ASSERT( alg.isExecuted() );

// Retrieve the workspace from data service. TODO: Change to your desired type
// Mantid::API::Workspace_sptr ws;
// TS_ASSERT_THROWS_NOTHING( ws = Mantid::API::AnalysisDataService::Instance().retrieveWS<Mantid::API::Workspace>(outWSName) );
// TS_ASSERT(ws);
// if (!ws) return;

// TODO: Check the results

// Remove workspace from the data service.
// Mantid::API::AnalysisDataService::Instance().remove(outWSName);
}

void xtest_Something()
{
TSM_ASSERT( "You forgot to write a test!", 0);
}


};


#endif /* MANTID_ALGORITHMS_CALIBRATETOELASTICLINETEST_H_ */

0 comments on commit 6d7fcbd

Please sign in to comment.