38 const std::vector<std::string> exts{
".dat",
".bin"};
39 declareProperty(std::make_unique<FileProperty>(
"Filename",
"",
FileProperty::Load, exts),
40 "The DspacemapFile containing the d-space mapping.");
42 std::vector<std::string> propOptions{
"POWGEN",
"VULCAN-ASCII",
"VULCAN-Binary"};
43 declareProperty(
"FileType",
"POWGEN", std::make_shared<StringListValidator>(propOptions),
44 "The type of file being read.");
47 "An output OffsetsWorkspace.");
58 const std::string DFileName =
getProperty(
"Filename");
65 if (type ==
"POWGEN") {
70 std::map<detid_t, double> vulcan;
71 if (type ==
"VULCAN-ASCII") {
73 }
else if (type ==
"VULCAN-Binary") {
76 throw std::invalid_argument(
"Unexpected FileType property value received.");
95 const auto &detectorInfo = offsetsWS->detectorInfo();
96 const double l1 = detectorInfo.l1();
98 const char *filename = DFileName.c_str();
99 std::ifstream fin(filename, std::ios_base::in | std::ios_base::binary);
101 std::vector<double> dspace;
104 fin.read(
reinterpret_cast<char *
>(&read),
sizeof read);
107 dspace.emplace_back(read);
110 const auto &detectorIds = detectorInfo.detectorIDs();
120 offset = dspace[detectorId] / factor - 1.0;
124 offsetsWS->setValue(detectorId, offset);
125 }
catch (std::invalid_argument &) {
147 g_log.
notice() <<
"Name of instrument = " << instrument->getName() <<
'\n';
148 g_log.
notice() <<
"Input map (dict): size = " << vulcan.size() <<
'\n';
152 instrument->getDetectors(allDetectors);
154 detid2det_map::const_iterator it;
156 g_log.
notice() <<
"Input number of detectors = " << allDetectors.size() <<
'\n';
159 double l1, beamline_norm;
161 instrument->getInstrumentParameters(l1, beamline, beamline_norm, samplePos);
182 detid_t anydetinrefmodule = 21 * 1250 + 5;
184 auto det_iter = allDetectors.find(anydetinrefmodule);
186 if (det_iter == allDetectors.end()) {
187 throw std::invalid_argument(
"Any Detector ID is Instrument's detector");
189 referencePos = det_iter->second->getParent()->getPos();
190 double refl2 = referencePos.
norm();
191 double halfcosTwoThetaRef = referencePos.
scalar_prod(beamline) / (refl2 * beamline_norm);
192 double sinThetaRef = sqrt(0.5 - halfcosTwoThetaRef);
193 double difcRef = sinThetaRef * (l1 + refl2) /
CONSTANT;
196 for (it = allDetectors.begin(); it != allDetectors.end(); ++it) {
197 int detectorID = it->first;
202 double vulcan_factor = 0.0;
203 std::map<detid_t, double>::const_iterator vulcan_iter = vulcan.find(detectorID);
204 if (vulcan_iter != vulcan.end()) {
205 vulcan_factor = vulcan_iter->second;
212 double intermoduleoffset = 0;
213 double interstackoffset = 0;
215 detid_t intermoduleid =
detid_t(detectorID / 1250) * 1250 + 1250 - 2;
216 vulcan_iter = vulcan.find(intermoduleid);
217 if (vulcan_iter == vulcan.end()) {
218 g_log.
error() <<
"Cannot find inter-module offset ID = " << intermoduleid <<
'\n';
220 intermoduleoffset = vulcan_iter->second;
223 detid_t interstackid =
detid_t(detectorID / 1250) * 1250 + 1250 - 1;
224 vulcan_iter = vulcan.find(interstackid);
225 if (vulcan_iter == vulcan.end()) {
226 g_log.
error() <<
"Cannot find inter-module offset ID = " << intermoduleid <<
'\n';
228 interstackoffset = vulcan_iter->second;
245 detPos = det->getPos();
249 double l2 = detPos.
norm();
250 double halfcosTwoTheta = detPos.
scalar_prod(beamline) / (
l2 * beamline_norm);
251 double sinTheta = sqrt(0.5 - halfcosTwoTheta);
252 double difc_pixel = sinTheta * (l1 +
l2) /
CONSTANT;
266 offset = difc_pixel / difcRef * (pow(10.0, -(vulcan_factor + intermoduleoffset + interstackoffset))) - 1.0;
270 offsetsWS->setValue(detectorID, offset);
272 if (intermoduleid != 27498 && intermoduleid != 28748 && intermoduleid != 29998 && intermoduleid != 33748 &&
273 intermoduleid != 34998 && intermoduleid != 36248) {
274 g_log.
error() <<
"Detector ID = " << detectorID <<
" Inter-Module ID = " << intermoduleid <<
'\n';
275 throw std::invalid_argument(
"Indexing error!");
278 }
catch (std::invalid_argument &) {
279 g_log.
notice() <<
"Misses Detector ID = " << detectorID <<
'\n';
283 g_log.
notice() <<
"Number of matched detectors =" << numfinds <<
'\n';
298 std::ifstream grFile(fileName.c_str());
300 g_log.
error() <<
"Unable to open vulcan file " << fileName <<
'\n';
306 while (getline(grFile, str)) {
307 if (str.empty() || str[0] ==
'#')
309 std::istringstream istr(str);
312 istr >> udet >> correction;
313 vulcan.emplace(udet, correction);
317 g_log.
notice() <<
"Read Vulcan ASCII File: # Entry = " << numentries <<
'\n';
341 std::vector<VulcanCorrectionFactor> results = file.
loadAll();
342 for (
auto &result : results) {
343 vulcan[
static_cast<detid_t>(result.pixelID)] = result.factor;
#define DECLARE_ALGORITHM(classname)
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
@ Load
allowed here which will be passed to the algorithm
A property class for workspaces.
static void getInstrument3WaysInit(Mantid::API::Algorithm *alg)
For use by getInstrument3Ways, initializes the properties.
static Geometry::Instrument_const_sptr getInstrument3Ways(API::Algorithm *alg)
Get a pointer to an instrument in one of 3 ways: InputWorkspace, InstrumentName, InstrumentFilename.
Loads a Dspacemap file (POWGEN binary, VULCAN binary or ascii format) into an OffsetsWorkspace.
void CalculateOffsetsFromVulcanFactors(std::map< detid_t, double > &vulcan, const Mantid::DataObjects::OffsetsWorkspace_sptr &offsetsWS)
Make a map of the conversion factors between tof and D-spacing for all pixel IDs in a workspace.
void CalculateOffsetsFromDSpacemapFile(const std::string &DFileName, const Mantid::DataObjects::OffsetsWorkspace_sptr &offsetsWS)
Make a map of the conversion factors between tof and D-spacing for all pixel IDs in a workspace.
void readVulcanAsciiFile(const std::string &fileName, std::map< detid_t, double > &vulcan)
Reads an ASCII VULCAN filename where:
void readVulcanBinaryFile(const std::string &fileName, std::map< detid_t, double > &vulcan)
Reads a Binary VULCAN filename where:
void exec() override
Run the algorithm.
An OffsetsWorkspace is a specialized Workspace2D where the Y value at each pixel is the offset to be ...
The BinaryFile template is a helper function for loading simple binary files.
std::vector< T > loadAll()
Loads the entire contents of the file into a pointer to a std::vector.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void notice(const std::string &msg)
Logs at notice level.
void error(const std::string &msg)
Logs at error level.
constexpr double scalar_prod(const V3D &v) const noexcept
Calculates the cross product.
double norm() const noexcept
std::shared_ptr< OffsetsWorkspace > OffsetsWorkspace_sptr
shared pointer to the OffsetsWorkspace class
MANTID_GEOMETRY_DLL double tofToDSpacingFactor(const double l1, const double l2, const double twoTheta, const double offset)
Calculate and return conversion factor from tof to d-spacing.
std::shared_ptr< const Mantid::Geometry::IDetector > IDetector_const_sptr
Shared pointer to IDetector (const version)
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
static constexpr double NeutronMass
Mass of the neutron in kg.
static constexpr double h
Planck constant in J*s.
int32_t detid_t
Typedef for a detector ID.
std::map< detid_t, Geometry::IDetector_const_sptr > detid2det_map
Typedef of a map from detector ID to detector shared pointer.
Structure of the vulcan binary file.
double factor
Correction factor for pixel.
double pixelID
ID for pixel.
@ Output
An output workspace.