Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

buildable_monomer_family_pattern.h

Go to the documentation of this file.
00001 // -*- mode: c++; -*-
00002 //
00003 //The Biomolecule Toolkit (BTK) is a C++ library for use in the
00004 //modeling, analysis, and design of biological macromolecules.
00005 //Copyright (C) 2004, Christopher Saunders <ctsa@users.sourceforge.net>
00006 //
00007 //This program is free software; you can redistribute it and/or modify
00008 //it under the terms of the GNU Lesser General Public License as published
00009 //by the Free Software Foundation; either version 2.1 of the License, or (at
00010 //your option) any later version.
00011 //
00012 //This program is distributed in the hope that it will be useful,  but
00013 //WITHOUT ANY WARRANTY; without even the implied warranty of
00014 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015 //Lesser General Public License for more details. 
00016 //
00017 //You should have received a copy of the GNU Lesser General Public License 
00018 //along with this program; if not, write to the Free Software Foundation, 
00019 //Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00020 //
00021 
00022 // singleton static data class -
00023 // abstract base to singleton data classes defining 
00024 //  family patterns for peptide and nucleotide types
00025 //
00026 
00027 #ifndef BTK_BUILDABLE_MONOMER_FAMILY_PATTERN_H
00028 #define BTK_BUILDABLE_MONOMER_FAMILY_PATTERN_H
00029 
00030 
00031 #include "atom_group_concept.h"
00032 #include "atom_index_tetrad.h"
00033 #include "atom_index_pair.h"
00034 #include "atom_types.h"
00035 #include "group_types.h"
00036 #include "group_variant_types.h"
00037 #include "torsion_types.h"
00038 
00039 #include <boost/optional.hpp>
00040 #include <boost/tuple/tuple.hpp>
00041 
00042 #include <cassert>
00043 
00044 #include <map>
00045 #include <set>
00046 #include <utility>
00047 #include <vector>
00048 
00049 namespace BTK{
00050 
00051 
00052   class BuildableMonomerFamilyPattern {
00053     typedef BuildableMonomerFamilyPattern self_type;
00054   public:
00055     typedef self_type types;
00056     typedef std::pair<int,ATOM::index_t> monomer_atom_idx_t;
00057 
00058     typedef AtomIndexPair bond_t;
00059 
00060     typedef AtomIndexTetrad tetrad_t;
00061 
00062     typedef std::set<ATOM::index_t> atom_container_t;
00063     typedef std::set<bond_t> bond_container_t;
00064     typedef std::set<tetrad_t> tetrad_container_t;
00065  
00066     typedef boost::tuple<monomer_atom_idx_t,monomer_atom_idx_t,
00067                          monomer_atom_idx_t,monomer_atom_idx_t> torsion_atom_t;
00068 
00069   protected:
00070     typedef std::map<monomer_atom_idx_t,tetrad_container_t> tetrad_map_t;
00071     
00072     typedef std::map<TORSION::index_t,torsion_atom_t> torsion_atom_map_t;
00073 
00074     struct member_pattern_t {
00075       atom_container_t _atoms;
00076       bond_container_t _bonds;
00077       tetrad_map_t _tetrads;
00078     };
00079 
00080     struct member_modifier_t {
00081       member_pattern_t _add;
00082       member_pattern_t _delete;
00083     };
00084 
00085     typedef std::map<GROUP_VARIANT::index_t,member_modifier_t> member_modifier_map_t;
00086 
00087     struct modifiable_member_pattern_t {
00088       member_pattern_t _default;
00089       member_modifier_map_t _modifiers;
00090 
00091       // torsion atoms are not eligible for modification (implementable -- but what would the
00092       // appication be??)
00093       torsion_atom_map_t _torsion_atoms;
00094     };
00095 
00096     
00097     typedef std::map<GROUP::index_t,modifiable_member_pattern_t> member_map_t;
00098 
00099 //    typedef std::map<GROUP::index_t,member_pattern_t> member_map_t;
00100 
00101     struct family_pattern_t { 
00102       member_map_t _member_map;
00103     };
00104 
00105   public:    
00106     // changing the family_pattern class over to functional access --
00107     // temporarily making the whole scheme much less efficient while
00108     // the variant scheme is being worked out, (now we pass out copies
00109     // of the data instead of const refs... yuk!!)
00110     //
00111     
00112     atom_container_t 
00113     atoms(GROUP::index_t g,
00114           AtomGroupConcept::group_variant_container_t v) const 
00115     {
00116       return get_modified_data<atom_container_t>(g,v,get_atoms());
00117     }
00118     
00119     bond_container_t 
00120     bonds(GROUP::index_t g,
00121     AtomGroupConcept::group_variant_container_t v) const
00122     {
00123       return get_modified_data<bond_container_t>(g,v,get_bonds());
00124     }
00125 
00126     tetrad_container_t
00127     tetrads(GROUP::index_t g,
00128       AtomGroupConcept::group_variant_container_t v,
00129             monomer_atom_idx_t ma) const
00130     {
00131       return get_modified_data<tetrad_container_t>(g,v,get_tetrads(ma));
00132     }
00133 
00134     // torsion atoms are not subject to the group variant scheme...
00135     torsion_atom_t
00136     torsion_atoms(GROUP::index_t g,
00137                   TORSION::index_t t) const
00138     {
00139       torsion_atom_map_t::const_iterator ci = member(g)._torsion_atoms.find(t);
00140       if(ci == member(g)._torsion_atoms.end()) { assert(0); }
00141       return ci->second;
00142     }
00143 
00144   protected:
00145     virtual family_pattern_t& family_pattern() = 0;
00146     virtual const family_pattern_t& family_pattern() const = 0;
00147 
00148     //
00149     // This method is being used instead of writing the tetrad info
00150     // directly in the family pattern constructor to get around a gcc
00151     // optimization behaviour that causes *very* high compile time and
00152     // memory usage when the tetrad code pattern below is specified
00153     // directly in the code for each tetrad.
00154     //
00155     // This is defined separately from the class definition to
00156     // prevent inlining. If this function is inlined the usual gcc
00157     // optimization problems occur.
00158     //
00159     void
00160     tetrad_helper(GROUP::index_t g,
00161                   int i1,
00162                   ATOM::index_t a1,
00163                   int i2,
00164                   ATOM::index_t a2,
00165                   int i3,
00166                   ATOM::index_t a3,
00167                   int i4,
00168                   ATOM::index_t a4,
00169                   double l,
00170                   double a,
00171                   double d,
00172                   bool r);
00173   private:
00174 
00175     struct get_atoms {
00176       atom_container_t
00177       operator()(const member_pattern_t& t)
00178       {
00179         return t._atoms;
00180       }
00181     };
00182    
00183     struct get_bonds {
00184       bond_container_t
00185       operator()(const member_pattern_t& t)
00186       {
00187         return t._bonds;
00188       }
00189     };
00190 
00191     struct get_tetrads {
00192       get_tetrads(monomer_atom_idx_t ma) : _ma(ma) {}
00193 
00194       tetrad_container_t
00195       operator()(const member_pattern_t& t)
00196       {
00197         const tetrad_map_t& tm = t._tetrads;
00198         tetrad_map_t::const_iterator tmi = tm.find(_ma);
00199 
00200         // we expect calls to tetrad for atomtypes with no tetrads, this
00201         // should not be treated as an error
00202         //
00203         if( tmi == tm.end() ) 
00204           return tetrad_container_t();
00205         else 
00206           return tmi->second;
00207       }
00208 
00209     private:
00210       monomer_atom_idx_t _ma;
00211     };
00212    
00213 
00214     // accepts one of the get_ function objects above, together with
00215     // the modifier set, to produce the appropriate modified container
00216     // 
00217     template <typename SetContainer,typename UnaryFunction>
00218     SetContainer
00219     get_modified_data(GROUP::index_t g,
00220                       AtomGroupConcept::group_variant_container_t v,
00221                       UnaryFunction get_func) const 
00222     {
00223       SetContainer c = get_func(member(g)._default);
00224 
00225       typedef AtomGroupConcept::group_variant_container_t::const_iterator vci;
00226       vci i=v.begin(),i_end=v.end();
00227 
00228       // add variant additions and delete variant subtractions
00229       //
00230       for(;i!=i_end;++i){
00231         member_modifier_map_t::const_iterator mm = member(g)._modifiers.find(*i);
00232         if( mm == member(g)._modifiers.end() ) continue;
00233 
00234         const SetContainer& tmp_add = get_func(mm->second._add);
00235         c.insert(tmp_add.begin(),tmp_add.end());
00236         
00237         const SetContainer& tmp_delete = get_func(mm->second._delete);
00238         typename SetContainer::const_iterator si=tmp_delete.begin(),si_end=tmp_delete.end();
00239         for(;si!=si_end;++si){
00240           c.erase(*si);
00241         }
00242       }
00243       return c;
00244     }
00245 
00246 
00247     const modifiable_member_pattern_t& 
00248     member(GROUP::index_t g) const 
00249     {
00250       member_map_t::const_iterator ci = family_pattern()._member_map.find(g);
00251       if( ci == family_pattern()._member_map.end() ) { assert(0); }
00252       return ci->second;
00253     }
00254 
00255   };
00256 } // namespace BTK
00257 
00258 
00259 
00260 #endif

Generated on Wed Apr 14 00:43:16 2004 for BTK by doxygen 1.3.6