00001 #ifndef CCTBX_GEOMETRY_RESTRAINTS_UTILS_H
00002 #define CCTBX_GEOMETRY_RESTRAINTS_UTILS_H
00003
00004 #include <cctbx/uctbx.h>
00005 #include <cctbx/sgtbx/rt_mx.h>
00006 #include <cctbx/error.h>
00007 #include <cctbx/import_scitbx_af.h>
00008 #include <scitbx/vec3.h>
00009 #include <scitbx/array_family/shared.h>
00010
00011 namespace cctbx { namespace geometry_restraints {
00012
00020 inline
00021 scitbx::mat3<double>
00022 r_inv_cart(
00023 uctbx::unit_cell const& unit_cell,
00024 sgtbx::rt_mx const& rt_mx)
00025 {
00026 typedef scitbx::type_holder<double> t_h;
00027 scitbx::mat3<double> o(unit_cell.orthogonalization_matrix());
00028 scitbx::mat3<double> f(unit_cell.fractionalization_matrix());
00029 scitbx::mat3<double> r_inv_cart_
00030 = o*rt_mx.r().inverse().as_floating_point(t_h())*f;
00031 return r_inv_cart_;
00032 }
00033
00037 inline
00038 double
00039 angle_delta_deg(double angle_1, double angle_2, int periodicity=1)
00040 {
00041 double half_period = 180./std::max(1,std::abs(periodicity));
00042 double d = std::fmod(angle_2-angle_1, 2*half_period);
00043 if (d < -half_period) d += 2*half_period;
00044 else if (d > half_period) d -= 2*half_period;
00045 return d;
00046 }
00047
00048 namespace detail {
00049
00050 template <typename ProxyType, typename RestraintType>
00051 struct generic_deltas
00052 {
00053 static
00054 af::shared<double>
00055 get(
00056 af::const_ref<scitbx::vec3<double> > const& sites_cart,
00057 af::const_ref<ProxyType> const& proxies)
00058 {
00059 af::shared<double> result((af::reserve(proxies.size())));
00060 for(std::size_t i=0;i<proxies.size();i++) {
00061 ProxyType const& proxy = proxies[i];
00062 RestraintType restraint(sites_cart, proxy);
00063 result.push_back(restraint.delta);
00064 }
00065 return result;
00066 }
00067
00068 static
00069 af::shared<double>
00070 get(
00071 uctbx::unit_cell const& unit_cell,
00072 af::const_ref<scitbx::vec3<double> > const& sites_cart,
00073 af::const_ref<ProxyType> const& proxies)
00074 {
00075 af::shared<double> result((af::reserve(proxies.size())));
00076 for(std::size_t i=0;i<proxies.size();i++) {
00077 ProxyType const& proxy = proxies[i];
00078 RestraintType restraint(unit_cell, sites_cart, proxy);
00079 result.push_back(restraint.delta);
00080 }
00081 return result;
00082 }
00083 };
00084
00085 template <typename ProxyType, typename RestraintType>
00086 struct generic_residuals
00087 {
00088 static
00089 af::shared<double>
00090 get(
00091 af::const_ref<scitbx::vec3<double> > const& sites_cart,
00092 af::const_ref<ProxyType> const& proxies)
00093 {
00094 af::shared<double> result((af::reserve(proxies.size())));
00095 for(std::size_t i=0;i<proxies.size();i++) {
00096 ProxyType const& proxy = proxies[i];
00097 RestraintType restraint(sites_cart, proxy);
00098 result.push_back(restraint.residual());
00099 }
00100 return result;
00101 }
00102
00103 static
00104 af::shared<double>
00105 get(
00106 uctbx::unit_cell const& unit_cell,
00107 af::const_ref<scitbx::vec3<double> > const& sites_cart,
00108 af::const_ref<ProxyType> const& proxies)
00109 {
00110 af::shared<double> result((af::reserve(proxies.size())));
00111 for(std::size_t i=0;i<proxies.size();i++) {
00112 ProxyType const& proxy = proxies[i];
00113 RestraintType restraint(unit_cell, sites_cart, proxy);
00114 result.push_back(restraint.residual());
00115 }
00116 return result;
00117 }
00118 };
00119
00120 template <typename ProxyType, typename RestraintType>
00121 struct generic_residual_sum
00122 {
00123 static
00124 double
00125 get(
00126 af::const_ref<scitbx::vec3<double> > const& sites_cart,
00127 af::const_ref<ProxyType> const& proxies,
00128 af::ref<scitbx::vec3<double> > const& gradient_array)
00129 {
00130 CCTBX_ASSERT( gradient_array.size() == 0
00131 || gradient_array.size() == sites_cart.size());
00132 double result = 0;
00133 for(std::size_t i=0;i<proxies.size();i++) {
00134 ProxyType const& proxy = proxies[i];
00135 RestraintType restraint(sites_cart, proxy);
00136 result += restraint.residual();
00137 if (gradient_array.size() != 0) {
00138 restraint.add_gradients(gradient_array, proxy.i_seqs);
00139 }
00140 }
00141 return result;
00142 }
00143
00144 static
00145 double
00146 get(
00147 uctbx::unit_cell const& unit_cell,
00148 af::const_ref<scitbx::vec3<double> > const& sites_cart,
00149 af::const_ref<ProxyType> const& proxies,
00150 af::ref<scitbx::vec3<double> > const& gradient_array)
00151 {
00152 CCTBX_ASSERT( gradient_array.size() == 0
00153 || gradient_array.size() == sites_cart.size());
00154 double result = 0;
00155 for(std::size_t i=0;i<proxies.size();i++) {
00156 ProxyType const& proxy = proxies[i];
00157 RestraintType restraint(unit_cell, sites_cart, proxy);
00158 result += restraint.residual();
00159 if (gradient_array.size() != 0) {
00160 restraint.add_gradients(unit_cell, gradient_array, proxy);
00161 }
00162 }
00163 return result;
00164 }
00165 };
00166
00167 }
00168
00169 }}
00170
00171 #endif // CCTBX_GEOMETRY_RESTRAINTS_UTILS_H