00001 #ifndef CCTBX_CRYSTL_ORIENT_H
00002 #define CCTBX_CRYSTL_ORIENT_H
00003
00004 #include <cctbx/uctbx.h>
00005 #include <cctbx/sgtbx/change_of_basis_op.h>
00006
00007 namespace cctbx {
00008
00010 typedef scitbx::vec3<double> oc_vec3;
00012 typedef scitbx::mat3<double> oc_mat3;
00014 typedef scitbx::af::shared<oc_vec3> oc_vec3_list;
00015
00016 enum basis_type { direct=0, reciprocal=1 };
00017
00019
00023 template <typename FloatType>
00024 oc_vec3
00025 vector_rotate_thru(oc_vec3 const& vec, oc_vec3 const& unit,
00026 FloatType const& angle){
00027
00028
00029
00030 return unit*(unit*vec)
00031 +(vec-(unit*(unit*vec)))*std::cos(angle)
00032 -(vec.cross(unit))*std::sin(angle);
00033 }
00034
00036
00054 class crystal_orientation
00055 {
00056 public:
00058
00061 crystal_orientation(){}
00062
00064
00067 explicit
00068 crystal_orientation(oc_mat3 const&, bool const&);
00069
00071 cctbx::uctbx::unit_cell
00072 unit_cell() const;
00073
00075 cctbx::uctbx::unit_cell
00076 unit_cell_inverse() const;
00077
00079 oc_mat3
00080 direct_matrix() const;
00081
00083 oc_mat3
00084 reciprocal_matrix() const;
00085
00087
00092 crystal_orientation
00093 change_basis(cctbx::sgtbx::change_of_basis_op const&) const;
00094
00096
00101 crystal_orientation
00102 change_basis(oc_mat3 const&) const;
00103
00105
00109 template <typename FloatType>
00110 crystal_orientation
00111 rotate_thru(oc_vec3 const& unit_axis, FloatType const& angle){
00112
00113
00114
00115
00116 oc_vec3_list abc;
00117 for (int i=0; i<3; ++i){
00118 abc.push_back( Astar_.get_column(i) );
00119 }
00120
00121 oc_vec3_list newabc;
00122 for (int i=0; i<3; ++i){
00123 newabc.push_back( vector_rotate_thru(abc[i],unit_axis,angle) );
00124 }
00125
00126 oc_mat3 new_recip_matrix;
00127 for (int i=0; i<3; ++i){
00128 new_recip_matrix.set_column( i, newabc[i] );
00129 }
00130
00131 return crystal_orientation(new_recip_matrix, cctbx::reciprocal);
00132 }
00133
00135
00139 inline double
00140 direct_mean_square_difference(crystal_orientation const& other) const
00141 {
00142 return cctbx::uctbx::mean_square_difference(
00143 direct_matrix(),other.direct_matrix())/3;
00144 }
00145
00147
00153 inline double
00154 difference_Z_score(crystal_orientation const& other) const
00155 {
00156 oc_mat3 diff = (direct_matrix() - other.direct_matrix());
00157 double Z = 0.0;
00158 for (int idx = 0; idx<3; ++idx){
00159 oc_vec3 this_basis_vector(direct_matrix().get_row(idx));
00160 oc_vec3 diff_vector(diff.get_row(idx));
00161 Z += diff_vector.length()/(0.01*this_basis_vector.length());
00162 }
00163 return Z;
00164 }
00165
00167
00170 oc_mat3
00171 best_similarity_transformation(crystal_orientation const& other,
00172 double const& fractional_length_tolerance,
00173 int unimodular_generator_range=1) const;
00174
00175 protected:
00177 oc_mat3 Astar_;
00178
00179 };
00180 }
00181
00182 #endif // CCTBX_CRYSTL_ORIENT_H