00001
00002
00003
00004
00005
00006
00007
00008 #ifndef IMPATOM_FRAGMENT_H
00009 #define IMPATOM_FRAGMENT_H
00010
00011 #include "atom_config.h"
00012 #include "Hierarchy.h"
00013 #include <IMP/Decorator.h>
00014 #include <IMP/core/internal/ArrayOnAttributesHelper.h>
00015
00016 IMPATOM_BEGIN_NAMESPACE
00017
00018
00019
00020
00021 class IMPATOMEXPORT Fragment: public Hierarchy
00022 {
00023
00024 struct Traits
00025 : public IMP::core::internal::ArrayOnAttributesHelper<IntKey, Int>
00026 {Traits(std::string str)
00027 : IMP::core::internal::ArrayOnAttributesHelper<IntKey, Int>(str){}
00028 };
00029 IMP_DECORATOR_ARRAY_DECL(private, Fragment, ResidueBegin,
00030 residue_begin,
00031 residue_begins, btraits_, int, Ints)
00032 IMP_DECORATOR_ARRAY_DECL(private, Fragment, ResidueEnd,
00033 residue_end,
00034 residue_ends, etraits_, int, Ints)
00035 static Traits btraits_;
00036 static Traits etraits_;
00037
00038
00039
00040
00041 void add_residue_indexes(int begin, int end);
00042 public:
00043 static Fragment setup_particle(Particle *p) {
00044 add_required_attributes_for_residue_begin(p, btraits_);
00045 add_required_attributes_for_residue_end(p, etraits_);
00046 if (!Hierarchy::particle_is_instance(p)) {
00047 Hierarchy::setup_particle(p);
00048 }
00049 return Fragment(p);
00050 }
00051
00052
00053 static Fragment setup_particle(Particle *p, Fragment o) {
00054 add_required_attributes_for_residue_begin(p, btraits_);
00055 add_required_attributes_for_residue_end(p, etraits_);
00056 if (!Hierarchy::particle_is_instance(p)) {
00057 Hierarchy::setup_particle(p);
00058 }
00059 Fragment f(p);
00060 for (unsigned int i=0; i< o.get_number_of_residue_begins(); ++i) {
00061 f.add_residue_begin(o.get_residue_begin(i));
00062 f.add_residue_end(o.get_residue_end(i));
00063 }
00064 return Fragment(p);
00065 }
00066
00067 virtual ~Fragment();
00068
00069 static bool particle_is_instance(Particle *p) {
00070 return has_required_attributes_for_residue_begin(p, btraits_)
00071 && Hierarchy::particle_is_instance(p);
00072 }
00073
00074
00075
00076 void set_residue_indexes( Ints o);
00077
00078 Ints get_residue_indexes() const;
00079
00080
00081
00082 bool get_contains_residue(int rindex) {
00083 for (unsigned int i=0; i< get_number_of_residue_begins(); ++i) {
00084 if (get_residue_begin(i) <= rindex) {
00085 if (get_residue_end(i) > rindex) return true;
00086 }
00087 }
00088 return false;
00089 }
00090
00091 #if !defined(IMP_DOXYGEN)
00092 #if !defined(SWIG)
00093 class ResidueIndexIterator {
00094 friend class Fragment;
00095 const Fragment *f_;
00096 int i_, j_;
00097 mutable int v_;
00098 public:
00099 typedef int value_type;
00100 typedef const int &reference;
00101 typedef const int* pointer;
00102 typedef std::forward_iterator_tag iterator_category;
00103 typedef int difference_type;
00104 ResidueIndexIterator(const Fragment * f, int index): f_(f) {
00105 i_=index;
00106 j_=0;
00107 }
00108 const ResidueIndexIterator& operator++() {
00109 ++j_;
00110 int diff= f_->get_residue_end(i_)- f_->get_residue_begin(i_);
00111 if (diff == j_) {
00112 ++i_;
00113 j_=0;
00114 }
00115 return *this;
00116 }
00117 ResidueIndexIterator operator++(int) {
00118 ResidueIndexIterator it= *this;
00119 operator++();
00120 return it;
00121 }
00122 int operator*() const {
00123 return f_->get_residue_begin(i_) + j_;
00124 }
00125 const int& operator->() const {
00126 v_= operator*();
00127 return v_;
00128 }
00129 bool operator==(const ResidueIndexIterator &o) const {
00130 IMP_INTERNAL_CHECK(f_ == o.f_, "Can't compare iterators from different "
00131 << "containers");
00132 return i_ == o.i_ && j_== o.j_;
00133 }
00134 bool operator!=(const ResidueIndexIterator &o) const {
00135 return !operator==(o);
00136 }
00137 };
00138 #endif // SWIG
00139 #else
00140 class ResidueIndexIterator;
00141 #endif
00142
00143 #if !defined(SWIG)
00144 ResidueIndexIterator residue_indexes_begin() const {
00145 return ResidueIndexIterator(this, 0);
00146 }
00147
00148 ResidueIndexIterator residue_indexes_end() const {
00149 return ResidueIndexIterator(this, get_number_of_residue_ends());
00150 }
00151 #endif
00152
00153 IMP_DECORATOR(Fragment, Hierarchy);
00154 };
00155
00156 IMP_DECORATORS(Fragment, Hierarchies);
00157
00158
00159
00160
00161
00162 IMP_OUTPUT_OPERATOR(Fragment);
00163
00164 IMPATOM_END_NAMESPACE
00165
00166 #endif