00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00024
00025 #ifndef BTK_MOLECULES_POLYMER_HPP
00026 #define BTK_MOLECULES_POLYMER_HPP
00027
00028 #include <list>
00029
00030 #include <boost/operators.hpp>
00031 #include <boost/iterator/reverse_iterator.hpp>
00032
00033 #include <btk/core/utility/grouped_element_iterator.hpp>
00034 #include <btk/core/molecules/polymer_structure.hpp>
00035
00036 namespace BTK {
00037 namespace MOLECULES {
00038
00053 template <typename MonomerType,
00054 typename ChemicalTypeSystemType =
00055 typename MonomerType::chemical_type_system,
00056 typename DictionaryType =
00057 typename ChemicalTypeSystemType::structure_dictionary,
00058 typename StorageStrategy = std::list<MonomerType> >
00059 class Polymer :
00060 public PolymerStructure<MonomerType,
00061 ChemicalTypeSystemType,
00062 DictionaryType,
00063 StorageStrategy>,
00064 public boost::less_than_comparable<Polymer<MonomerType,
00065 ChemicalTypeSystemType,
00066 DictionaryType,
00067 StorageStrategy> >
00068 {
00069 typedef PolymerStructure<MonomerType,
00070 ChemicalTypeSystemType,
00071 DictionaryType,
00072 StorageStrategy> base_type;
00073 typedef Polymer<MonomerType,
00074 ChemicalTypeSystemType,
00075 DictionaryType,
00076 StorageStrategy> self_type;
00077 public:
00078 IMPORT_POLYMER_STRUCTURE_TYPES(base_type);
00079
00082
00084 typedef typename monomer_type::atom_type atom_type;
00085
00087 typedef typename atom_type::id_type atom_id_type;
00088
00090
00091 typedef UTILITY::
00092 GroupedElementIterator<monomer_iterator,
00093 typename monomer_type::atom_iterator,
00094 monomer_type,
00095 atom_type> atom_iterator;
00096
00097 typedef boost::reverse_iterator<atom_iterator> reverse_atom_iterator;
00098
00099 typedef UTILITY::
00100 GroupedElementIterator<const_monomer_iterator,
00101 typename monomer_type::const_atom_iterator,
00102 monomer_type const,
00103 atom_type const> const_atom_iterator;
00104
00105 typedef boost::reverse_iterator<const_atom_iterator> const_reverse_atom_iterator;
00107
00113 Polymer(size_type s = 0,
00114 monomer_type const & m = monomer_type(),
00115 char chain_id = ' ',
00116 structure_id_type t = structure_id_type()) :
00117 base_type(s,m,t), _chain_id(chain_id) {}
00118
00124 template <typename MonomerIterator>
00125 Polymer(MonomerIterator first,
00126 MonomerIterator last,
00127 char chain_id = ' ',
00128 structure_id_type t = structure_id_type()) :
00129 base_type(first,last,t), _chain_id(chain_id) {}
00130
00131 Polymer(self_type const & source) :
00132 base_type(source), _chain_id(source._chain_id) {}
00133
00134 virtual ~Polymer() {}
00135
00137
00138
00140 atom_iterator structure_begin()
00141 {
00142 return atom_iterator(base_type::polymer_begin(),
00143 base_type::polymer_end(),
00144 &monomer_type::monomer_begin,
00145 &monomer_type::monomer_end);
00146 }
00147
00149 const_atom_iterator structure_begin() const
00150 {
00151 return const_atom_iterator(base_type::polymer_begin(),
00152 base_type::polymer_end(),
00153 &monomer_type::monomer_begin,
00154 &monomer_type::monomer_end);
00155 }
00156
00158 reverse_atom_iterator structure_rbegin()
00159 {
00160 return reverse_atom_iterator(self_type::structure_end());
00161 }
00162
00164 const_reverse_atom_iterator structure_rbegin() const
00165 {
00166 return const_reverse_atom_iterator(self_type::structure_end());
00167 }
00168
00170 atom_iterator structure_end()
00171 {
00172 return atom_iterator(base_type::polymer_begin(),
00173 base_type::polymer_end(),
00174 &monomer_type::monomer_begin,
00175 &monomer_type::monomer_end,
00176 true);
00177 }
00178
00180 const_atom_iterator structure_end() const
00181 {
00182 return const_atom_iterator(base_type::polymer_begin(),
00183 base_type::polymer_end(),
00184 &monomer_type::monomer_begin,
00185 &monomer_type::monomer_end,
00186 true);
00187 }
00188
00190 reverse_atom_iterator structure_rend()
00191 {
00192 return reverse_atom_iterator(self_type::structure_begin());
00193 }
00194
00196 const_reverse_atom_iterator structure_rend() const
00197 {
00198 return const_reverse_atom_iterator(self_type::structure_begin());
00199 }
00200
00203 size_type num_atoms() const
00204 {
00205 size_type s = 0;
00206 const_monomer_iterator mi;
00207
00208 for (mi = self_type::polymer_begin();
00209 mi != self_type::polymer_end(); ++mi) {
00210 s += mi->num_atoms();
00211 }
00212
00213 return s;
00214 }
00216
00220 virtual std::ostream & print(std::ostream & os,
00221 size_type first_atom_num = 1,
00222 size_type first_monomer_num = 1) const
00223 {
00224 const_monomer_iterator mi;
00225 unsigned group_num = first_monomer_num;
00226 unsigned atom_num = first_atom_num;
00227
00228 for (mi = self_type::polymer_begin();
00229 mi != self_type::polymer_end(); ++mi) {
00230 mi->print(os,
00231 atom_num,
00232 group_num++,
00233 _chain_id);
00234
00235 atom_num += mi->size();
00236 }
00237
00238 os << "TER\n";
00239
00240 return os;
00241 }
00242
00244
00245
00246 char chain_id() const { return _chain_id; }
00248 void set_chain_id(char chain_id) { _chain_id = chain_id; }
00250
00251
00252
00253
00254 IMPORT_BTK_SEQUENCE_METHODS(base_type);
00255
00256 using base_type::set_type;
00257 using base_type::set_chemical_type_system;
00258
00259 virtual dictionary const & get_dictionary() const
00260 {
00261 return base_type::get_chemical_type_system().get_structure_dictionary();
00262 }
00263
00264 virtual dictionary & get_dictionary()
00265 {
00266 return base_type::get_chemical_type_system().get_structure_dictionary();
00267 }
00268
00269 void swap(self_type & b)
00270 {
00271 base_type::swap(b);
00272 std::swap(_chain_id,b._chain_id);
00273 }
00274
00275 self_type const & operator=(self_type const & rhs)
00276 {
00277 if (this == &rhs) return *this;
00278 base_type::operator=(rhs);
00279 _chain_id = rhs._chain_id;
00280 return *this;
00281 }
00282
00283 bool operator==(self_type const & rhs) const
00284 {
00285 return (_chain_id == rhs._chain_id &&
00286 base_type::operator==(rhs));
00287 }
00288
00289 bool operator!=(self_type const & rhs) const
00290 {
00291 return !(operator==(rhs));
00292 }
00293
00294 bool operator<(self_type const & rhs) const
00295 {
00296 return (_chain_id < rhs._chain_id ||
00297 (_chain_id == rhs._chain_id && base_type::operator<(rhs)));
00298 }
00299
00300 private:
00301 char _chain_id;
00302 };
00303
00304 #define IMPORT_POLYMER_TYPES(PolymerType) \
00305 IMPORT_POLYMER_STRUCTURE_TYPES(PolymerType) \
00306 typedef typename PolymerType::atom_type atom_type; \
00307 typedef typename PolymerType::atom_id_type atom_id_type;
00308
00309 }
00310 }
00311
00312 #endif