5#ifndef GEMMI_XDS_ASCII_HPP_
6#define GEMMI_XDS_ASCII_HPP_
21 return std::fabs(wavelength - 1.5418) < 0.0019 ||
22 std::fabs(wavelength - 0.7107) < 0.0002 ||
23 std::fabs(wavelength - 2.29) < 0.01;
41 int frame()
const {
return (
int) std::floor(zd + 1); }
46 double wavelength = 0.;
47 double cell_constants[6] = {0., 0., 0., 0., 0., 0.};
49 int frame_number_min = -1;
50 int frame_number_max = -1;
52 int reflection_count = -1;
58 int spacegroup_number = 0;
61 double wavelength = 0.;
62 double incident_beam_dir[3] = {0., 0., 0.};
63 double oscillation_range = 0.;
64 double rotation_axis[3] = {0., 0., 0.};
65 double starting_angle = 0.;
66 double reflecting_range_esd = 0.;
67 int starting_frame = 1;
74 double detector_distance = 0.;
84 isets.emplace_back(
id);
87 template<
typename Stream>
88 void read_stream(
Stream&& stream,
const std::string& source);
92 if (
input.is_stdin()) {
94 }
else if (
input.is_compressed()) {
95 read_stream(
input.get_uncompressing_stream(),
input.path());
103 for (
Iset& iset : isets) {
104 iset.frame_number_min =
INT_MAX;
105 iset.frame_number_max = 0;
107 if (
refl.iset == iset.id) {
108 ++iset.reflection_count;
109 int frame =
refl.frame();
110 iset.frame_number_min = std::min(iset.frame_number_min, frame);
111 iset.frame_number_max = std::max(iset.frame_number_max, frame);
113 if (iset.frame_number_min > iset.frame_number_max)
115 std::vector<uint8_t>
frames(iset.frame_number_max - iset.frame_number_min + 1);
117 if (
refl.iset == iset.id)
118 frames[
refl.frame() - iset.frame_number_min] = 1;
119 iset.frame_count = 0;
121 iset.frame_count += f;
126 double z =
refl.zd - starting_frame + 1;
127 return starting_angle + oscillation_range * z;
132 double length = vec.length();
134 fail(
"unknown ", name);
140 return get_normalized(rotation_axis,
"rotation axis");
145 return get_normalized(incident_beam_dir,
"incident beam direction");
149 for (
int i = 0;
i < 3; ++
i)
150 if (cell_axes[
i][0] == 0 && cell_axes[
i][1] == 0 && cell_axes[
i][2] == 0)
159 Vec3 z = get_rotation_axis();
161 Vec3 x = get_s0_direction();
162 Vec3 y = z.cross(x).normalized();
164 x = y.cross(z).normalized();
165 return Mat33::from_columns(x, y, z);
169 if (!has_cell_axes())
170 fail(
"unknown unit cell axes");
171 Vec3 a = cell_axes.row_copy(0);
172 Vec3 b = cell_axes.row_copy(1);
173 Vec3 c = cell_axes.row_copy(2);
174 Vec3 ar = b.cross(c).normalized();
175 Vec3 br = c.cross(a);
176 Vec3 cr = ar.cross(br).normalized();
178 return Mat33::from_columns(ar, br, cr);
198 if (std::strncmp(a, b,
N-1) != 0)
210 double& val,
const char*
line) {
212 if (
result.ec != std::errc())
213 fail(
"failed to parse number in:\n",
line);
219 double (&
arr)[
N],
const char*
line) {
220 for (
int i = 0;
i <
N; ++
i) {
222 if (
result.ec != std::errc())
223 fail(
"failed to parse number #",
i+1,
" in:\n",
line);
228template<
typename Stream>
237 fail(
"not an unmerged XDS_ASCII nor INTEGRATE.HKL file: " +
source_path);
240 if (
line[0] ==
'!') {
260 if (
result.ec != std::errc())
261 fail(
"failed to parse mosaicity:\n",
line);
264 if (
result.ec != std::errc())
265 fail(
"failed to parse wavelength:\n",
line);
270 if (
result.ec != std::errc())
276 if (
result.ec != std::errc())
290 if (
result.ec != std::errc())
291 fail(
"failed to parse iset wavelength:\n",
line);
323 if (!
starts_with(
line,
"!H,K,L,IOBS,SIGMA,XCAL,YCAL,ZCAL,RLP,PEAK,CORR,MAXC"))
324 fail(
"unexpected column order in INTEGRATE.HKL");
327 "H=1",
"K=2",
"L=3",
"IOBS=4",
"SIGMA(IOBS)=5",
328 "XD=6",
"YD=7",
"ZD=8",
"RLP=9",
"PEAK=10",
"CORR=11",
"MAXC=12"
333 if (std::strncmp(
line,
"!ITEM_", 6) != 0 ||
334 std::strncmp(
line+6, col, std::strlen(col)) != 0)
335 fail(
"column !ITEM_" + std::string(col),
" not found.");
342 isets.emplace_back(1);
346 if (
size_t(
refl.iset - 1) >=
isets.size())
347 fail(
"unexpected ITEM_ISET " + std::to_string(
refl.iset));
353 const char*
p =
line;
354 for (
int i = 0;
i < 3; ++
i)
371 r.rlp =
r.peak =
r.corr =
r.maxc = 0;
373 if (
result.ec != std::errc())
374 fail(
"failed to parse data line:\n",
line);
void parse_numbers_into_array(const char *start, const char *end, double(&arr)[N], const char *line)
void vector_remove_if(std::vector< T > &v, F &&condition)
int simple_atoi(const char *p, const char **endptr=nullptr)
size_t copy_line_from_stream(char *line, int size, Input &&in)
bool starts_with_ptr_b(const char *a, const char(&b)[N], const char **endptr)
std::array< int, 3 > Miller
A synonym for convenient passing of hkl.
from_chars_result fast_from_chars(const char *start, const char *end, double &d)
std::string read_word(const char *line)
fileptr_t file_open(const char *path, const char *mode)
bool starts_with_ptr(const char *a, const char(&b)[N], const char **endptr)
bool likely_in_house_source(double wavelength)
bool starts_with(const std::string &str, const std::string &prefix)
void fail(const std::string &msg)
XdsAscii read_xds_ascii_file(const std::string &path)
const char * skip_word(const char *p)
std::string trim_str(const std::string &str)
const char * parse_number_into(const char *start, const char *end, double &val, const char *line)
const char * skip_blank(const char *p)
void set(double a_, double b_, double c_, double alpha_, double beta_, double gamma_)
double incident_beam_dir[3]
Vec3 get_rotation_axis() const
Vec3 get_s0_direction() const
bool has_cell_axes() const
Mat33 calculate_conversion_from_cambridge() const
Return transition matrix from "Cambridge" frame to XDS frame.
double reflecting_range_esd
Mat33 get_orientation() const
void read_stream(Stream &&stream, const std::string &source)
double rot_angle(const Refl &refl) const
void gather_iset_statistics()
std::vector< Iset > isets
static Vec3 get_normalized(const double(&arr)[3], const char *name)
void eliminate_overloads(double overload)
void apply_polarization_correction(double p, Vec3 normal)
Iset & find_or_add_iset(int id)
void eliminate_batchmin(int batchmin)
void read_input(T &&input)