Gemmi C++ API
Loading...
Searching...
No Matches
intensit.hpp
Go to the documentation of this file.
1// Copyright 2020 Global Phasing Ltd.
2//
3// Class Intensities that reads multi-record data from MTZ, mmCIF or XDS_ASCII
4// and merges it into mean or anomalous intensities.
5// It can also read merged data.
6
7#ifndef GEMMI_INTENSIT_HPP_
8#define GEMMI_INTENSIT_HPP_
9
10#include <cstdint> // for int8_t
11#include <unordered_map>
12#include "symmetry.hpp"
13#include "unitcell.hpp"
14#include "util.hpp" // for vector_remove_if
15#include "stats.hpp" // for Correlation
16
17namespace gemmi {
18
19struct Binner;
20struct Mtz;
21struct XdsAscii;
22struct ReflnBlock;
23namespace cif { struct Block; }
24using std::int8_t;
25
26// If used to request a particular data type:
27// MergedMA = Mean if available, otherwise Anomalous,
28// MergedAM = Anomalous if available, otherwise Mean.
29// UAM = Unmerged if available, otherwise MergedAM
32
34 int all_refl = 0; // all reflections, sometimes called observations
35 int unique_refl = 0;
36 int stats_refl = 0; // unique reflections with 2+ observations (used for statistics)
37 double r_merge_num = 0; // numerator for R-merge
38 double r_meas_num = 0; // numerator for R-meas
39 double r_pim_num = 0; // numerator for R-pim
40 double r_denom = 0; // denominator for R-*
41 // sums for CC1/2
42 double sum_ibar = 0;
43 double sum_ibar2 = 0;
44 double sum_sig2_eps = 0;
45
48 void add_other(const MergingStats& o) {
49 all_refl += o.all_refl;
50 unique_refl += o.unique_refl;
51 stats_refl += o.stats_refl;
52 r_merge_num += o.r_merge_num;
53 r_meas_num += o.r_meas_num;
54 r_pim_num += o.r_pim_num;
55 r_denom += o.r_denom;
56 sum_ibar += o.sum_ibar;
57 sum_ibar2 += o.sum_ibar2;
58 sum_sig2_eps += o.sum_sig2_eps;
59 }
60
61 double r_merge() const { return r_merge_num / r_denom; }
62 double r_meas() const { return r_meas_num / r_denom; }
63 double r_pim() const { return r_pim_num / r_denom; }
64 double cc_half() const; // calculated using sigma-tau method
66 double cc_full() const {
67 double cc = cc_half();
68 return 2 * cc / (1 + cc);
69 }
70 double cc_star() const { return std::sqrt(cc_full()); }
71};
72
75
77 struct Refl {
79 int8_t isign; // 1 for I(+), -1 for I(-), 0 for mean or unmerged
80 int8_t isym; // for unmerged data: encodes symmetry op like M/ISYM in MTZ
81 short nobs;
82 double value;
83 double sigma;
84
85 bool operator<(const Refl& o) const {
86 return std::tie(hkl[0], hkl[1], hkl[2], isign) <
87 std::tie(o.hkl[0], o.hkl[1], o.hkl[2], o.isign);
88 }
89 // for merged data
90 const char* intensity_label() const {
91 if (isign == 0)
92 return "<I>";
93 return isign > 0 ? "I(+)" : "I(-)";
94 }
95 std::string hkl_label() const {
96 return cat(intensity_label(), " (", hkl[0], ' ', hkl[1], ' ', hkl[2], ')');
97 }
98 };
99
101 SMat33<double> b = {0., 0., 0., 0., 0., 0.};
102
103 bool ok() const { return !b.all_zero(); }
104 double scale(const Miller& hkl, const UnitCell& cell) const {
105 Vec3 s = cell.frac.mat.left_multiply(Vec3(hkl[0], hkl[1], hkl[2]));
106 return std::exp(0.5 * b.r_u_r(s));
107 }
108 };
109
110 std::vector<Refl> data;
111 const SpaceGroup* spacegroup = nullptr;
113 double unit_cell_rmsd[6] = {0., 0., 0., 0., 0., 0.};
115 DataType type = DataType::Unknown;
116 std::vector<Op> isym_ops;
118
119 static const char* type_str(DataType data_type) {
120 switch (data_type) {
121 case DataType::Unmerged: return "I";
122 case DataType::Mean: return "<I>";
123 case DataType::Anomalous: return "I+/I-";
124 case DataType::MergedAM:
125 case DataType::MergedMA:
126 case DataType::UAM:
127 case DataType::Unknown: return "n/a";
128 }
129 unreachable();
130 }
131
132 const char* type_str() const { return Intensities::type_str(type); }
133
134 std::string spacegroup_str() const { return spacegroup ? spacegroup->xhm() : "none"; }
135
136 // returns (d_max, d_min)
137 std::array<double,2> resolution_range() const;
138
139 // pre: both are sorted
141
142 void add_if_valid(const Miller& hkl, int8_t isign, int8_t isym, double value, double sigma) {
143 // XDS marks rejected reflections with negative sigma.
144 // Sigma 0.0 rarely happens (e.g. 5tkn), but is also problematic.
145 if (!std::isnan(value) && sigma > 0)
146 data.push_back({hkl, isign, isym, /*nobs=*/0, value, sigma});
147 }
148
150 if (!spacegroup)
151 return;
152 GroupOps gops = spacegroup->operations();
153 vector_remove_if(data, [&](Refl& x) { return gops.is_systematically_absent(x.hkl); });
154 }
155
156 void sort() { std::sort(data.begin(), data.end()); }
157
159
161 Intensities m(*this);
162 m.merge_in_place(new_type);
163 return m;
164 }
165
167 std::vector<MergingStats> calculate_merging_stats(const Binner* binner,
168 char use_weights='Y') const;
169
170 // call with DataType::Anomalous before calculate_merging_stats() to get I+/I- stats
172
174
177 // with check_complete=true, throw if anomalous data is null where it shouldn't be
179
180 void import_mtz(const Mtz& mtz, DataType data_type=DataType::Unknown);
181
185
187
188 void import_refln_block(const ReflnBlock& rb, DataType data_type=DataType::Unknown);
189
190 void import_xds(const XdsAscii& xds);
191
192 // returns STARANISO version or empty string
193 std::string take_staraniso_b_from_mtz(const Mtz& mtz);
194
196
198};
199
200// Minimal compatibility with MtzDataProxy and ReflnDataProxy.
202 const Intensities& intensities_;
203 size_t stride() const { return 1; }
204 size_t size() const { return intensities_.data.size(); }
205 const SpaceGroup* spacegroup() const { return intensities_.spacegroup; }
206 const UnitCell& unit_cell() const { return intensities_.unit_cell; }
207 Miller get_hkl(size_t offset) const { return intensities_.data[offset].hkl; }
208 double get_num(size_t n) const { return intensities_.data[n].value; }
209};
210
211template<typename DataProxy>
212std::pair<DataType, size_t> check_data_type_under_symmetry(const DataProxy& proxy) {
213 const SpaceGroup* sg = proxy.spacegroup();
214 if (!sg)
215 return {DataType::Unknown, 0};
216 std::unordered_map<Op::Miller, int, MillerHash> seen;
217 ReciprocalAsu asu(sg);
218 GroupOps gops = sg->operations();
219 bool centric = gops.is_centrosymmetric();
221 for (size_t i = 0; i < proxy.size(); i += proxy.stride()) {
222 auto hkl_sign = asu.to_asu_sign(proxy.get_hkl(i), gops);
223 int sign = hkl_sign.second ? 2 : 1; // 2=positive, 1=negative
224 auto r = seen.emplace(hkl_sign.first, sign);
225 if (data_type != DataType::Unmerged && !r.second) {
226 if ((r.first->second & sign) != 0 || centric) {
228 } else {
229 r.first->second |= sign;
231 }
232 }
233 }
234 return {data_type, seen.size()};
235}
236
237} // namespace gemmi
238#endif
#define GEMMI_DLL
Definition fail.hpp:53
void vector_remove_if(std::vector< T > &v, F &&condition)
Definition util.hpp:267
std::array< int, 3 > Miller
A synonym for convenient passing of hkl.
Definition unitcell.hpp:129
std::pair< DataType, size_t > check_data_type_under_symmetry(const DataProxy &proxy)
Definition intensit.hpp:212
Vec3_< double > Vec3
Definition math.hpp:113
std::string cat(Args const &... args)
Definition util.hpp:33
GEMMI_DLL std::string read_staraniso_b_from_mtz(const Mtz &mtz, SMat33< double > &output)
Returns STARANISO version or empty string.
void unreachable()
Definition fail.hpp:80
Statistics utilities: classes Covariance, Correlation, DataStats.
bool is_systematically_absent(const Op::Miller &hkl) const
Definition symmetry.hpp:332
bool is_centrosymmetric() const
Definition symmetry.hpp:304
Miller get_hkl(size_t offset) const
Definition intensit.hpp:207
const UnitCell & unit_cell() const
Definition intensit.hpp:206
double get_num(size_t n) const
Definition intensit.hpp:208
const SpaceGroup * spacegroup() const
Definition intensit.hpp:205
double scale(const Miller &hkl, const UnitCell &cell) const
Definition intensit.hpp:104
std::string hkl_label() const
Definition intensit.hpp:95
bool operator<(const Refl &o) const
Definition intensit.hpp:85
const char * intensity_label() const
Definition intensit.hpp:90
static const char * type_str(DataType data_type)
Definition intensit.hpp:119
void import_xds(const XdsAscii &xds)
void merge_in_place(DataType new_type)
void import_unmerged_intensities_from_mmcif(const ReflnBlock &rb)
void import_f_squared_from_mmcif(const ReflnBlock &rb)
bool take_staraniso_b_from_mmcif(const cif::Block &block)
std::vector< Op > isym_ops
Definition intensit.hpp:116
void import_mean_intensities_from_mtz(const Mtz &mtz)
std::string spacegroup_str() const
Definition intensit.hpp:134
void import_anomalous_intensities_from_mtz(const Mtz &mtz, bool check_complete=false)
void import_anomalous_intensities_from_mmcif(const ReflnBlock &rb, bool check_complete=false)
void switch_to_asu_indices()
void import_mean_intensities_from_mmcif(const ReflnBlock &rb)
AnisoScaling staraniso_b
Definition intensit.hpp:117
std::string take_staraniso_b_from_mtz(const Mtz &mtz)
void remove_systematic_absences()
Definition intensit.hpp:149
void add_if_valid(const Miller &hkl, int8_t isign, int8_t isym, double value, double sigma)
Definition intensit.hpp:142
Mtz prepare_merged_mtz(bool with_nobs)
DataType prepare_for_merging(DataType new_type)
const char * type_str() const
Definition intensit.hpp:132
void import_refln_block(const ReflnBlock &rb, DataType data_type=DataType::Unknown)
void import_unmerged_intensities_from_mtz(const Mtz &mtz)
std::array< double, 2 > resolution_range() const
Intensities merged(DataType new_type)
Definition intensit.hpp:160
void import_mtz(const Mtz &mtz, DataType data_type=DataType::Unknown)
Correlation calculate_correlation(const Intensities &other) const
std::vector< Refl > data
Definition intensit.hpp:110
const SpaceGroup * spacegroup
Definition intensit.hpp:111
std::vector< MergingStats > calculate_merging_stats(const Binner *binner, char use_weights='Y') const
use_weights can be 'Y' (yes, like Aimless), 'U' (unweighted), 'X' (yes, like XDS)
Vec3 left_multiply(const Vec3 &p) const
Definition math.hpp:173
double cc_full() const
split-half reliability using the Spearman-Brown prediction formula :-)
Definition intensit.hpp:66
double cc_half() const
double r_merge() const
Definition intensit.hpp:61
void add_other(const MergingStats &o)
This class is additive.
Definition intensit.hpp:48
double r_pim() const
Definition intensit.hpp:63
double cc_star() const
Definition intensit.hpp:70
double r_meas() const
Definition intensit.hpp:62
std::pair< Op::Miller, bool > to_asu_sign(const Op::Miller &hkl, const GroupOps &gops) const
Similar to to_asu(), but the second returned value is sign: true for + or centric.
GroupOps operations() const
Definition symmetry.hpp:837
std::string xhm() const
Definition symmetry.hpp:755
Unit cell.
Definition unitcell.hpp:165
Transform frac
Definition unitcell.hpp:174
Crystallographic Symmetry. Space Groups. Coordinate Triplets.
Unit cell.
Utilities. Mostly for working with strings and vectors.