Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
mantidproject
mantid
Commits
7d3a2f10
Unverified
Commit
7d3a2f10
authored
Mar 12, 2021
by
Zhang, Chen
Committed by
GitHub
Mar 12, 2021
Browse files
Merge pull request #30844 from mantidproject/SCD218_newObjFuncSCDCalibratePanels_216
Scd218 new obj func scd calibrate panels 216
parents
bba6c826
1393d52d
Changes
6
Hide whitespace changes
Inline
Side-by-side
Framework/Crystal/inc/MantidCrystal/SCDCalibratePanels2.h
View file @
7d3a2f10
...
...
@@ -31,6 +31,7 @@ namespace Crystal {
*
* Spirit successor of ISAW and its reincarnation: SCDCalibratePanels
*/
class
MANTID_CRYSTAL_DLL
SCDCalibratePanels2
:
public
Mantid
::
API
::
Algorithm
{
public:
/// Algorithm's name for identification
...
...
@@ -65,34 +66,48 @@ private:
std
::
map
<
std
::
string
,
std
::
string
>
validateInputs
()
override
;
/// Private function dedicated for parsing lattice constant
void
parseLatticeConstant
(
std
::
shared_ptr
<
Mantid
::
DataObjects
::
PeaksWorkspace
>
pws
);
void
parseLatticeConstant
(
Mantid
::
API
::
IPeaksWorkspace_sptr
pws
);
/// Update the UB matrix
void
updateUBMatrix
(
std
::
shared_ptr
<
Mantid
::
DataObjects
::
PeaksWorkspace
>
pws
);
void
updateUBMatrix
(
Mantid
::
API
::
IPeaksWorkspace_sptr
pws
);
/// Remove unindexed peaks from workspace
Mantid
::
API
::
IPeaksWorkspace_sptr
removeUnindexedPeaks
(
Mantid
::
API
::
IPeaksWorkspace_sptr
pws
);
/// Private function for getting names of banks to be calibrated
void
getBankNames
(
std
::
shared_ptr
<
Mantid
::
DataObjects
::
PeaksWorkspace
>
pws
);
void
getBankNames
(
Mantid
::
API
::
I
PeaksWorkspace
_sptr
pws
);
/// Private function for calibrating T0
void
optimizeT0
(
std
::
shared_ptr
<
Mantid
::
DataObjects
::
PeaksWorkspace
>
pws
);
void
optimizeT0
(
Mantid
::
API
::
I
PeaksWorkspace
_sptr
pws
);
/// Private function for calibrating L1
void
optimizeL1
(
std
::
shared_ptr
<
Mantid
::
DataObjects
::
PeaksWorkspace
>
pws
);
void
optimizeL1
(
Mantid
::
API
::
I
PeaksWorkspace
_sptr
pws
);
/// Private function for calibrating banks
void
optimizeBanks
(
std
::
shared_ptr
<
Mantid
::
DataObjects
::
PeaksWorkspace
>
pws
);
void
optimizeBanks
(
Mantid
::
API
::
IPeaksWorkspace_sptr
pws
);
/// Helper function for selecting peaks based on given bank name
Mantid
::
API
::
IPeaksWorkspace_sptr
selectPeaksByBankName
(
Mantid
::
API
::
IPeaksWorkspace_sptr
pws
,
const
std
::
string
bankname
,
const
std
::
string
outputwsn
);
/// Helper function that calculates the ideal qSample based on
/// integer HKL
Mantid
::
API
::
MatrixWorkspace_sptr
getIdealQSampleAsHistogram1D
(
Mantid
::
API
::
IPeaksWorkspace_sptr
pws
);
/// Helper functions for adjusting T0 for all peaks
void
adjustT0
(
double
dT0
,
DataObjects
::
PeaksWorkspace_sptr
&
pws
);
void
adjustT0
(
double
dT0
,
Mantid
::
API
::
I
PeaksWorkspace_sptr
&
pws
);
/// Helper functions for adjusting components
void
adjustComponent
(
double
dx
,
double
dy
,
double
dz
,
double
rvx
,
double
rvy
,
double
rvz
,
double
rang
,
std
::
string
cmptName
,
DataObjects
::
PeaksWorkspace_sptr
&
pws
);
Mantid
::
API
::
I
PeaksWorkspace_sptr
&
pws
);
/// Generate a Table workspace to store the calibration results
DataObjects
::
TableWorkspace_sptr
Mantid
::
API
::
I
TableWorkspace_sptr
generateCalibrationTable
(
std
::
shared_ptr
<
Geometry
::
Instrument
>
&
instrument
);
/// Save to xml file for Mantid to load
...
...
@@ -108,7 +123,7 @@ private:
/// Save the calibration table to a CSV file
void
saveCalibrationTable
(
const
std
::
string
&
FileName
,
DataObjects
::
TableWorkspace_sptr
&
tws
);
Mantid
::
API
::
I
TableWorkspace_sptr
&
tws
);
/// unique vars for a given instance of calibration
double
m_a
,
m_b
,
m_c
,
m_alpha
,
m_beta
,
m_gamma
;
...
...
@@ -120,8 +135,9 @@ private:
double
m_bank_translation_bounds
=
5e-2
;
// meter
double
m_bank_rotation_bounds
=
5.0
;
// degree
double
m_source_translation_bounds
=
0.1
;
// meter
bool
LOGCHILDALG
{
fals
e
};
bool
LOGCHILDALG
{
tru
e
};
const
int
MINIMUM_PEAKS_PER_BANK
{
6
};
const
double
PI
{
3.1415926535897932384626433832795028841971693993751058209
};
// Column names and types
const
std
::
string
calibrationTableColumnNames
[
8
]
=
{
...
...
@@ -133,7 +149,7 @@ private:
"double"
,
"double"
,
"double"
,
"double"
};
boost
::
container
::
flat_set
<
std
::
string
>
m_BankNames
;
Mantid
::
DataObjects
::
TableWorkspace_sptr
mCaliTable
;
Mantid
::
API
::
I
TableWorkspace_sptr
mCaliTable
;
};
}
// namespace Crystal
...
...
Framework/Crystal/inc/MantidCrystal/SCDCalibratePanels2ObjFunc.h
View file @
7d3a2f10
...
...
@@ -10,6 +10,7 @@
#include "MantidAPI/ParamFunction.h"
#include "MantidAPI/Workspace_fwd.h"
#include "MantidCrystal/DllConfig.h"
#include "MantidDataObjects/PeaksWorkspace.h"
#include "MantidKernel/V3D.h"
namespace
Mantid
{
...
...
@@ -33,23 +34,29 @@ public:
void
function1D
(
double
*
out
,
const
double
*
xValues
,
const
size_t
order
)
const
override
;
void
setPeakWorkspace
(
Mantid
::
API
::
IPeaksWorkspace_sptr
&
pws
,
const
std
::
string
componentName
);
private:
/// temp workspace holder
mutable
std
::
shared_ptr
<
API
::
Workspace
>
m_ws
;
mutable
std
::
string
m_cmpt
;
mutable
Mantid
::
API
::
IPeaksWorkspace_sptr
m_pws
;
mutable
int
n_iter
;
const
bool
LOGCHILDALG
{
false
};
const
Mantid
::
Kernel
::
V3D
UNSET_HKL
{
0
,
0
,
0
};
const
double
PI
{
3.1415926535897932384626433832795028841971693993751058209
};
/// helper functions
void
moveInstruentComponentBy
(
double
deltaX
,
double
deltaY
,
double
deltaZ
,
std
::
string
componentName
,
const
API
::
Workspace_sptr
&
ws
)
const
;
void
rotateInstrumentComponentBy
(
double
rotVx
,
double
rotVy
,
double
rotVz
,
double
rotAng
,
std
::
string
componentName
,
const
API
::
Workspace_sptr
&
ws
)
const
;
Mantid
::
API
::
IPeaksWorkspace_sptr
moveInstruentComponentBy
(
double
deltaX
,
double
deltaY
,
double
deltaZ
,
std
::
string
componentName
,
Mantid
::
API
::
IPeaksWorkspace_sptr
&
pws
)
const
;
Mantid
::
API
::
IPeaksWorkspace_sptr
rotateInstrumentComponentBy
(
double
rotVx
,
double
rotVy
,
double
rotVz
,
double
rotAng
,
std
::
string
componentName
,
Mantid
::
API
::
IPeaksWorkspace_sptr
&
pws
)
const
;
};
}
// namespace Crystal
...
...
Framework/Crystal/src/SCDCalibratePanels2.cpp
View file @
7d3a2f10
...
...
@@ -27,6 +27,11 @@
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/math/special_functions/round.hpp>
#include <cmath>
#include <fstream>
#include <iostream>
namespace
Mantid
{
namespace
Crystal
{
...
...
@@ -48,7 +53,7 @@ DECLARE_ALGORITHM(SCDCalibratePanels2)
*/
void
SCDCalibratePanels2
::
init
()
{
// Input peakworkspace
declareProperty
(
std
::
make_unique
<
WorkspaceProperty
<
PeaksWorkspace
>>
(
declareProperty
(
std
::
make_unique
<
WorkspaceProperty
<
I
PeaksWorkspace
>>
(
"PeakWorkspace"
,
""
,
Kernel
::
Direction
::
Input
),
"Workspace of Indexed Peaks"
);
...
...
@@ -115,7 +120,7 @@ void SCDCalibratePanels2::init() {
setPropertyGroup
(
"CalibrateBanks"
,
PARAMETERS
);
// Output options group
declareProperty
(
std
::
make_unique
<
WorkspaceProperty
<
TableWorkspace
>>
(
declareProperty
(
std
::
make_unique
<
WorkspaceProperty
<
I
TableWorkspace
>>
(
"OutputWorkspace"
,
""
,
Direction
::
Output
),
"The workspace containing the calibration table."
);
const
std
::
vector
<
std
::
string
>
detcalExts
{
".DetCal"
,
".Det_Cal"
};
...
...
@@ -132,9 +137,7 @@ void SCDCalibratePanels2::init() {
std
::
make_unique
<
FileProperty
>
(
"CSVFilename"
,
"SCDCalibrate2.csv"
,
FileProperty
::
OptionalSave
,
".csv"
),
"Path to an .csv file which contains the Calibration Table"
);
// TODO:
// - add option to store intermedia calibration results for additional
// analysis if needed
// group into Output group
const
std
::
string
OUTPUT
(
"Output"
);
setPropertyGroup
(
"OutputWorkspace"
,
OUTPUT
);
setPropertyGroup
(
"DetCalFilename"
,
OUTPUT
);
...
...
@@ -192,7 +195,7 @@ std::map<std::string, std::string> SCDCalibratePanels2::validateInputs() {
// Lattice constants are required if no UB is attached to the input
// peak workspace
PeaksWorkspace_sptr
pws
=
getProperty
(
"PeakWorkspace"
);
I
PeaksWorkspace_sptr
pws
=
getProperty
(
"PeakWorkspace"
);
double
a
=
getProperty
(
"a"
);
double
b
=
getProperty
(
"b"
);
double
c
=
getProperty
(
"c"
);
...
...
@@ -215,7 +218,7 @@ std::map<std::string, std::string> SCDCalibratePanels2::validateInputs() {
*/
void
SCDCalibratePanels2
::
exec
()
{
// parse all inputs
PeaksWorkspace_sptr
m_pws
=
getProperty
(
"PeakWorkspace"
);
I
PeaksWorkspace_sptr
m_pws
=
getProperty
(
"PeakWorkspace"
);
// recalculate UB with given lattice constant
// if required
...
...
@@ -227,6 +230,9 @@ void SCDCalibratePanels2::exec() {
updateUBMatrix
(
m_pws
);
}
// remove unindexed peaks
m_pws
=
removeUnindexedPeaks
(
m_pws
);
bool
calibrateT0
=
getProperty
(
"CalibrateT0"
);
bool
calibrateL1
=
getProperty
(
"CalibrateL1"
);
bool
calibrateBanks
=
getProperty
(
"CalibrateBanks"
);
...
...
@@ -252,17 +258,26 @@ void SCDCalibratePanels2::exec() {
getBankNames
(
m_pws
);
// STEP_2: optimize T0,L1,L2,etc.
if
(
calibrateT0
)
if
(
calibrateT0
)
{
g_log
.
notice
()
<<
"** Calibrating T0 as requested
\n
"
;
optimizeT0
(
m_pws
);
if
(
calibrateL1
)
}
if
(
calibrateL1
)
{
g_log
.
notice
()
<<
"** Calibrating L1 (moderator) as requested
\n
"
;
optimizeL1
(
m_pws
);
if
(
calibrateBanks
)
}
if
(
calibrateBanks
)
{
g_log
.
notice
()
<<
"** Calibrating L2 and orientation (bank) as requested
\n
"
;
optimizeBanks
(
m_pws
);
}
// STEP_3: generate a table workspace to save the calibration results
g_log
.
notice
()
<<
"-- Generate calibration table
\n
"
;
Instrument_sptr
instCalibrated
=
std
::
const_pointer_cast
<
Geometry
::
Instrument
>
(
m_pws
->
getInstrument
());
TableWorkspace_sptr
tablews
=
generateCalibrationTable
(
instCalibrated
);
I
TableWorkspace_sptr
tablews
=
generateCalibrationTable
(
instCalibrated
);
// STEP_4: Write to disk if required
if
(
!
XmlFilename
.
empty
())
...
...
@@ -290,38 +305,7 @@ void SCDCalibratePanels2::exec() {
*
* @param pws
*/
void
SCDCalibratePanels2
::
optimizeT0
(
std
::
shared_ptr
<
PeaksWorkspace
>
pws
)
{
// tl;dr; mocking a matrix workspace to store the target Qvectors
// details
// The optimizer we are going to use is the Fit algorithm, which is
// designed to match one histogram with another target one.
// So what we are doing here is creating a fake histogram out of the
// qSamples so that Fit algorithm can take it in and start optimizing.
// The same goes for optimizeL1 and optimizeBanks.
int
npks
=
pws
->
getNumberPeaks
();
MatrixWorkspace_sptr
t0ws
=
std
::
dynamic_pointer_cast
<
MatrixWorkspace
>
(
WorkspaceFactory
::
Instance
().
create
(
"Workspace2D"
,
// use workspace 2D to mock a histogram
1
,
// one vector
3
*
npks
,
// X :: anything is fine
3
*
npks
));
// Y :: flattened Q vector
// setting values to t0ws
auto
&
measured
=
t0ws
->
getSpectrum
(
0
);
auto
&
xv
=
measured
.
mutableX
();
auto
&
yv
=
measured
.
mutableY
();
auto
&
ev
=
measured
.
mutableE
();
for
(
int
i
=
0
;
i
<
npks
;
++
i
)
{
const
Peak
&
pk
=
pws
->
getPeak
(
i
);
V3D
qv
=
pk
.
getQSampleFrame
();
for
(
int
j
=
0
;
j
<
3
;
++
j
)
{
xv
[
i
*
3
+
j
]
=
i
*
3
+
j
;
yv
[
i
*
3
+
j
]
=
qv
[
j
];
ev
[
i
*
3
+
j
]
=
1
;
}
}
void
SCDCalibratePanels2
::
optimizeT0
(
IPeaksWorkspace_sptr
pws
)
{
// create child Fit alg to optimize T0
IAlgorithm_sptr
fitT0_alg
=
createChildAlgorithm
(
"Fit"
,
-
1
,
-
1
,
false
);
//-- obj func def
...
...
@@ -333,22 +317,27 @@ void SCDCalibratePanels2::optimizeT0(std::shared_ptr<PeaksWorkspace> pws) {
// class just to get Fit serving as an optimizer.
// For this particular case, we are constructing an objective function
// based on IFunction1D that outputs a fake histogram consist of
// qSample cal
u
cated based on perturbed instrument positions and
// qSample calc
ul
ated based on perturbed instrument positions and
// orientations.
std
::
ostringstream
fun_str
;
fun_str
<<
"name=SCDCalibratePanels2ObjFunc,Workspace="
<<
pws
->
getName
()
<<
",ComponentName=none"
;
MatrixWorkspace_sptr
t0ws
=
getIdealQSampleAsHistogram1D
(
pws
);
auto
objf
=
std
::
make_shared
<
SCDCalibratePanels2ObjFunc
>
();
objf
->
setPeakWorkspace
(
pws
,
"none"
);
fitT0_alg
->
setProperty
(
"Function"
,
std
::
dynamic_pointer_cast
<
IFunction
>
(
objf
));
//-- bounds&constraints def
std
::
ostringstream
tie_str
;
tie_str
<<
"DeltaX=0.0,DeltaY=0.0,DeltaZ=0.0,Theta=1.0,Phi=0.0,"
"DeltaRotationAngle=0.0"
;
//-- set&go
fitT0_alg
->
setPropertyValue
(
"Function"
,
fun_str
.
str
());
fitT0_alg
->
setProperty
(
"Ties"
,
tie_str
.
str
());
fitT0_alg
->
setProperty
(
"InputWorkspace"
,
t0ws
);
fitT0_alg
->
setProperty
(
"CreateOutput"
,
true
);
fitT0_alg
->
setProperty
(
"Output"
,
"fit"
);
fitT0_alg
->
executeAsChildAlg
();
//-- parse output
double
chi2OverDOF
=
fitT0_alg
->
getProperty
(
"OutputChi2overDoF"
);
ITableWorkspace_sptr
rst
=
fitT0_alg
->
getProperty
(
"OutputParameters"
);
...
...
@@ -357,6 +346,7 @@ void SCDCalibratePanels2::optimizeT0(std::shared_ptr<PeaksWorkspace> pws) {
adjustT0
(
dT0_optimized
,
pws
);
//-- log
int
npks
=
pws
->
getNumberPeaks
();
g_log
.
notice
()
<<
"-- Fit T0 results using "
<<
npks
<<
" peaks:
\n
"
<<
" dT0: "
<<
dT0_optimized
<<
"
\n
"
<<
" chi2/DOF = "
<<
chi2OverDOF
<<
"
\n
"
;
...
...
@@ -367,50 +357,32 @@ void SCDCalibratePanels2::optimizeT0(std::shared_ptr<PeaksWorkspace> pws) {
*
* @param pws
*/
void
SCDCalibratePanels2
::
optimizeL1
(
std
::
shared_ptr
<
PeaksWorkspace
>
pws
)
{
void
SCDCalibratePanels2
::
optimizeL1
(
I
PeaksWorkspace
_sptr
pws
)
{
// cache starting L1 position
double
original_L1
=
-
pws
->
getInstrument
()
->
getSource
()
->
getPos
().
Z
();
int
npks
=
pws
->
getNumberPeaks
();
MatrixWorkspace_sptr
l1ws
=
std
::
dynamic_pointer_cast
<
MatrixWorkspace
>
(
WorkspaceFactory
::
Instance
().
create
(
"Workspace2D"
,
// use workspace 2D to mock a histogram
1
,
// one vector
3
*
npks
,
// X :: anything is fine
3
*
npks
));
// Y :: flattened Q vector
double
original_L1
=
std
::
abs
(
pws
->
getInstrument
()
->
getSource
()
->
getPos
().
Z
());
auto
&
measured
=
l1ws
->
getSpectrum
(
0
);
auto
&
xv
=
measured
.
mutableX
();
auto
&
yv
=
measured
.
mutableY
();
auto
&
ev
=
measured
.
mutableE
();
for
(
int
i
=
0
;
i
<
npks
;
++
i
)
{
const
Peak
&
pk
=
pws
->
getPeak
(
i
);
V3D
qv
=
pk
.
getQSampleFrame
();
for
(
int
j
=
0
;
j
<
3
;
++
j
)
{
xv
[
i
*
3
+
j
]
=
i
*
3
+
j
;
yv
[
i
*
3
+
j
]
=
qv
[
j
];
ev
[
i
*
3
+
j
]
=
1
;
}
}
MatrixWorkspace_sptr
l1ws
=
getIdealQSampleAsHistogram1D
(
pws
);
// fit algorithm for the optimization of L1
IAlgorithm_sptr
fitL1_alg
=
createChildAlgorithm
(
"Fit"
,
-
1
,
-
1
,
false
);
//-- obj func def
std
::
ostringstream
fun_str
;
fun_str
<<
"name=SCDCalibratePanels2ObjFunc,Workspace="
<<
pws
->
getName
()
<<
",ComponentName=moderator"
;
auto
objf
=
std
::
make_shared
<
SCDCalibratePanels2ObjFunc
>
();
objf
->
setPeakWorkspace
(
pws
,
"moderator"
);
fitL1_alg
->
setProperty
(
"Function"
,
std
::
dynamic_pointer_cast
<
IFunction
>
(
objf
));
//-- bounds&constraints def
std
::
ostringstream
tie_str
;
tie_str
<<
"DeltaX=0.0,DeltaY=0.0,Theta=1.0,Phi=0.0,DeltaRotationAngle=0.0,"
"DeltaT0="
<<
m_T0
;
//-- set and go
fitL1_alg
->
setPropertyValue
(
"Function"
,
fun_str
.
str
());
fitL1_alg
->
setProperty
(
"Ties"
,
tie_str
.
str
());
fitL1_alg
->
setProperty
(
"InputWorkspace"
,
l1ws
);
fitL1_alg
->
setProperty
(
"CreateOutput"
,
true
);
fitL1_alg
->
setProperty
(
"Output"
,
"fit"
);
fitL1_alg
->
executeAsChildAlg
();
//-- parse output
double
chi2OverDOF
=
fitL1_alg
->
getProperty
(
"OutputChi2overDoF"
);
ITableWorkspace_sptr
rst
=
fitL1_alg
->
getProperty
(
"OutputParameters"
);
...
...
@@ -419,6 +391,7 @@ void SCDCalibratePanels2::optimizeL1(std::shared_ptr<PeaksWorkspace> pws) {
pws
->
getInstrument
()
->
getSource
()
->
getName
(),
pws
);
//-- log
int
npks
=
pws
->
getNumberPeaks
();
g_log
.
notice
()
<<
"-- Fit L1 results using "
<<
npks
<<
" peaks:
\n
"
<<
" dL1: "
<<
dL1_optimized
<<
"
\n
"
<<
" L1 "
<<
original_L1
<<
" -> "
...
...
@@ -431,66 +404,43 @@ void SCDCalibratePanels2::optimizeL1(std::shared_ptr<PeaksWorkspace> pws) {
*
* @param pws
*/
void
SCDCalibratePanels2
::
optimizeBanks
(
std
::
shared_ptr
<
PeaksWorkspace
>
pws
)
{
void
SCDCalibratePanels2
::
optimizeBanks
(
I
PeaksWorkspace
_sptr
pws
)
{
PARALLEL_FOR_IF
(
Kernel
::
threadSafe
(
*
pws
))
for
(
int
i
=
0
;
i
<
static_cast
<
int
>
(
m_BankNames
.
size
());
++
i
)
{
PARALLEL_START_INTERUPT_REGION
// prepare local copies to work with
const
std
::
string
bankname
=
*
std
::
next
(
m_BankNames
.
begin
(),
i
);
const
std
::
string
pwsBankiName
=
"_pws_"
+
bankname
;
//-- step 0: extract peaks that lies on the current bank
// NOTE: We are cloning the whole pws, then subtracting
// those that are not on the current bank.
PeaksWorkspace_sptr
pwsBanki
=
pws
->
clone
();
const
std
::
string
pwsBankiName
=
"_pws_"
+
bankname
;
AnalysisDataService
::
Instance
().
addOrReplace
(
pwsBankiName
,
pwsBanki
);
std
::
vector
<
Peak
>
&
allPeaks
=
pwsBanki
->
getPeaks
();
auto
notMyPeaks
=
std
::
remove_if
(
allPeaks
.
begin
(),
allPeaks
.
end
(),
[
&
bankname
](
const
Peak
&
pk
)
{
return
pk
.
getBankName
()
!=
bankname
;
});
allPeaks
.
erase
(
notMyPeaks
,
allPeaks
.
end
());
IPeaksWorkspace_sptr
pwsBanki
=
selectPeaksByBankName
(
pws
,
bankname
,
pwsBankiName
);
// Do not attempt correct panels with less than 6 peaks as the system will
// be under-determined
int
nBankPeaks
=
pwsBanki
->
getNumberPeaks
();
if
(
nBankPeaks
<
MINIMUM_PEAKS_PER_BANK
)
{
g_log
.
notice
()
<<
"-- Bank "
<<
bankname
<<
" have only "
<<
nBankPeaks
<<
" (<"
<<
MINIMUM_PEAKS_PER_BANK
<<
") Peaks, skipping
\n
"
;
AnalysisDataService
::
Instance
().
remove
(
pwsBankiName
);
// use ostringstream to prevent OPENMP breaks log info
std
::
ostringstream
msg_npeakCheckFail
;
msg_npeakCheckFail
<<
"-- Bank "
<<
bankname
<<
" have only "
<<
nBankPeaks
<<
" (<"
<<
MINIMUM_PEAKS_PER_BANK
<<
") Peaks, skipping
\n
"
;
g_log
.
notice
()
<<
msg_npeakCheckFail
.
str
();
continue
;
}
//-- step 1: prepare a mocked workspace with QSample as its yValues
MatrixWorkspace_sptr
wsBankCali
=
std
::
dynamic_pointer_cast
<
MatrixWorkspace
>
(
WorkspaceFactory
::
Instance
().
create
(
"Workspace2D"
,
// use workspace 2D to mock a histogram
1
,
// one vector
3
*
nBankPeaks
,
// X :: anything is fine
3
*
nBankPeaks
));
// Y :: flattened Q vector
auto
&
measured
=
wsBankCali
->
getSpectrum
(
0
);
auto
&
xv
=
measured
.
mutableX
();
auto
&
yv
=
measured
.
mutableY
();
auto
&
ev
=
measured
.
mutableE
();
// TODO: non-uniform weighting (ev) will be implemented at a later date
for
(
int
i
=
0
;
i
<
nBankPeaks
;
++
i
)
{
const
Peak
&
pk
=
pwsBanki
->
getPeak
(
i
);
V3D
qv
=
pk
.
getQSampleFrame
();
for
(
int
j
=
0
;
j
<
3
;
++
j
)
{
xv
[
i
*
3
+
j
]
=
i
*
3
+
j
;
yv
[
i
*
3
+
j
]
=
qv
[
j
];
ev
[
i
*
3
+
j
]
=
1
;
}
}
MatrixWorkspace_sptr
wsBankCali
=
getIdealQSampleAsHistogram1D
(
pwsBanki
);
//-- step 2&3: invoke fit to find both traslation and rotation
IAlgorithm_sptr
fitBank_alg
=
createChildAlgorithm
(
"Fit"
,
-
1
,
-
1
,
false
);
//---- setup obj fun def
std
::
ostringstream
fun_str
;
fun_str
<<
"name=SCDCalibratePanels2ObjFunc,Workspace="
<<
pwsBankiName
<<
",ComponentName="
<<
bankname
;
auto
objf
=
std
::
make_shared
<
SCDCalibratePanels2ObjFunc
>
();
objf
->
setPeakWorkspace
(
pwsBanki
,
bankname
);
fitBank_alg
->
setProperty
(
"Function"
,
std
::
dynamic_pointer_cast
<
IFunction
>
(
objf
));
//---- bounds&constraints def
std
::
ostringstream
tie_str
;
tie_str
<<
"DeltaT0="
<<
m_T0
;
...
...
@@ -503,13 +453,13 @@ void SCDCalibratePanels2::optimizeBanks(std::shared_ptr<PeaksWorkspace> pws) {
<<
btb
<<
","
<<
-
btb
<<
"<DeltaZ<"
<<
btb
;
//---- set&go
fitBank_alg
->
setPropertyValue
(
"Function"
,
fun_str
.
str
());
fitBank_alg
->
setProperty
(
"Ties"
,
tie_str
.
str
());
fitBank_alg
->
setProperty
(
"Constraints"
,
constraint_str
.
str
());
fitBank_alg
->
setProperty
(
"InputWorkspace"
,
wsBankCali
);
fitBank_alg
->
setProperty
(
"CreateOutput"
,
true
);
fitBank_alg
->
setProperty
(
"Output"
,
"fit"
);
fitBank_alg
->
executeAsChildAlg
();
//---- cache results
double
chi2OverDOF
=
fitBank_alg
->
getProperty
(
"OutputChi2overDoF"
);
ITableWorkspace_sptr
rstFitBank
=
...
...
@@ -524,6 +474,7 @@ void SCDCalibratePanels2::optimizeBanks(std::shared_ptr<PeaksWorkspace> pws) {
//-- step 4: update the instrument with optimization results
// if the fit results are above the tolerance/threshold
std
::
string
bn
=
bankname
;
std
::
ostringstream
calilog
;
if
(
pws
->
getInstrument
()
->
getName
().
compare
(
"CORELLI"
)
==
0
)
bn
.
append
(
"/sixteenpack"
);
if
((
std
::
abs
(
dx
)
<
m_tolerance_translation
)
&&
...
...
@@ -531,24 +482,22 @@ void SCDCalibratePanels2::optimizeBanks(std::shared_ptr<PeaksWorkspace> pws) {
(
std
::
abs
(
dz
)
<
m_tolerance_translation
)
&&
(
std
::
abs
(
rotang
)
<
m_tolerance_rotation
))
{
// skip the adjustment of the component as it is juat noise
g_log
.
notice
()
<<
"-- Fit "
<<
bn
<<
" results below tolerance, skippping
\n
"
;
calilog
<<
"-- Fit "
<<
bn
<<
" results below tolerance, skippping
\n
"
;
}
else
{
double
rvx
=
sin
(
theta
)
*
cos
(
phi
);
double
rvy
=
sin
(
theta
)
*
sin
(
phi
);
double
rvz
=
cos
(
theta
);
adjustComponent
(
dx
,
dy
,
dz
,
rvx
,
rvy
,
rvz
,
rotang
,
bn
,
pws
);
g_log
.
notice
()
<<
"-- Fit "
<<
bn
<<
" results using "
<<
nBankPeaks
<<
" peaks:
\n
"
<<
" d(x,y,z) = ("
<<
dx
<<
","
<<
dy
<<
","
<<
dz
<<
")
\n
"
<<
" rotang(rx,ry,rz) ="
<<
rotang
<<
"("
<<
rvx
<<
","
<<
rvy
<<
","
<<
rvz
<<
")
\n
"
<<
" chi2/DOF = "
<<
chi2OverDOF
<<
"
\n
"
;
calilog
<<
"-- Fit "
<<
bn
<<
" results using "
<<
nBankPeaks
<<
" peaks:
\n
"
<<
" d(x,y,z) = ("
<<
dx
<<
","
<<
dy
<<
","
<<
dz
<<
")
\n
"
<<
" rotang(rx,ry,rz) ="
<<
rotang
<<
"("
<<
rvx
<<
","
<<
rvy
<<
","
<<
rvz
<<
")
\n
"
<<
" chi2/DOF = "
<<
chi2OverDOF
<<
"
\n
"
;
}
g_log
.
notice
()
<<
calilog
.
str
();
// -- cleanup
AnalysisDataService
::
Instance
().
remove
(
pwsBankiName
);
PARALLEL_END_INTERUPT_REGION
}
PARALLEL_CHECK_INTERUPT_REGION
...
...
@@ -563,8 +512,7 @@ void SCDCalibratePanels2::optimizeBanks(std::shared_ptr<PeaksWorkspace> pws) {
* input peak workspace
*
*/
void
SCDCalibratePanels2
::
parseLatticeConstant
(
std
::
shared_ptr
<
PeaksWorkspace
>
pws
)
{
void
SCDCalibratePanels2
::
parseLatticeConstant
(
IPeaksWorkspace_sptr
pws
)
{
m_a
=
getProperty
(
"a"
);
m_b
=
getProperty
(
"b"
);
m_c
=
getProperty
(
"c"
);
...
...
@@ -593,30 +541,22 @@ void SCDCalibratePanels2::parseLatticeConstant(
*
* @param pws
*/
void
SCDCalibratePanels2
::
updateUBMatrix
(
std
::
shared_ptr
<
PeaksWorkspace
>
pws
)
{
IAlgorithm_sptr
findUB_alg
=
Mantid
::
API
::
AlgorithmFactory
::
Instance
().
create
(
"FindUBUsingLatticeParameters"
,
-
1
);
findUB_alg
->
initialize
();
findUB_alg
->
setChild
(
true
);
findUB_alg
->
setLogging
(
LOGCHILDALG
);
findUB_alg
->
setProperty
(
"PeaksWorkspace"
,
pws
);
findUB_alg
->
setProperty
(
"a"
,
m_a
);
findUB_alg
->
setProperty
(
"b"
,
m_b
);
findUB_alg
->
setProperty
(
"c"
,
m_c
);
findUB_alg
->
setProperty
(
"alpha"
,
m_alpha
);
findUB_alg
->
setProperty
(
"beta"
,
m_beta
);
findUB_alg
->
setProperty
(
"gamma"
,
m_gamma
);
findUB_alg
->
setProperty
(
"NumInitial"
,
15
);
// all four properties
findUB_alg
->
setProperty
(
"Tolerance"
,
0.15
);
// are using their default
findUB_alg
->
setProperty
(
"FixParameters"
,
false
);
// values
findUB_alg
->
setProperty
(
"Iterations"
,
1
);
//
findUB_alg
->
executeAsChildAlg
();
void
SCDCalibratePanels2
::
updateUBMatrix
(
IPeaksWorkspace_sptr
pws
)
{
IAlgorithm_sptr
calcUB_alg
=
createChildAlgorithm
(
"CalculateUMatrix"
,
-
1
,
-
1
,
false
);
calcUB_alg
->
setLogging
(
LOGCHILDALG
);
calcUB_alg
->
setProperty
(
"PeaksWorkspace"
,
pws
);
calcUB_alg
->
setProperty
(
"a"
,
m_a
);
calcUB_alg
->
setProperty
(
"b"
,
m_b
);
calcUB_alg
->
setProperty
(
"c"
,
m_c
);
calcUB_alg
->
setProperty
(
"alpha"
,
m_alpha
);
calcUB_alg
->
setProperty
(
"beta"
,
m_beta
);
calcUB_alg
->
setProperty
(
"gamma"
,
m_gamma
);
calcUB_alg
->
executeAsChildAlg
();
// Since UB is updated, we need to redo the indexation
IAlgorithm_sptr
idxpks_alg
=
Mantid
::
API
::
AlgorithmFactory
::
Instance
().
create
(
"IndexPeaks"
,
-
1
);
idxpks_alg
->
initialize
();
idxpks_alg
->
setChild
(
true
);
createChildAlgorithm
(
"IndexPeaks"
,
-
1
,
-
1
,
false
);
idxpks_alg
->
setLogging
(
LOGCHILDALG
);
idxpks_alg
->
setProperty
(
"PeaksWorkspace"
,
pws
);
idxpks_alg
->
setProperty
(
"RoundHKLs"
,
true
);
// both are using default
...
...
@@ -624,12 +564,34 @@ void SCDCalibratePanels2::updateUBMatrix(std::shared_ptr<PeaksWorkspace> pws) {
idxpks_alg
->
executeAsChildAlg
();
}
/**
* @brief
*
* @param pws
* @return IPeaksWorkspace_sptr
*/
IPeaksWorkspace_sptr
SCDCalibratePanels2
::
removeUnindexedPeaks
(
Mantid
::
API
::
IPeaksWorkspace_sptr
pws
)
{
IAlgorithm_sptr
fltpk_alg
=
createChildAlgorithm
(
"FilterPeaks"
);
fltpk_alg
->
setLogging
(
LOGCHILDALG
);
fltpk_alg
->
setProperty
(
"InputWorkspace"
,
pws
);
fltpk_alg
->
setProperty
(
"FilterVariable"
,
"h^2+k^2+l^2"
);
fltpk_alg
->
setProperty
(
"Operator"
,
">"
);
fltpk_alg
->
setProperty
(
"FilterValue"
,
0.0
);
fltpk_alg
->
setProperty
(
"OutputWorkspace"
,
"pws_filtered"
);