17#include <boost/algorithm/string/detail/classification.hpp>
18#include <boost/algorithm/string/split.hpp>
31using namespace Kernel;
41 std::make_shared<InstrumentValidator>()),
42 "A workspace that contains a reference to the instrument of interest. "
43 "You can use LoadEmptyInstrument to create such a workspace.");
45 "The name of the output CalFile");
47 "A string of the instrument component names to use as separate groups. "
48 "/ or , can be used to separate multiple groups.");
70 std::vector<std::string> vgroups;
71 boost::split(vgroups, groupsname, boost::algorithm::detail::is_any_ofF<char>(
",/*"));
72 if (vgroups.empty()) {
73 g_log.
error(
"Could not determine group names. Group names should be "
74 "separated by / or ,");
75 throw std::runtime_error(
"Could not determine group names. Group names "
76 "should be separated by / or ,");
80 std::map<std::string, int> group_map;
82 for (
auto &vgroup : vgroups) {
84 group_map[vgroup] = ++
index;
91 using sptr_ICompAss = std::shared_ptr<const Geometry::ICompAssembly>;
92 using sptr_IComp = std::shared_ptr<const Geometry::IComponent>;
93 using sptr_IDet = std::shared_ptr<const Geometry::IDetector>;
94 std::queue<std::pair<sptr_ICompAss, int>> assemblies;
95 sptr_ICompAss current = std::dynamic_pointer_cast<const Geometry::ICompAssembly>(inst);
97 sptr_IComp currentIComp;
98 sptr_ICompAss currentchild;
100 int top_group, child_group;
103 top_group = group_map[current->getName()];
104 assemblies.emplace(current, top_group);
107 std::string filename =
getProperty(
"GroupingFilename");
113 Progress prog(
this, 0.0, 0.8, assemblies.size());
114 while (!assemblies.empty())
116 current = assemblies.front().first;
117 top_group = assemblies.front().second;
119 int nchilds = current->nelements();
121 for (
int i = 0; i < nchilds; ++i) {
122 currentIComp = (*(current.get()))[i];
123 currentDet = std::dynamic_pointer_cast<const Geometry::IDetector>(currentIComp);
124 if (currentDet.get())
127 instrcalib[currentDet->getID()] = std::make_pair(number++, top_group);
129 instrcalib[number++] = std::make_pair(currentDet->getID(), top_group);
132 currentchild = std::dynamic_pointer_cast<const Geometry::ICompAssembly>(currentIComp);
133 if (currentchild.get()) {
134 child_group = group_map[currentchild->getName()];
135 if (child_group == 0)
136 child_group = top_group;
137 assemblies.emplace(currentchild, child_group);
150 std::ifstream file(filename.c_str());
155 std::ostringstream mess;
156 mess <<
"Calibration file " << filename <<
" already exist. Only grouping will be modified";
163 std::ostringstream message;
164 std::fstream outfile;
168 outfile.open(filename.c_str(), std::ios::out);
169 if (!outfile.is_open()) {
170 message <<
"Can't open Calibration File: " << filename;
172 throw std::runtime_error(message.str());
175 infile.open(filename.c_str(), std::ios::in);
176 std::string newfilename = filename +
"2";
177 outfile.open(newfilename.c_str(), std::ios::out);
178 if (!infile.is_open()) {
179 message <<
"Can't open input Calibration File: " << filename;
181 throw std::runtime_error(message.str());
183 if (!outfile.is_open()) {
184 message <<
"Can't open new Calibration File: " << newfilename;
186 throw std::runtime_error(message.str());
194 int number, udet, select, group;
198 while (getline(infile, str)) {
199 if (str.empty() || str[0] ==
'#')
201 std::istringstream istr(str);
202 istr >> number >> udet >> offset >> select >> group;
207 group = ((*it).second).second;
225 os << std::fixed << std::setw(9) << number << std::fixed << std::setw(15) << udet << std::fixed
226 << std::setprecision(7) << std::setw(15) << offset << std::fixed << std::setw(8) << select << std::fixed
227 << std::setw(8) << group <<
"\n";
232 os <<
"# Diffraction focusing calibration file created by Mantid"
234 os <<
"# Detectors have been grouped using assembly names:" <<
groups <<
"\n";
236 os <<
"# Template file " << filename <<
" has been used"
238 os <<
"# Only grouping has been changed, offset from template file have "
242 os <<
"# No template file, all offsets set to 0.0 and select to 1"
245 os <<
"# Number UDET offset select group"
#define DECLARE_ALGORITHM(classname)
double value
The value of the point.
std::map< DeltaEMode::Type, std::string > index
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
A specialized class for dealing with file properties.
@ Save
to specify a file to write to, the file may or may not exist
Helper class for reporting progress from algorithms.
A property class for workspaces.
void saveGroupingFile(const std::string &, bool overwrite) const
Creates and saves the output file.
void writeHeaders(std::ostream &os, const std::string &filename, bool overwrite) const
Writes out the header to the output file.
std::string groups
The names of the groups.
bool groupingFileDoesExist(const std::string &filename) const
Determine whether the grouping file already exists.
instrcalmap instrcalib
Calibration map used if the *.cal file exist.
void exec() override
Execution code.
static void writeCalEntry(std::ostream &os, int number, int udet, double offset, int select, int group)
Writes a single calibration line to the output file.
void init() override
Initialisation code.
void error(const std::string &msg)
Logs at error level.
void information(const std::string &msg)
Logs at information level.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
@ Input
An input workspace.