Skip to content

Commit

Permalink
Refs #11736 Add extra length option for gravity
Browse files Browse the repository at this point in the history
  • Loading branch information
AntonPiccardoSelg committed May 14, 2015
1 parent 2b4d99f commit d7d330c
Show file tree
Hide file tree
Showing 12 changed files with 131 additions and 48 deletions.
3 changes: 1 addition & 2 deletions Code/Mantid/Framework/API/inc/MantidAPI/MatrixWorkspace.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,7 @@ class MANTID_API_DLL MatrixWorkspace : public IMDWorkspace,
Geometry::IDetector_const_sptr getDetector(const size_t workspaceIndex) const;
double detectorTwoTheta(Geometry::IDetector_const_sptr det) const;
double detectorSignedTwoTheta(Geometry::IDetector_const_sptr det) const;
double gravitationalDrop(Geometry::IDetector_const_sptr det,
const double waveLength) const;

//@}

virtual void populateInstrumentParameters();
Expand Down
26 changes: 0 additions & 26 deletions Code/Mantid/Framework/API/src/MatrixWorkspace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -813,33 +813,7 @@ MatrixWorkspace::detectorTwoTheta(Geometry::IDetector_const_sptr det) const {
return det->getTwoTheta(samplePos, beamLine);
}

/**Calculates the distance a neutron coming from the sample will have deviated
* from a
* straight tragetory before hitting a detector. If calling this function many
* times
* for the same detector you can call this function once, with waveLength=1, and
* use
* the fact drop is proportional to wave length squared .This function has no
* knowledge
* of which axis is vertical for a given instrument
* @param det :: the detector that the neutron entered
* @param waveLength :: the neutrons wave length in meters
* @return the deviation in meters
*/
double MatrixWorkspace::gravitationalDrop(Geometry::IDetector_const_sptr det,
const double waveLength) const {
using namespace PhysicalConstants;
/// Pre-factor in gravity calculation: gm^2/2h^2
static const double gm2_OVER_2h2 =
g * NeutronMass * NeutronMass / (2.0 * h * h);

const V3D samplePos = getInstrument()->getSample()->getPos();
const double pathLength = det->getPos().distance(samplePos);
// Want L2 (sample-pixel distance) squared, times the prefactor g^2/h^2
const double L2 = gm2_OVER_2h2 * std::pow(pathLength, 2);

return waveLength * waveLength * L2;
}

//---------------------------------------------------------------------------------------
/** Add parameters to the instrument parameter map that are defined in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ class GravitySANSHelper {
GravitySANSHelper()
: m_beamLineNorm(-1), m_dropPerAngstrom2(-1), m_cachedDrop(-1) {}
GravitySANSHelper(API::MatrixWorkspace_const_sptr ws,
Geometry::IDetector_const_sptr det);
Geometry::IDetector_const_sptr det,
const double extraLength = 0.0);
double calcSinTheta(const double wavAngstroms) const;
double calcComponents(const double wavAngstroms, double &xFrac,
double &yFrac) const;
Expand Down Expand Up @@ -71,6 +72,11 @@ class GravitySANSHelper {
double gravitationalDrop(const double wav) const {
return m_dropPerAngstrom2 * wav * wav;
}

double gravitationalDrop(API::MatrixWorkspace_const_sptr ws,
Geometry::IDetector_const_sptr det,
const double waveLength,
const double extraLength) const;
double calcSinTheta() const;
};
}
Expand Down
3 changes: 2 additions & 1 deletion Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/Q1D2.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ class DLLExport Q1D2 : public API::Algorithm {
const MantidVec::iterator theNorms,
const MantidVec::iterator errorSquared) const;
void convertWavetoQ(const size_t specInd, const bool doGravity,
const size_t offset, MantidVec::iterator Qs) const;
const size_t offset, MantidVec::iterator Qs,
const double extraLength) const;
void getQBinPlus1(const MantidVec &OutQs, const double QToFind,
MantidVec::const_iterator &loc) const;
void normalize(const MantidVec &normSum, const MantidVec &normError2,
Expand Down
39 changes: 36 additions & 3 deletions Code/Mantid/Framework/Algorithms/src/GravitySANSHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ using Kernel::V3D;
* @param det :: the detector for which the calculations will be for
*/
GravitySANSHelper::GravitySANSHelper(API::MatrixWorkspace_const_sptr ws,
Geometry::IDetector_const_sptr det)
Geometry::IDetector_const_sptr det,
const double extraLength)
: m_beamLineNorm(-1), m_det(det), m_dropPerAngstrom2(-1), m_cachedDrop(0) {
m_samplePos = ws->getInstrument()->getSample()->getPos();
const V3D sourcePos = ws->getInstrument()->getSource()->getPos();
Expand All @@ -25,7 +26,7 @@ GravitySANSHelper::GravitySANSHelper(API::MatrixWorkspace_const_sptr ws,
m_cachedLineOfSight = m_det->getPos() - m_samplePos;
// the drop is proportional to the wave length squared and using this to do
// the full calculation only once increases the speed a lot
m_dropPerAngstrom2 = ws->gravitationalDrop(m_det, 1e-10);
m_dropPerAngstrom2 = gravitationalDrop(ws, m_det, 1e-10, extraLength);
}
/** Caclulates the sin of the that the neutron left the sample at, before the
* effect of gravity
Expand Down Expand Up @@ -79,5 +80,37 @@ double GravitySANSHelper::calcSinTheta() const {
// This is sin(theta)
return sqrt(0.5 - halfcosTheta);
}
}


/**Calculates the distance a neutron coming from the sample will have deviated
* from a
* straight tragetory before hitting a detector. If calling this function many
* times
* for the same detector you can call this function once, with waveLength=1, and
* use
* the fact drop is proportional to wave length squared .This function has no
* knowledge
* of which axis is vertical for a given instrument
* @param ws :: workspace
* @param det :: the detector that the neutron entered
* @param waveLength :: the neutrons wave length in meters
* @param extraLength :: additional length
* @return the deviation in meters
*/
double GravitySANSHelper::gravitationalDrop(API::MatrixWorkspace_const_sptr ws,
Geometry::IDetector_const_sptr det,
const double waveLength,
const double extraLength) const {
using namespace PhysicalConstants;
/// Pre-factor in gravity calculation: gm^2/2h^2
static const double gm2_OVER_2h2 =
g * NeutronMass * NeutronMass / (2.0 * h * h);

const V3D samplePos = ws->getInstrument()->getSample()->getPos();
const double pathLength = det->getPos().distance(samplePos) + extraLength;
// Want L2 (sample-pixel distance) squared, times the prefactor g^2/h^2
const double L2 = gm2_OVER_2h2 * std::pow(pathLength, 2);

return waveLength * waveLength * L2;
}}
}
11 changes: 8 additions & 3 deletions Code/Mantid/Framework/Algorithms/src/Q1D2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ void Q1D2::init() {
"_sumOfCounts and _sumOfNormFactors equals the workspace"
" returned by the property OutputWorkspace "
"(default is false).");
declareProperty(
"ExtraLength", 0.0, mustBePositive,
"Additional length for gravity correction.");
}
/**
@ throw invalid_argument if the workspaces are not mututially compatible
Expand Down Expand Up @@ -173,7 +176,7 @@ void Q1D2::exec() {
binNormEs, norms, normETo2s);

// now read the data from the input workspace, calculate Q for each bin
convertWavetoQ(i, doGravity, wavStart, QIn);
convertWavetoQ(i, doGravity, wavStart, QIn, getProperty("ExtraLength"));

// Pointers to the counts data and it's error
MantidVec::const_iterator YIn = m_dataWS->readY(i).begin() + wavStart;
Expand Down Expand Up @@ -483,13 +486,15 @@ void Q1D2::normToMask(const size_t offSet, const size_t specIndex,
* @param[in] specInd the spectrum to calculate
* @param[in] doGravity if to include gravity in the calculation of Q
* @param[in] offset index number of the first input bin to use
* @param[in] extraLength for gravitational correction
* @param[out] Qs points to a preallocated array that is large enough to contain
* all the calculated Q values
* @throw NotFoundError if the detector associated with the spectrum is not
* found in the instrument definition
*/
void Q1D2::convertWavetoQ(const size_t specInd, const bool doGravity,
const size_t offset, MantidVec::iterator Qs) const {
const size_t offset, MantidVec::iterator Qs,
const double extraLength) const {
static const double FOUR_PI = 4.0 * M_PI;

IDetector_const_sptr det = m_dataWS->getDetector(specInd);
Expand All @@ -499,7 +504,7 @@ void Q1D2::convertWavetoQ(const size_t specInd, const bool doGravity,
// going from bin boundaries to bin centered x-values the size goes down one
const MantidVec::const_iterator end = m_dataWS->readX(specInd).end() - 1;
if (doGravity) {
GravitySANSHelper grav(m_dataWS, det);
GravitySANSHelper grav(m_dataWS, det, extraLength);
for (; waves != end; ++Qs, ++waves) {
// the HistogramValidator at the start should ensure that we have one more
// bin on the input wavelengths
Expand Down
4 changes: 3 additions & 1 deletion Code/Mantid/Framework/Algorithms/src/Qxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ void Qxy::init() {
"OutputWorkspace_sumOfNormFactors. The division of "
"_sumOfCounts and _sumOfNormFactors equals the workspace "
"returned by the property OutputWorkspace");
declareProperty("ExtraLength", 0.0, mustBePositive,
"Additional length for gravity correction.");
}

void Qxy::exec() {
Expand Down Expand Up @@ -187,7 +189,7 @@ void Qxy::exec() {
// constructed once per spectrum
GravitySANSHelper grav;
if (doGravity) {
grav = GravitySANSHelper(inputWorkspace, det);
grav = GravitySANSHelper(inputWorkspace, det, getProperty("ExtraLength"));
}

for (int j = static_cast<int>(numBins) - 1; j >= static_cast<int>(wavStart);
Expand Down
2 changes: 1 addition & 1 deletion Code/Mantid/Framework/Algorithms/test/Q1D2Test.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ class Q1D2Test : public CxxTest::TestSuite

Mantid::API::AnalysisDataService::Instance().remove(outputWS);
}

void testCuts()
{
Mantid::Algorithms::Q1D2 Q1D;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
<string notr="true"/>
</property>
<property name="currentIndex">
<number>5</number>
<number>1</number>
</property>
<property name="elideMode">
<enum>Qt::ElideNone</enum>
Expand Down Expand Up @@ -868,6 +868,42 @@
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_23">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_15">
<property name="text">
<string>Extra Length</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="gravity_extra_length_line_edit">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>70</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
Expand Down
11 changes: 9 additions & 2 deletions Code/Mantid/MantidQt/CustomInterfaces/src/SANSRunWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -951,7 +951,12 @@ bool SANSRunWindow::loadUserFile()
{
m_uiForm.gravity_check->setChecked(false);
}


// Read the extra length for the gravity correction
const double extraLengthParam = runReduceScriptFunction(
"print i.ReductionSingleton().to_Q.get_extra_length()").toDouble();
m_uiForm.gravity_extra_length_line_edit->setText(QString::number(extraLengthParam));

////Detector bank: support REAR, FRONT, HAB, BOTH, MERGED, MERGE options
QString detName = runReduceScriptFunction(
"print i.ReductionSingleton().instrument.det_selection").trimmed();
Expand Down Expand Up @@ -2268,7 +2273,9 @@ QString SANSRunWindow::readUserFileGUIChanges(const States type)
{
exec_reduce += "False";
}
exec_reduce += ")\n";
// Take into acount of the additional length
exec_reduce += ", extra_length=" + m_uiForm.gravity_extra_length_line_edit->text().trimmed() + ")\n";

//Sample offset
exec_reduce += "i.SetSampleOffset('"+
m_uiForm.smpl_offset->text()+"')\n";
Expand Down
5 changes: 3 additions & 2 deletions Code/Mantid/scripts/SANS/ISISCommandInterface.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,10 @@ def SetTransSpectrum(specNum, interp=False):
def SetSampleOffset(value):
ReductionSingleton().instrument.set_sample_offset(value)

def Gravity(flag):
_printMessage('Gravity(' + str(flag) + ')')
def Gravity(flag, extra_length = 0.0):
_printMessage('Gravity(' + str(flag) + ', '+ str(extra_length) + ')')
ReductionSingleton().to_Q.set_gravity(flag)
ReductionSingleton().to_Q.set_extra_length(extra_length)

def SetFrontDetRescaleShift(scale=1.0, shift=0.0, fitScale=False, fitShift=False, qMin=None, qMax=None):
"""
Expand Down
29 changes: 24 additions & 5 deletions Code/Mantid/scripts/SANS/isis_reduction_steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -1672,6 +1672,7 @@ class ConvertToQISIS(ReductionStep):
'2D' : 'Qxy'}
# defines if Q1D should correct for gravity by default
_DEFAULT_GRAV = False
_DEFAULT_EXTRA_LENGTH = 0.0
def __init__(self, normalizations):
"""
@param normalizations: CalculateNormISIS object contains the workspace, ReductionSteps or files require for the optional normalization arguments
Expand All @@ -1689,6 +1690,8 @@ def __init__(self, normalizations):
self._use_gravity = self._DEFAULT_GRAV
#used to implement a default setting for gravity that can be over written but doesn't over write
self._grav_set = False
#can be used to add an additional length to the neutron path during the correction for gravity in the Q calcuation
self._grav_extra_length = self._DEFAULT_EXTRA_LENGTH
#this should contain the rebin parameters
self.binning = None

Expand Down Expand Up @@ -1733,6 +1736,16 @@ def set_gravity(self, flag, override=True):
print msg
sanslog.warning(msg)

def get_extra_length(self):
return self._grav_extra_length

def set_extra_length(self, extra_length):
"""
Add extra length when correcting for gravity when calculating Q
@param extra_length : additional length for the gravity correction during the calculation of Q
"""
self._grav_extra_length = extra_length

def execute(self, reducer, workspace):
"""
Calculate the normalization workspaces and then call the chosen Q conversion algorithm.
Expand All @@ -1754,9 +1767,9 @@ def execute(self, reducer, workspace):

try:
if self._Q_alg == 'Q1D':
Q1D(DetBankWorkspace=workspace,OutputWorkspace= workspace, OutputBinning=self.binning, WavelengthAdj=wave_adj, PixelAdj=pixel_adj, AccountForGravity=self._use_gravity, RadiusCut=self.r_cut*1000.0, WaveCut=self.w_cut, OutputParts=self.outputParts, WavePixelAdj = wavepixeladj)
Q1D(DetBankWorkspace=workspace,OutputWorkspace= workspace, OutputBinning=self.binning, WavelengthAdj=wave_adj, PixelAdj=pixel_adj, AccountForGravity=self._use_gravity, RadiusCut=self.r_cut*1000.0, WaveCut=self.w_cut, OutputParts=self.outputParts, WavePixelAdj = wavepixeladj, ExtraLength=self._grav_extra_length)
elif self._Q_alg == 'Qxy':
Qxy(InputWorkspace=workspace,OutputWorkspace= workspace,MaxQxy= reducer.QXY2,DeltaQ= reducer.DQXY, WavelengthAdj=wave_adj, PixelAdj=pixel_adj, AccountForGravity=self._use_gravity, RadiusCut=self.r_cut*1000.0, WaveCut=self.w_cut, OutputParts=self.outputParts)
Qxy(InputWorkspace=workspace,OutputWorkspace= workspace,MaxQxy= reducer.QXY2,DeltaQ= reducer.DQXY, WavelengthAdj=wave_adj, PixelAdj=pixel_adj, AccountForGravity=self._use_gravity, RadiusCut=self.r_cut*1000.0, WaveCut=self.w_cut, OutputParts=self.outputParts, ExtraLength=self._grav_extra_length)
ReplaceSpecialValues(InputWorkspace=workspace,OutputWorkspace= workspace, NaNValue="0", InfinityValue="0")
else:
raise NotImplementedError('The type of Q reduction has not been set, e.g. 1D or 2D')
Expand Down Expand Up @@ -2068,15 +2081,21 @@ def read_line(self, line, reducer):
# for /DET/FRONT and /DET/REAR commands
reducer.instrument.setDetector(det_specif)

# There are two entries for Gravity: 1. ON/OFF (TRUE/FALSE)
# 2. LEXTRA=xx.xx
elif upper_line.startswith('GRAVITY'):
flag = upper_line[8:].strip()
if flag == 'ON' or flag == 'TRUE':
grav = upper_line[8:].strip()
if grav == 'ON' or grav == 'TRUE':
reducer.to_Q.set_gravity(True, override=False)
elif flag == 'OFF' or flag == 'FALSE':
elif grav == 'OFF' or grav == 'FALSE':
reducer.to_Q.set_gravity(False, override=False)
elif grav.startswith('LEXTRA'):
extra_length = grav[6:].strip()
reducer.to_Q.set_extra_length(float(extra_length))
else:
_issueWarning("Gravity flag incorrectly specified, disabling gravity correction")
reducer.to_Q.set_gravity(False, override=False)
reducer.to_Q.set_extra_length(0.0)

elif upper_line.startswith('FIT/TRANS/'):
#check if the selector is passed:
Expand Down

0 comments on commit d7d330c

Please sign in to comment.