00001 #ifndef CCTBX_DMTBX_TRIPLET_PHASE_RELATION_H
00002 #define CCTBX_DMTBX_TRIPLET_PHASE_RELATION_H
00003
00004 #include <scitbx/math/modulo.h>
00005 #include <cctbx/error.h>
00006 #include <scitbx/constants.h>
00007
00008 namespace cctbx { namespace dmtbx {
00009
00011 class triplet_phase_relation
00012 {
00013 public:
00015 triplet_phase_relation() {}
00016
00018 triplet_phase_relation(
00019 std::size_t ik,
00020 bool friedel_flag_k,
00021 int ht_k,
00022 std::size_t ihmk,
00023 bool friedel_flag_hmk,
00024 int ht_hmk,
00025 int t_den)
00026 {
00027 CCTBX_ASSERT(ht_k >= 0);
00028 CCTBX_ASSERT(ht_hmk >= 0);
00029 if (ik < ihmk || (ik == ihmk && friedel_flag_k == false)) {
00030 ik_ = ik;
00031 ihmk_ = ihmk;
00032 friedel_flag_k_ = friedel_flag_k;
00033 friedel_flag_hmk_ = friedel_flag_hmk;
00034 }
00035 else {
00036 ik_ = ihmk;
00037 ihmk_ = ik;
00038 friedel_flag_k_ = friedel_flag_hmk;
00039 friedel_flag_hmk_ = friedel_flag_k;
00040 }
00041 if (!friedel_flag_k) ht_k *= -1;
00042 if (!friedel_flag_hmk) ht_hmk *= -1;
00043 ht_sum_ = scitbx::math::mod_positive(ht_k + ht_hmk, t_den);
00044 }
00045
00047 std::size_t
00048 ik() const { return ik_; }
00049
00051 bool
00052 friedel_flag_k() const { return friedel_flag_k_; }
00053
00055 std::size_t
00056 ihmk() const { return ihmk_; }
00057
00059 bool
00060 friedel_flag_hmk() const { return friedel_flag_hmk_; }
00061
00063 int
00064 ht_sum() const { return ht_sum_; }
00065
00067
00073 bool
00074 is_sigma_2(std::size_t ih) const
00075 {
00076 return ik_ != ih && ihmk_ != ih && ik_ != ihmk_;
00077 }
00078
00080 bool is_similar_to(triplet_phase_relation const& other) const
00081 {
00082 return ik_ == other.ik_ && ihmk_ == other.ihmk_;
00083 }
00084
00086 bool operator<(triplet_phase_relation const& other) const
00087 {
00088 if (ik_ < other.ik_) return true;
00089 if (ik_ > other.ik_) return false;
00090 if (ihmk_ < other.ihmk_) return true;
00091 if (ihmk_ > other.ihmk_) return false;
00092 if (ht_sum_ < other.ht_sum_) return true;
00093 if (ht_sum_ > other.ht_sum_) return false;
00094 if (!friedel_flag_k_ && other.friedel_flag_k_) return true;
00095 if (friedel_flag_k_ && !other.friedel_flag_k_) return false;
00096 if (!friedel_flag_hmk_ && other.friedel_flag_hmk_) return true;
00097 return false;
00098 }
00099
00101 template <typename FloatType>
00102 FloatType
00103 phi_k_phi_hmk(const FloatType* phases, int t_den) const
00104 {
00105 FloatType phi_k = phases[ik_];
00106 if (friedel_flag_k_) phi_k = -phi_k;
00107 FloatType phi_hmk = phases[ihmk_];
00108 if (friedel_flag_hmk_) phi_hmk = -phi_hmk;
00109 return phi_k + phi_hmk + (scitbx::constants::two_pi * ht_sum_) / t_den;
00110 }
00111
00112 protected:
00113 std::size_t ik_;
00114 bool friedel_flag_k_;
00115 std::size_t ihmk_;
00116 bool friedel_flag_hmk_;
00117 int ht_sum_;
00118 };
00119
00121 class weighted_triplet_phase_relation : public triplet_phase_relation
00122 {
00123 public:
00125 weighted_triplet_phase_relation() {}
00126
00128 weighted_triplet_phase_relation(
00129 triplet_phase_relation const& tpr,
00130 std::size_t weight)
00131 :
00132 triplet_phase_relation(tpr),
00133 weight_(weight)
00134 {}
00135
00137 std::size_t
00138 weight() const { return weight_; }
00139
00140 protected:
00141 std::size_t weight_;
00142 };
00143
00144 }}
00145
00146 #endif // CCTBX_DMTBX_TRIPLET_PHASE_RELATION_H