13#include <initializer_list>
37 std::pair<Miller, int>
hkl_isym = asu_.to_asu(hkl, group_ops_);
85 float min_value =
NAN;
86 float max_value =
NAN;
96 float&
operator[](std::size_t n) {
return parent->
data[idx + n * stride()]; }
97 float operator[](std::size_t n)
const {
return parent->
data[idx + n * stride()]; }
98 float&
at(std::size_t n) {
return parent->
data.at(idx + n * stride()); }
99 float at(std::size_t n)
const {
return parent->
data.at(idx + n * stride()); }
101 return type ==
'H' || type ==
'B' || type ==
'Y' || type ==
'I';
105 if (idx + 1 < parent->
columns.size()) {
131 floats.resize(156, 0.);
146 return UnitCell(floats[0], floats[1], floats[2],
147 floats[3], floats[4], floats[5]);
165 return Mat33(floats[6], floats[9], floats[12],
166 floats[7], floats[10], floats[13],
167 floats[8], floats[11], floats[14]);
182 MtzMetadata::operator=(std::move(
o));
183 datasets = std::move(
o.datasets);
184 columns = std::move(
o.columns);
185 batches = std::move(
o.batches);
186 data = std::move(
o.data);
194 datasets =
o.datasets;
205 datasets.push_back({0,
"HKL_base",
"HKL_base",
"HKL_base", cell, 0.});
206 for (
int i = 0;
i != 3; ++
i)
207 add_column(std::string(1,
"HKL"[
i]),
'H', 0,
i,
false);
217 if (
ds.id == dataset &&
ds.cell.is_crystal() &&
ds.cell.a > 0)
223 return const_cast<Mtz*
>(
this)->get_cell(dataset);
228 cell.set_cell_images_from_spacegroup(spacegroup);
237 spacegroup_number =
new_sg ? spacegroup->ccp4 : 0;
238 spacegroup_name =
new_sg ? spacegroup->hm :
"";
242 if (datasets.empty())
243 fail(
"MTZ dataset not found (missing DATASET header line?).");
244 return datasets.back();
248 if ((
size_t)
id < datasets.size() && datasets[
id].id ==
id)
253 fail(
"MTZ file has no dataset with ID " + std::to_string(
id));
256 return const_cast<Mtz*
>(
this)->dataset(
id);
261 if (
d.dataset_name == name)
266 return const_cast<Mtz*
>(
this)->dataset_with_name(label);
269 int count(
const std::string& label)
const {
271 for (
const Column& col : columns)
272 if (col.label == label)
279 for (
const Column& col : columns)
280 if (col.type == type)
286 for (
Column& col : columns)
287 if (col.label == label && (!
ds ||
ds->id == col.dataset_id)
288 && (type ==
'*' || type == col.type))
293 char type=
'*')
const {
294 return const_cast<Mtz*
>(
this)->column_with_label(label,
ds, type);
298 if (
const Column* col = column_with_label(label,
ds))
300 fail(
"Column label not found: " + label);
304 std::vector<const Column*>
cols;
305 for (
const Column& col : columns)
306 if (col.type == type)
307 cols.push_back(&col);
312 std::vector<int>
cols;
313 for (
int i = 0;
i < (
int) columns.size(); ++
i)
314 if (columns[
i].type == col_type)
323 std::vector<std::pair<int,int>>
r;
324 for (
int i = 0;
i < (
int) columns.size(); ++
i) {
325 const Column& col = columns[
i];
327 if (
sign_pos != std::string::npos) {
330 for (
int j = 0;
j < (
int) columns.size(); ++
j)
332 columns[
j].type == col.
type &&
334 r.emplace_back(
i,
j);
344 char type=
'*')
const {
345 for (
const char* label :
labels)
346 if (
const Column* col = column_with_label(label,
nullptr, type))
353 for (
Column& col : columns)
354 if (col.type == type) {
355 for (
const char* label :
labels)
356 if (col.label == label)
364 return column_with_type_and_any_of_labels(
'I',
365 {
"FREE",
"RFREE",
"FREER",
"FreeR_flag",
"R-free-flags",
"FreeRflag",
"R_FREE_FLAGS"});
368 return const_cast<Mtz*
>(
this)->rfree_column();
372 return column_with_type_and_any_of_labels(
'J', {
"IMEAN",
"I",
"IOBS",
"I-obs"});
375 return const_cast<Mtz*
>(
this)->imean_column();
379 return column_with_type_and_any_of_labels(
'K', {
"I(+)",
"IOBS(+)",
"I-obs(+)",
"Iplus"});
382 return const_cast<Mtz*
>(
this)->iplus_column();
386 return column_with_type_and_any_of_labels(
'K', {
"I(-)",
"IOBS(-)",
"I-obs(-)",
"Iminus"});
389 return const_cast<Mtz*
>(
this)->iminus_column();
393 return data.size() == columns.size() * nreflections;
403 std::array<double,2>
reso = calculate_min_max_1_d2();
411 same_byte_order = !same_byte_order;
435 read_stream(
stream,
true);
436 }
catch (std::system_error&) {
438 }
catch (std::runtime_error&
e) {
439 fail(std::string(
e.what()) +
": " + path);
443 template<
typename Input>
445 source_path =
input.path();
459 for (
int i = 0;
i != 3; ++
i)
460 data[
offset +
i] =
static_cast<float>(hkl[
i]);
487 datasets.push_back({id, name, name, name, cell, 0.0});
488 return datasets.back();
505 template <
typename Func>
509 auto out = data.begin();
510 size_t width = columns.size();
511 for (
auto r = data.begin();
r < data.end();
r += width)
514 std::copy(
r,
r + width,
out);
517 data.erase(
out, data.end());
518 nreflections =
int(data.size() / width);
524 fail(
"Internal error");
527 fail(
"expand_data_rows(): pos out of range");
532 size_t ncols = columns.size();
534 fail(
"Mtz.set_data(): expected " + std::to_string(
ncols) +
" columns.");
547 template<
typename Write>
void write_to_stream(
Write write)
const;
557template<
typename Input>
578 fail(
"MTZ file has no column with label: " + label);
587 size_t size()
const {
return mtz_.columns.size() * mtz_.nreflections; }
588 float get_num(
size_t n)
const {
return data_[n]; }
fail(), unreachable() and __declspec/__attribute__ macros
Bidirectional iterators (over elements of any container) that can filter, uniquify,...
Logger - a tiny utility for passing messages through a callback.
Math utilities. 3D linear algebra.
void swap_eight_bytes(void *start)
MtzDataProxy data_proxy(const Mtz &mtz)
std::array< int, 3 > Miller
A synonym for convenient passing of hkl.
Mtz read_mtz_file(const std::string &path)
void vector_insert_columns(std::vector< T > &data, size_t old_width, size_t length, size_t n, size_t pos, const T &new_value)
void fail(const std::string &msg)
Mtz read_mtz(Input &&input, bool with_data)
Passes messages (including warnings/errors) to a callback function.
const SpaceGroup * spacegroup() const
size_t column_index(const std::string &label) const
const UnitCell & unit_cell() const
Miller get_hkl(size_t offset) const
float get_num(size_t n) const
MtzExternalDataProxy(const Mtz &mtz, const float *data)
Miller get_hkl(size_t offset) const
float get_num(size_t n) const
std::vector< float > floats
std::vector< std::string > axes
void set_wavelength(float lambda)
UnitCell get_cell() const
void set_cell(const UnitCell &uc)
void set_dataset_id(int id)
float & operator[](std::size_t n)
float at(std::size_t n) const
const Column * get_next_column_if_type(char next_type) const
float operator[](std::size_t n) const
const_iterator begin() const
float & at(std::size_t n)
const_iterator end() const
const Dataset & dataset() const
const Column * column_with_one_of_labels(std::initializer_list< const char * > labels, char type=' *') const
the order of labels matters
size_t write_to_buffer(char *buf, size_t maxlen) const
Mtz & operator=(Mtz &&o) noexcept
std::vector< Dataset > datasets
Column * column_with_label(const std::string &label, const Dataset *ds=nullptr, char type=' *')
void read_stream(AnyStream &stream, bool with_data)
const Column * iplus_column() const
Column & add_column(const std::string &label, char type, int dataset_id, int pos, bool expand_data)
int count_type(char type) const
std::vector< Batch > batches
const Column & get_column_with_label(const std::string &label, const Dataset *ds=nullptr) const
void reindex(const Op &op)
Reindex data, usually followed by ensure_asu(). Outputs messages through logger.
void write_to_cstream(std::FILE *stream) const
void expand_to_p1()
Change symmetry to P1 and expand reflections.
std::vector< int > positions_of_columns_with_type(char col_type) const
const Dataset * dataset_with_name(const std::string &label) const
bool sort(int use_first=3)
Dataset & add_dataset(const std::string &name)
const UnitCell & get_cell(int dataset=-1) const
const Column * iminus_column() const
void read_main_headers(AnyStream &stream, std::vector< std::string > *save_headers)
read headers until END
bool switch_to_asu_hkl()
(for unmerged MTZ only) change HKL to ASU equivalent and set ISYM
void write_to_file(const std::string &path) const
void ensure_asu(bool tnt_asu=false)
(for merged MTZ only) change HKL to ASU equivalent, adjust phases, etc
void set_spacegroup(const SpaceGroup *new_sg)
double resolution_low() const
void read_file_gz(const std::string &path, bool with_data=true)
the same as read_input(MaybeGzipped(path), with_data)
Dataset & dataset(int id)
size_t size_to_write() const
std::vector< const Column * > columns_with_type(char type) const
Column & copy_column(int dest_idx, const Column &src_col, const std::vector< std::string > &trailing_cols={})
void read_all_headers(AnyStream &stream)
std::vector< int > sorted_row_indices(int use_first=3) const
void read_input(Input &&input, bool with_data)
std::array< double, 2 > calculate_min_max_1_d2() const
Calculates min/max for all combinations of reflections and unit cells, where unit cells are a global ...
std::vector< std::pair< int, int > > positions_of_plus_minus_columns() const
const Column * rfree_column() const
const Column * imean_column() const
void read_first_bytes(AnyStream &stream)
Column * column_with_type_and_any_of_labels(char type, std::initializer_list< const char * > labels)
the order of labels doesn't matter
void set_hkl(size_t offset, const Miller &hkl)
double resolution_high() const
void read_raw_data(AnyStream &stream, bool do_read=true)
void set_cell_for_all(const UnitCell &new_cell)
Dataset * dataset_with_name(const std::string &name)
void read_file(const std::string &path)
Mtz & operator=(Mtz const &)=delete
void read_history_and_batch_headers(AnyStream &stream)
read the part between END and MTZENDOFHEADERS
Column & replace_column(size_t dest_idx, const Column &src_col, const std::vector< std::string > &trailing_cols={})
const Column * column_with_label(const std::string &label, const Dataset *ds=nullptr, char type=' *') const
bool switch_to_original_hkl()
(for unmerged MTZ only) change HKL according to M/ISYM
void set_data(const float *new_data, size_t n)
const Dataset & dataset(int id) const
std::vector< Column > columns
void remove_rows_if(Func condition)
Mtz(bool with_base=false)
size_t find_offset_of_hkl(const Miller &hkl, size_t start=0) const
Returns offset of the first hkl or (size_t)-1. Can be slow.
void write_to_string(std::string &str) const
UnitCellParameters get_average_cell_from_batch_headers(double *rmsd) const
void expand_data_rows(size_t added, int pos_=-1)
Miller get_hkl(size_t offset) const
UnitCell & get_cell(int dataset=-1)
int count(const std::string &label) const
std::vector< float > data
void remove_column(size_t idx)
GroupOps operations() const
UnmergedHklMover(const SpaceGroup *spacegroup)
int move_to_asu(std::array< int, 3 > &hkl)
Crystallographic Symmetry. Space Groups. Coordinate Triplets.
Utilities. Mostly for working with strings and vectors.