Skip to content

Commit

Permalink
Merge branch 'tube_calibration_1' into develop re #6344
Browse files Browse the repository at this point in the history
Conflicts:
	Code/Mantid/Framework/Algorithms/src/ApplyCalibration.cpp

Signed-off-by: Karl Palmen <karl.palmen@stfc.ac.uk>
  • Loading branch information
KarlPalmen committed Mar 7, 2013
2 parents 804e126 + cb5fed5 commit a00da7c
Show file tree
Hide file tree
Showing 6 changed files with 383 additions and 27 deletions.
1 change: 1 addition & 0 deletions Code/Mantid/Framework/Algorithms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,7 @@ set ( TEST_FILES
AlphaCalcTest.h
AnyShapeAbsorptionTest.h
AppendSpectraTest.h
ApplyCalibrationTest.h
ApplyDeadTimeCorrTest.h
ApplyDetailedBalanceTest.h
ApplyTransmissionCorrectionTest.h
Expand Down
37 changes: 10 additions & 27 deletions Code/Mantid/Framework/Algorithms/src/ApplyCalibration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ The PositionTable must have columns ''Detector ID'' and ''Detector Position''. T
#include "MantidGeometry/Instrument/Component.h"
#include "MantidAPI/FileProperty.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidGeometry/Instrument/ComponentHelper.h"
#include <boost/scoped_ptr.hpp>

namespace Mantid
Expand All @@ -33,7 +34,7 @@ namespace Mantid
using Geometry::Instrument;
using Geometry::Instrument_sptr;
using Geometry::IDetector_sptr;
using Kernel::V3D;
using Geometry::IComponent_const_sptr;

/// Empty default constructor
ApplyCalibration::ApplyCalibration()
Expand Down Expand Up @@ -91,32 +92,14 @@ namespace Mantid
*/
void ApplyCalibration::setDetectorPosition(const Geometry::Instrument_const_sptr & instrument, int detID, V3D pos, bool /*sameParent*/ )
{
Geometry::IDetector_const_sptr det = instrument->getDetector(detID);
// Then find the corresponding relative position
boost::shared_ptr<const Geometry::IComponent> parent = det->getParent();
if (parent)
{
pos -= parent->getPos();
Quat rot = parent->getRelativeRot();
rot.inverse();
rot.rotate(pos);
}
boost::shared_ptr<const Geometry::IComponent>grandparent = parent->getParent();
if (grandparent)
{
Quat rot = grandparent->getRelativeRot();
rot.inverse();
rot.rotate(pos);
boost::shared_ptr<const Geometry::IComponent>greatgrandparent = grandparent->getParent();
if (greatgrandparent) {
Quat rot2 = greatgrandparent->getRelativeRot();
rot2.inverse();
rot2.rotate(pos);
}
}

// Add a parameter for the new position
m_pmap->addV3D(det.get(), "pos", pos);

IComponent_const_sptr det =instrument->getDetector(detID); ;
// Do the move
using namespace Geometry::ComponentHelper;
TransformType positionType = Absolute;
// TransformType positionType = Relative;
Geometry::ComponentHelper::moveComponent(*det, *m_pmap, pos, positionType);

}

} // namespace Algorithms
Expand Down
155 changes: 155 additions & 0 deletions Code/Mantid/Framework/Algorithms/test/ApplyCalibrationTest.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
#ifndef APPLYCALIBRATIONTEST_H_
#define APPLYCALIBRATIONTEST_H_

#include <cxxtest/TestSuite.h>

#include "MantidDataHandling/LoadInstrument.h"
#include "MantidAPI/IAlgorithm.h"
#include "MantidAlgorithms/ApplyCalibration.h"
#include "MantidAPI/Workspace.h"
#include "MantidDataObjects/Workspace2D.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "WorkspaceCreationHelperTest.h"
#include "MantidAPI/AnalysisDataService.h"
#include "MantidAPI/ITableWorkspace.h"
#include "MantidAPI/TableRow.h"
#include "MantidKernel/V3D.h"
#include "MantidGeometry/Instrument.h"
#include "MantidGeometry/Instrument/Component.h"
#include "MantidDataHandling/LoadEmptyInstrument.h"
#include <stdexcept>

using namespace Mantid::Algorithms;
using namespace Mantid::API;
using namespace Mantid::Kernel;
using namespace Mantid::DataObjects;
using Mantid::Geometry::IDetector_const_sptr;

class ApplyCalibrationTest : public CxxTest::TestSuite
{
public:

void testName()
{
TS_ASSERT_EQUALS( appCalib.name(), "ApplyCalibration" )
}

void testInit()
{
appCalib.initialize();
TS_ASSERT( appCalib.isInitialized() )
}

void testSimple()
{

int ndets = 3;

// Create workspace with paremeterised instrument and put into data store
Workspace2D_sptr ws = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(ndets, 10, true);
const std::string wsName("ApplyCabrationWs");
AnalysisDataServiceImpl & dataStore = AnalysisDataService::Instance();
dataStore.add(wsName, ws);

// Create Calibration Table
ITableWorkspace_sptr posTableWs = WorkspaceFactory::Instance().createTable();
posTableWs->addColumn("int","Detector ID");
posTableWs->addColumn("V3D","Detector Position");

for(int i=0; i < ndets; ++i)
{
TableRow row = posTableWs->appendRow();
row << i+1 << V3D(1.0,0.01*i,2.0);
}
TS_ASSERT_THROWS_NOTHING(appCalib.setPropertyValue("Workspace", wsName ));
TS_ASSERT_THROWS_NOTHING(appCalib.setProperty<ITableWorkspace_sptr>("PositionTable", posTableWs ));
TS_ASSERT_THROWS_NOTHING(appCalib.execute());

TS_ASSERT( appCalib.isExecuted() );

IDetector_const_sptr det = ws->getDetector(0);
int id = det->getID();
V3D newPos = det->getPos();
TS_ASSERT_EQUALS( id, 1);
TS_ASSERT_DELTA( newPos.X() , 1.0, 0.0001);
TS_ASSERT_DELTA( newPos.Y() , 0.0, 0.0001);
TS_ASSERT_DELTA( newPos.Z() , 2.0, 0.0001);

det = ws->getDetector(ndets-1);
id = det->getID();
newPos = det->getPos();
TS_ASSERT_EQUALS( id, ndets);
TS_ASSERT_DELTA( newPos.X() , 1.0, 0.0001);
TS_ASSERT_DELTA( newPos.Y() , 0.01*(ndets-1), 0.0001);
TS_ASSERT_DELTA( newPos.Z() , 2.0, 0.0001);
}

void testComplex()
{
/* The purpse of this test is to test the algorithm when the relative positioning and rotation
* of components is complicated. This is the case for the MAPS instrument and so here we
* load the IDF of a MAPS instrument where the number of detectors has been reduced.
*/

int ndets = 3;

// Create workspace with a reduced MAPS instrument (parametrised) and retrieve vfrom data store.
const std::string wsName("ApplyCabrationWs");
Mantid::DataHandling::LoadEmptyInstrument loader;
loader.initialize();
loader.setPropertyValue("Filename", "IDFs_For_UNIT_TESTING/MAPS_Definition_reduced.xml");
loader.setPropertyValue("OutputWorkspace", wsName);
loader.execute();
AnalysisDataServiceImpl & dataStore = AnalysisDataService::Instance();
MatrixWorkspace_sptr ws = dataStore.retrieveWS<MatrixWorkspace>(wsName);

// Create Calibration Table
int firstDetectorID = 34208002;
ITableWorkspace_sptr posTableWs = WorkspaceFactory::Instance().createTable();
posTableWs->addColumn("int","Detector ID");
posTableWs->addColumn("V3D","Detector Position");

for(int i=0; i < ndets; ++i)
{
TableRow row = posTableWs->appendRow();
row << firstDetectorID + 10*i << V3D(1.0,0.01*i,2.0);
}
TS_ASSERT_THROWS_NOTHING(appCalib.setPropertyValue("Workspace", wsName ));
TS_ASSERT_THROWS_NOTHING(appCalib.setProperty<ITableWorkspace_sptr>("PositionTable", posTableWs ));
TS_ASSERT_THROWS_NOTHING(appCalib.execute());

TS_ASSERT( appCalib.isExecuted() );

IDetector_const_sptr det = ws->getDetector(1830);
int id = det->getID();
V3D newPos = det->getPos();
TS_ASSERT_EQUALS( id, firstDetectorID);
TS_ASSERT_DELTA( newPos.X() , 1.0, 0.0001);
TS_ASSERT_DELTA( newPos.Y() , 0.0, 0.0001);
TS_ASSERT_DELTA( newPos.Z() , 2.0, 0.0001);

det = ws->getDetector(1840);
id = det->getID();
newPos = det->getPos();
TS_ASSERT_EQUALS( id, firstDetectorID + 10);
TS_ASSERT_DELTA( newPos.X() , 1.0, 0.0001);
TS_ASSERT_DELTA( newPos.Y() , 0.01, 0.0001);
TS_ASSERT_DELTA( newPos.Z() , 2.0, 0.0001);

det = ws->getDetector(1850);
id = det->getID();
newPos = det->getPos();
TS_ASSERT_EQUALS( id, firstDetectorID + 20);
TS_ASSERT_DELTA( newPos.X() , 1.0, 0.0001);
TS_ASSERT_DELTA( newPos.Y() , 0.02, 0.0001);
TS_ASSERT_DELTA( newPos.Z() , 2.0, 0.0001);
}


private:
ApplyCalibration appCalib;


};

#endif /*APPLYCALIBRATIONTEST_H_*/
73 changes: 73 additions & 0 deletions Code/Mantid/scripts/Calibration/Examples/TubeCalibDemoMaps_All.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#
# TUBE CALIBRATION DEMONSTRATION PROGRAM FOR MAPS - Execute this
#
# Here we run the calibration of a selected part of MAPS

#
from mantid.api import WorkspaceFactory # For table worskspace of calibrations
from tube_calib_fit_params import * # To handle fit parameters
from ideal_tube import * # For ideal tube
from tube_calib import * # For tube calibration functions
from tube_spec import * # For tube specification class


# == Set parameters for calibration ==

path = r"C:/Temp/" # Path name of folder containing input and output files
filename = 'MAPS14919.raw' # Name of calibration run
rangeLower = 2000 # Integrate counts in each spectra from rangeLower to rangeUpper
rangeUpper = 10000 #


# Set initial parameters for peak finding
ExpectedHeight = -1000.0 # Expected Height of Peaks (initial value of fit parameter)
ExpectedWidth = 8.0 # Expected width of centre peak (initial value of fit parameter)
ExpectedPositions = [4.0, 85.0, 128.0, 161.0, 252.0] # Expected positions of the edges and peak (initial values of fit parameters)

# Set what we want to calibrate (e.g whole intrument or one door )
CalibratedComponent = 'MAPS' # Calibrate all


# Get calibration raw file and integrate it
rawCalibInstWS = Load(path+filename) #'raw' in 'rawCalibInstWS' means unintegrated.
print "Integrating Workspace"
CalibInstWS = Integration( rawCalibInstWS, RangeLower=rangeLower, RangeUpper=rangeUpper )
DeleteWorkspace(rawCalibInstWS)
print "Created workspace (CalibInstWS) with integrated data from run and instrument to calibrate"

# == Create Objects needed for calibration ==

#Create Calibration Table
calibrationTable = CreateEmptyTableWorkspace(OutputWorkspace="CalibTable")
calibrationTable.addColumn(type="int",name="Detector ID") # "Detector ID" column required by ApplyCalbration
calibrationTable.addColumn(type="V3D",name="Detector Position") # "Detector Position" column required by ApplyCalbration

# Specify component to calibrate
thisTubeSet = TubeSpec(CalibInstWS)
thisTubeSet.setTubeSpecByString(CalibratedComponent)

# Get ideal tube
iTube = IdealTube()
# Set positions of where the shadows and ends should be.
# An intelligent guess is used here that is not correct for all tubes.
iTube.setPositionsAndForm([-0.50,-0.16,-0.00, 0.16, 0.50 ],[2,1,1,1,2])

# Get fitting parameters
fitPar = TubeCalibFitParams( ExpectedPositions, ExpectedHeight, ExpectedWidth )

print "Created objects needed for calibration."

# == Get the calibration and put results into calibration table ==
# also put peaks into PeakFile
getCalibration( CalibInstWS, thisTubeSet, calibrationTable, fitPar, iTube, PeakFile=path+'TubeDemoMaps01.txt' )
print "Got calibration (new positions of detectors) "

# == Apply the Calibation ==
ApplyCalibration( Workspace=CalibInstWS, PositionTable=calibrationTable)
print "Applied calibration"


# == Save workspace ==
SaveNexusProcessed( CalibInstWS, path+'TubeCalibDemoMapsResult.nxs',"Result of Running TCDemoMaps.py")
print "saved calibrated workspace (CalibInstWS) into Nexus file TubeCalibDemoMapsResult.nxs"

72 changes: 72 additions & 0 deletions Code/Mantid/scripts/Calibration/Examples/TubeCalibDemoMaps_B1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#
# TUBE CALIBRATION DEMONSTRATION PROGRAM FOR MAPS - Execute this
#
# Here we run the calibration of a selected part of MAPS

#
from mantid.api import WorkspaceFactory # For table worskspace of calibrations
from tube_calib_fit_params import * # To handle fit parameters
from ideal_tube import * # For ideal tube
from tube_calib import * # For tube calibration functions
from tube_spec import * # For tube specification class


# == Set parameters for calibration ==

path = r"C:/Temp/" # Path name of folder containing input and output files
filename = 'MAPS14919.raw' # Name of calibration run
rangeLower = 2000 # Integrate counts in each spectra from rangeLower to rangeUpper
rangeUpper = 10000 #


# Set initial parameters for peak finding
ExpectedHeight = -1000.0 # Expected Height of Peaks (initial value of fit parameter)
ExpectedWidth = 8.0 # Expected width of centre peak (initial value of fit parameter)
ExpectedPositions = [4.0, 85.0, 128.0, 161.0, 252.0] # Expected positions of the edges and peak (initial values of fit parameters)

# Set what we want to calibrate (e.g whole intrument or one door )
CalibratedComponent = 'B1_window' # Calibrate B1 window


# Get calibration raw file and integrate it
rawCalibInstWS = Load(path+filename) #'raw' in 'rawCalibInstWS' means unintegrated.
print "Integrating Workspace"
CalibInstWS = Integration( rawCalibInstWS, RangeLower=rangeLower, RangeUpper=rangeUpper )
DeleteWorkspace(rawCalibInstWS)
print "Created workspace (CalibInstWS) with integrated data from run and instrument to calibrate"

# == Create Objects needed for calibration ==

#Create Calibration Table
calibrationTable = CreateEmptyTableWorkspace(OutputWorkspace="CalibTable")
calibrationTable.addColumn(type="int",name="Detector ID") # "Detector ID" column required by ApplyCalbration
calibrationTable.addColumn(type="V3D",name="Detector Position") # "Detector Position" column required by ApplyCalbration

# Specify component to calibrate
thisTubeSet = TubeSpec(CalibInstWS)
thisTubeSet.setTubeSpecByString(CalibratedComponent)

# Get ideal tube
iTube = IdealTube()
# The positions of the shadows and ends here are an intelligent guess.
iTube.setPositionsAndForm([-0.50,-0.165,-0.00, 0.165, 0.50 ],[2,1,1,1,2])

# Get fitting parameters
fitPar = TubeCalibFitParams( ExpectedPositions, ExpectedHeight, ExpectedWidth )

print "Created objects needed for calibration."

# == Get the calibration and put results into calibration table ==
# also put peaks into PeakFile
getCalibration( CalibInstWS, thisTubeSet, calibrationTable, fitPar, iTube, PeakFile=path+'TubeDemoMaps01.txt' )
print "Got calibration (new positions of detectors) "

# == Apply the Calibation ==
ApplyCalibration( Workspace=CalibInstWS, PositionTable=calibrationTable)
print "Applied calibration"


# == Save workspace ==
SaveNexusProcessed( CalibInstWS, path+'TubeCalibDemoMapsResult.nxs',"Result of Running TCDemoMaps.py")
print "saved calibrated workspace (CalibInstWS) into Nexus file TubeCalibDemoMapsResult.nxs"

0 comments on commit a00da7c

Please sign in to comment.