Skip to content

Commit

Permalink
Split TOF-only code from AlignDetectors to AlignDetectorInTOF. Refs #…
Browse files Browse the repository at this point in the history
  • Loading branch information
wdzhou committed Nov 9, 2011
1 parent ce7589d commit d527847
Show file tree
Hide file tree
Showing 6 changed files with 366 additions and 144 deletions.
3 changes: 3 additions & 0 deletions Code/Mantid/Framework/Algorithms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ set ( SRC_FILES
src/AbsorptionCorrection.cpp
src/AddLogDerivative.cpp
src/AddSampleLog.cpp
src/AlignDetectorInTOF.cpp
src/AlignDetectors.cpp
src/AlphaCalc.cpp
src/AnyShapeAbsorption.cpp
Expand Down Expand Up @@ -172,6 +173,7 @@ set ( INC_FILES
inc/MantidAlgorithms/AbsorptionCorrection.h
inc/MantidAlgorithms/AddLogDerivative.h
inc/MantidAlgorithms/AddSampleLog.h
inc/MantidAlgorithms/AlignDetectorInTOF.h
inc/MantidAlgorithms/AlignDetectors.h
inc/MantidAlgorithms/AlphaCalc.h
inc/MantidAlgorithms/AnyShapeAbsorption.h
Expand Down Expand Up @@ -340,6 +342,7 @@ set ( INC_FILES
set ( TEST_FILES
test/AddLogDerivativeTest.h
test/AddSampleLogTest.h
test/AlignDetectorInTOFTest.h
test/AlignDetectorsTest.h
test/AlphaCalcTest.h
test/AnyShapeAbsorptionTest.h
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#ifndef MANTID_ALGORITHMS_ALIGNDETECTORINTOF_H_
#define MANTID_ALGORITHMS_ALIGNDETECTORINTOF_H_

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

namespace Mantid
{
namespace Algorithms
{

/** AlignDetectorInTOF : TODO: DESCRIPTION
@date 2011-11-08
Copyright © 2011 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://svn.mantidproject.org/mantid/trunk/Code/Mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class DLLExport AlignDetectorInTOF : public API::Algorithm
{
public:
AlignDetectorInTOF();
virtual ~AlignDetectorInTOF();

/// Algorithm's name for identification overriding a virtual method
virtual const std::string name() const { return "AlignDetectorsInTOF";};
/// Algorithm's version for identification overriding a virtual method
virtual int version() const { return 1;};
/// Algorithm's category for identification overriding a virtual method
virtual const std::string category() const { return "Diffraction";}

private:
/// Sets documentation strings for this algorithm
virtual void initDocs();
// Implement abstract Algorithm methods
void init();

void exec();

void execTOFEvent(std::string calfilename, Mantid::API::MatrixWorkspace_const_sptr inputWS);

};


} // namespace Algorithms
} // namespace Mantid

#endif /* MANTID_ALGORITHMS_ALIGNDETECTORINTOF_H_ */
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class DLLExport AlignDetectors : public API::Algorithm

void execEvent();

void execTOFEvent(std::string calfilename, Mantid::API::MatrixWorkspace_const_sptr inputWS);
// void execTOFEvent(std::string calfilename, Mantid::API::MatrixWorkspace_const_sptr inputWS);

/// Pointer for an event workspace
Mantid::DataObjects::EventWorkspace_const_sptr eventW;
Expand Down
263 changes: 263 additions & 0 deletions Code/Mantid/Framework/Algorithms/src/AlignDetectorInTOF.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
/*WIKI*
The offsets are a correction to the TOF values and are applied to each TOF event as follows:
:<math> d = \frac{h}{2m_N} \frac{t.o.f.}{L_{tot} sin \theta} (1+ \rm{offset})</math>
The detector offsets can be obtained from either: an [[OffsetsWorkspace]] where each pixel has one value, the offset; or a .cal file (in the form created by the ARIEL software).
'''Note:''' the workspace that this algorithms outputs is a [[Ragged Workspace]].
==== Restrictions on the input workspace ====
The input workspace must contain histogram or event data where the X unit is time-of-flight and the Y data is raw counts. The [[instrument]] associated with the workspace must be fully defined because detector, source & sample position are needed.
*WIKI*/
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAlgorithms/AlignDetectorInTOF.h"
#include "MantidAPI/FileProperty.h"
#include "MantidAPI/SpectraDetectorMap.h"
#include "MantidAPI/WorkspaceValidators.h"
#include "MantidDataObjects/EventWorkspace.h"
#include "MantidDataObjects/OffsetsWorkspace.h"
#include "MantidKernel/V3D.h"
#include "MantidKernel/PhysicalConstants.h"
#include "MantidKernel/UnitFactory.h"
#include <fstream>
#include <sstream>

using namespace Mantid::Kernel;
using namespace Mantid::API;
using namespace Mantid::Geometry;
using namespace Mantid::DataObjects;
using Mantid::DataObjects::OffsetsWorkspace;

using namespace Mantid::Kernel;
using namespace Mantid::API;

namespace Mantid
{
namespace Algorithms
{

// Register the algorithm into the algorithm factory
DECLARE_ALGORITHM(AlignDetectorInTOF)

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

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


/// Sets documentation strings for this algorithm
void AlignDetectorInTOF::initDocs()
{
this->setWikiSummary("Performs correction on TOF value on each TOF. ");
this->setOptionalMessage("Performs correction on TOF value on each TOF.");
}

void AlignDetectorInTOF::init()
{
/*
CompositeWorkspaceValidator<> *wsValidator = new CompositeWorkspaceValidator<>;
//Workspace unit must be TOF.
wsValidator->add(new WorkspaceUnitValidator<>("TOF"));
wsValidator->add(new RawCountValidator<>);
wsValidator->add(new InstrumentValidator<>);
declareProperty( new WorkspaceProperty<API::MatrixWorkspace>("InputWorkspace","",Direction::Input,wsValidator),
"A workspace with units of TOF" );
*/

//Input workspace must be in dSpacing and be an inputWorkspace
API::CompositeWorkspaceValidator<EventWorkspace> *wsValidator2 = new API::CompositeWorkspaceValidator<EventWorkspace>;
wsValidator2->add(new API::WorkspaceUnitValidator<EventWorkspace>("TOF"));

declareProperty( new WorkspaceProperty<DataObjects::EventWorkspace>("InputWorkspace","",Direction::Input,wsValidator2),
"An EventWorkspace with units of TOF" );


declareProperty( new WorkspaceProperty<API::MatrixWorkspace>("OutputWorkspace","",Direction::Output),
"The name to use for the output workspace" );

std::vector<std::string> exts;
exts.push_back(".cal");
exts.push_back(".dat");
declareProperty(new FileProperty("CalibrationFile", "", FileProperty::OptionalLoad, exts),
"Optional: The .cal file containing the position correction factors. Either this or OffsetsWorkspace needs to be specified.");

}

//-----------------------------------------------------------------------
/** Executes the algorithm
* @throw Exception::FileError If the calibration file cannot be opened and read successfully
* @throw Exception::InstrumentDefinitionError If unable to obtain the source-sample distance
*/
void AlignDetectorInTOF::exec()
{
// Get the input workspace
MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");

// Read in the calibration data
const std::string calFileName = getProperty("CalibrationFile");
progress(0.0,"Reading calibration file");
if (calFileName.empty())
throw std::invalid_argument("You must specify CalibrationFile.");

if (calFileName.empty()){
throw std::invalid_argument("Must use Ke's calibration file in TOF");
}

this->execTOFEvent(calFileName, inputWS);

return;
}

/*
* Compute TOF with Offset
* @params
*
*/
void AlignDetectorInTOF::execTOFEvent(std::string calfilename, Mantid::API::MatrixWorkspace_const_sptr inputWS){

g_log.debug() << "Processing in TOF only!" << std::endl;

// 1. Read spectral - offset file
std::map<detid_t, double> specmap;

std::ifstream calfile(calfilename.c_str());
if (!calfile){
g_log.error() << "File " << calfilename << " is not readable" << std::endl;
}
std::string line;
detid_t specid;
double offset;
while(getline(calfile, line)){
std::istringstream ss(line);
ss >> specid >> offset;
specmap.insert(std::make_pair(specid, offset));
}

// 2. Convert to Eventworkspace and generate a new workspace for output
EventWorkspace_const_sptr eventWS = boost::dynamic_pointer_cast<const EventWorkspace>(inputWS);
if (!eventWS){
g_log.error() << "Input Worskspace is not EventWorkspace!" << std::endl;
throw std::invalid_argument("Input Workspace is not EventWorkspace");
}

API::MatrixWorkspace_sptr outputMatrixWS = this->getProperty("OutputWorkspace");
EventWorkspace_sptr outputWS;
if (outputMatrixWS == inputWS){
outputWS = boost::dynamic_pointer_cast<EventWorkspace>(outputMatrixWS);
} else {
outputWS = boost::dynamic_pointer_cast<EventWorkspace>(
API::WorkspaceFactory::Instance().create("EventWorkspace", eventWS->getNumberHistograms(), 2, 1));
API::WorkspaceFactory::Instance().initializeFromParent(eventWS, outputWS, false);
outputWS->copyDataFrom((*eventWS));

outputMatrixWS = boost::dynamic_pointer_cast<MatrixWorkspace>(outputWS);
this->setProperty("OutputWorkspace", outputMatrixWS);
}

// 3. Convert!
for (int ispec = 0; ispec < static_cast<int>(outputWS->getNumberHistograms()); ispec ++){
// For each spectrum

EventList events = outputWS->getEventList(ispec);
std::set<detid_t> detectorids = eventWS->getSpectrum(size_t(ispec))->getDetectorIDs();

// a) Check! There is only one possible detector ID in the set
if (detectorids.size() != 1){
g_log.error() << "Spectrum " << ispec << " Detectors = " << detectorids.size() << std::endl;
}

std::set<detid_t>::iterator setiter;
double shiftfactor = 1.0;
detid_t detid = 0;
for (setiter=detectorids.begin(); setiter != detectorids.end(); ++setiter){

detid = *setiter;
std::map<detid_t, double>::iterator mapiter = specmap.find(detid);
if (mapiter == specmap.end()){
// No match
g_log.error() << "Detector (ID) = " << detid << " Has No Entry In Calibration File" << std::endl;
} else {
// Matched
// i) Inner-module offset
double offset1 = mapiter->second;

// ii) Inter-module offset
detid_t index2 = detid_t(detid/1250)*1250+1250-2;
std::map<detid_t, double>::iterator itermodule = specmap.find(index2);
if (itermodule == specmap.end()){
throw std::invalid_argument("Inter-module offset cannot be found");
}
double offset2 = itermodule->second;

// iii) Inter-stack offset
detid_t index3 = index2 + 1;
std::map<detid_t, double>::iterator iterstack = specmap.find(index3);
if (iterstack == specmap.end()){
throw std::invalid_argument("Inter-stack offset cannot be found");
}
double offset3 = iterstack->second;

// iv) overall factor
shiftfactor = pow(10.0, -(offset1+offset2+offset3));

/*
if (ispec < 30){
g_log.notice() << "Detector " << detid << " Shift Factor = " << shiftfactor << " Inner-module = " << offset1 << std::endl;
}
*/
}

} // for one and only one detector
if (ispec < 30){
g_log.notice() << "Detector " << detid << " Shift Factor = " << shiftfactor << " Number of events = " << events.getNumberEvents() << std::endl;
}

/*
if (ispec == 11){
std::vector<double> tofs;
outputWS->getEventList(ispec).getTofs(tofs);
// events.getTofs(tofs);
g_log.notice() << "Before: TOF[0] = " << tofs[0] << std::endl;
}
*/
outputWS->getEventList(ispec).convertTof(shiftfactor, 0.0);
/*
if (ispec == 11){
std::vector<double> tofs;
events.getTofs(tofs);
g_log.notice() << "After: TOF[0] = " << tofs[0] << std::endl;
}
*/

} // for spec

// Another check
/*
EventList checklist = outputWS->getEventList(11);
std::vector<double> tofs;
checklist.getTofs(tofs);
g_log.notice() << "Final Check: TOF[11][0]" << tofs[0] << std::endl;
*/

return;
}

} // namespace Mantid
} // namespace Algorithms

0 comments on commit d527847

Please sign in to comment.