faif
FoldedMatrix.h
1 #ifndef FOLDED_MATRIX_H
2 #define FOLDED_MATRIX_H
3 
4 /* the classes and functions to calculate and store energy matrix (in Nussinov algorithm).
5  The classes and function for internal use, by FoldedChain.h and FoldedPair.h (are not the library interface).
6 */
7 
8 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
9 //visual studio 8.0 - konwersja pomiedzy unsigned int a size_t
10 #pragma warning(disable:4267)
11 //visual studio 8.0 - arytmetyka dla iteratorow przy konwersji na inta
12 #pragma warning(disable:4244)
13 #endif
14 
15 #include <iterator>
16 #include <algorithm>
17 #include <cassert>
18 #include <boost/noncopyable.hpp>
19 #include <boost/scoped_ptr.hpp>
20 #include <boost/bind.hpp>
21 #include <boost/ref.hpp>
22 
23 
24 #include "Chain.h"
25 #include "SecStruct.h"
26 
27 namespace faif {
28  namespace dna {
29 
30  /** \brief matrix - 2D array with indexing */
31  class Matrix : boost::noncopyable {
32  public:
33  Matrix(unsigned int length) : len_(length) {
34  unsigned int size_ = len_*len_;
35  m_ = new EnergyValue[size_];
36  std::fill(m_, m_ + size_, 0);
37  // for(unsigned int i=0;i<size_;++i) m_[i] = 0;
38  }
39  ~Matrix() { delete [] m_; }
40  const EnergyValue& get(int x, int y) const{ return m_[x*len_+y]; }
41  void set(int x, int y, EnergyValue val) { m_[x*len_ + y] = val; }
42  unsigned int getLength() const { return len_; }
43  private:
44  unsigned int len_;
45  EnergyValue* m_;
46  };
47 
48  class SecStructProxy;
49  typedef boost::scoped_ptr<SecStructProxy> SecStructProxyPtr;
50 
51  /** strategy to use folded matrix algorithm with single chain and with two chains */
53  public:
54  FoldedMatrixStrategy(const EnergyNucleo& energy) : energy_(energy) {}
55  virtual ~FoldedMatrixStrategy() {}
56 
57  /** return the iterator for nuleotide of i-th index in matrix */
58  virtual Chain::const_iterator getNucleotide(int index) const = 0;
59 
60  /** returns the split index (the first index belonging to the second chain) */
61  virtual int getSplitIndex() const = 0;
62 
63  /** returns the number of nucleotides in chain (chains) */
64  virtual int getLength() const = 0;
65 
66  /** calculates energy between two nucleotides of given indexes */
67  int getEnergy(int index_A, int index_B) const {
68  return energy_.getEnergy( *getNucleotide(index_A), *getNucleotide(index_B) );
69  }
70  private:
71  FoldedMatrixStrategy& operator=(const FoldedMatrixStrategy&); //!< private, reference members
72  const EnergyNucleo& energy_;
73  };
74 
75  /** dna chain or two dna chains with energy matrix */
76  class FoldedMatrix : boost::noncopyable {
77  public:
78  // c-tor for single strand
79  FoldedMatrix(const FoldedMatrixStrategy& strategy, unsigned int max_foldings);
80 
81  ~FoldedMatrix() {}
82 
83  /** calculates secondary structures (backtracking in energy matrix) */
84  const SecStructures& getStructures();
85 
86  EnergyValue getSecStructEnergy() { return structure_energy_; }
87 
88  /** calculates one secondary structure (energy matrix view in depth) */
90  SecStruct structure;
91  findDepthRecur(structure, 0, strategy_.getLength() - 1);
92  return structure;
93  }
94 
95  std::ostream& printMatrix(std::ostream& os, int print_width) const ;
96 
97  std::ostream& printStructures(std::ostream& os, int print_width) const;
98  private:
99  const FoldedMatrixStrategy& strategy_;
100  unsigned int max_foldings_;
101 
102  Matrix matrix_;
103 
104  /** secondary structure energy */
105  EnergyValue structure_energy_;
106  SecStructProxyPtr proxy_;
107 
108  void makeMatrix();
109 
110  //SecStruct& findDepthRecur(SecStruct& structure, const ConnectPair& curr_point) const;
111  SecStruct& findDepthRecur(SecStruct& structure, int first_idx, int second_idx ) const;
112  };
113 
114 
115  //----------------------------------------------------------------------------------------------
116  //
117  // implementation
118  //
119  //----------------------------------------------------------------------------------------------
120 
121 
122  namespace {
123 
124  /** partly calculated sec structure and counter */
125  class SecStructCount {
126  public:
127  explicit SecStructCount(const SecStruct& sec_struct)
128  : counter_(1), sec_struct_(sec_struct) {}
129  SecStructCount(const SecStructCount& c)
130  : counter_(c.counter_), sec_struct_(c.sec_struct_) {}
131  ~SecStructCount() {}
132 
133  //comparison
134  bool operator==(const SecStructCount& s) const { return sec_struct_ == s.sec_struct_; }
135  //equiwalance
136  bool operator<(const SecStructCount& s) const { return sec_struct_ < s.sec_struct_; }
137 
138  //accessor
139  const SecStruct& get() const { return sec_struct_; }
140  //modyfikacja przechowywanej struktury
141  void addPair(const ConnectPair& pair) { sec_struct_.addPair(pair); }
142 
143  //zmnijesza licznik, zwraca true, jezeli licznik > 0
144  bool dec() const { --counter_; return counter_ > 0; }
145  //zwieksza licznik
146  void inc() const { ++counter_; }
147  //odczyt licznika
148  int getCounter() const { return counter_; }
149  private:
150  SecStructCount& operator=(const SecStructCount&); //zabroniony
151  mutable int counter_; //licznik odwolan
152  SecStruct sec_struct_; //przechowywana struktura drugorzedowa
153 
154  };
155 
156  //for debugging
157  inline std::ostream& operator<<(std::ostream& os, const SecStructCount& sec_struct_count) {
158  os << sec_struct_count.get() << "[" << sec_struct_count.getCounter() << "]";
159  return os;
160  }
161 
162  typedef std::set<SecStructCount> SecStructParts;
163  typedef SecStructParts::iterator StructPartIter;
164 
165  /** zarzadza czesciowo obliczonymi strukturami drugorzedowymi.
166  Usuwa te, ktore juz nie sa potrzebne, dodaje nowe (jezeli nie przekroczy ich maksymalnej liczby) */
167  class StructPartManager : boost::noncopyable {
168  public:
169  StructPartManager(unsigned int max_foldings) : max_foldings_(max_foldings) { }
170 
171  StructPartIter begin() { return structures_.begin(); }
172  StructPartIter end() { return structures_.end(); }
173 
174  unsigned int size() const { return structures_.size(); }
175 
176  /** modyfikuje wybrana strukture lub dodaje nowa (jezeli jest wiele do niej odwolan) */
177  StructPartIter addPair(StructPartIter iter, const ConnectPair& pair ) {
178  SecStructCount new_struct(iter->get());
179  new_struct.addPair(pair);
180  remove(iter);
181  return insert(new_struct);
182  }
183 
184  /** dodaje nowa strukture (jezeli istniala - to zwieksza licznik, jezeli za duzo struktur - to nie dodaje */
185  StructPartIter insert(const SecStructCount& sec_struct_count) {
186  StructPartIter new_iter = structures_.find(sec_struct_count);
187  if(new_iter != structures_.end() )
188  new_iter->inc();
189  else if(structures_.size() < max_foldings_)
190  new_iter = structures_.insert(sec_struct_count).first;
191  return new_iter;
192  }
193  /** zmniejsza licznik (a jezeli trzeba to usuwa strukture */
194  void remove(StructPartIter iter) {
195  if(! iter->dec() )
196  structures_.erase(iter);
197  }
198  private:
199  SecStructParts structures_;
200  unsigned int max_foldings_;
201  };
202 
203  //kolekcja iteratorow bedzie uporzadkowana nie dla iteratorow a dla wartosci
204  struct SecStructIterLessFunctor {
205  bool operator()(const StructPartIter& itA, const StructPartIter& itB) const {
206  return itA->get() < itB->get();
207  }
208  };
209 
210 
211 
212  /** set of partly calculated secondary structures (iterators to sec structures, not full objects)
213  */
214  struct StructPartCollection : public std::set<StructPartIter,SecStructIterLessFunctor> {
215  public:
216  //zwieksza licznik dla kazdej przechowywanej struktury drugorzedowej
217  void incPartsCount() {
218  std::for_each( begin(), end(), boost::bind( &SecStructCount::inc, boost::bind(&StructPartIter::operator*,_1) ) );
219  }
220 
221  //zmniejsza licznik dla kazdej przechowywanej struktury drugorzedowej
222  void decPartsCount() {
223  std::for_each( begin(), end(), boost::bind( &SecStructCount::dec, boost::bind(&StructPartIter::operator*,_1) ) );
224  }
225 
226  //add single partly calculated secondary structure.
227  //if containter has already this structure the counter is decreased
228  //(because this structure is collected twice)
229  void joinOne(const StructPartIter& sec_struct) {
230  StructPartCollection::iterator found = find(sec_struct);
231  if(found != end() )
232  (*found)->dec();
233  else
234  insert(sec_struct);
235  }
236 
237  //adds sec structs from object and the argument
238  void join(const StructPartCollection& collection) {
239  std::for_each(collection.begin(), collection.end(), boost::bind(&StructPartCollection::joinOne, this, _1) );
240  }
241 
242  //creates new second structure (append pair into sec_struct by manager)
243  //inserts it into collection only if the manager adds new iterator (the number of sec structs not
244  //exceeded the max_foldings parameter in manager
245  bool addNewSecStruct(const StructPartIter& sec_struct, const ConnectPair& pair,
246  StructPartManager& manager) {
247  StructPartIter new_iter = manager.addPair(sec_struct, pair);
248  if(new_iter == manager.end())
249  return false;
250  insert(new_iter);
251  return true;
252  }
253 
254  //append the connect pair to all partly calculated second structures stored in collection
255  //the new colection with connected pair is returned by reference to argument (new_collection argument)
256  //returns 'true' if succeed (i.e. number of sec structures not exceed the 'max_foldings'
257  bool addPair(const ConnectPair& pair,
258  StructPartManager& manager, StructPartCollection& new_collection) const {
259 
260  for(StructPartCollection::const_iterator it = begin(); it != end(); ++it )
261  if(!new_collection.addNewSecStruct(*it, pair, manager) )
262  return false;
263  return true;
264  }
265 
266  };
267 
268  /** stream operator for debugging */
269  inline std::ostream& operator<<(std::ostream& os, const StructPartCollection& collection) {
270  std::transform(collection.begin(), collection.end(),
271  std::ostream_iterator<SecStructCount>(os,""),
272  boost::bind(&StructPartIter::operator*,_1) );
273  return os;
274  }
275 
276  /** the point of analyze in secondary structure search */
277  struct ActivePoint : public std::pair<int,int> {
278 
279  explicit ActivePoint(int x, int y) : std::pair<int,int>(x,y) {}
280 
281  //pary sa uporzadkowane w kolejnosci przegladania, tzn. (0,15) < (0,14) < (1,16)
282  bool operator<(const ActivePoint& p) {
283  if(first != p.first)
284  return first < p.first;
285  return p.second < second;
286  }
287  };
288 
289  //funkcja pomocnicza - operator strumieniowy
290  std::ostream& operator<<(std::ostream& os, const ActivePoint& p) {
291  os << '(' << p.first << ',' << p.second << ')';
292  return os;
293  }
294 
295  /** the point or set of points (if brancing) in secondary structure search.
296  It contain connection to partly calculated secondary structures.
297  */
298  class FoldActivePoints {
299  public:
300  //tworzy poczatkowy stan
301  explicit FoldActivePoints(const ActivePoint& start, const StructPartIter start_struct_iter) {
302  addActivePoint(start);
303  folded_parts_.insert(start_struct_iter);
304  }
305  //tworzy kolejny stan (kopia)
306  FoldActivePoints(const FoldActivePoints& bef)
307  : active_points_(bef.active_points_), folded_parts_(bef.folded_parts_) {}
308 
309  ~FoldActivePoints() { }
310  bool operator==(const FoldActivePoints& p) const { return active_points_ == p.active_points_; }
311  bool operator<(const FoldActivePoints& p) const { return active_points_ < p.active_points_; }
312 
313  //czy ma jeszcze punkty aktywne
314  bool hasActivePoint() const { return !active_points_.empty(); }
315 
316  //pobiera pierwszy punkt aktywny (usuwa go z kolekcji)
317  ActivePoint getFirstActivePoint() {
318  assert( !active_points_.empty() );
319  ActivePoint out = *(active_points_.begin());
320  active_points_.erase( active_points_.begin() );
321  return out;
322  }
323 
324  //dodaje nowy punkt do analizy
325  void addActivePoint(const ActivePoint& active_point) { active_points_.insert(active_point); }
326 
327  //laczy przechowywane struktury drugorzedowe
328  void join(const FoldActivePoints& f) const { folded_parts_.join( f.folded_parts_ ); }
329 
330  //dodaje pare do czesciowo obliczonych struktur
331  //zwraca true, jezeli udalo sie dodac (tzn. nie przekroczono liczby struktur)
332  bool addPair(const ConnectPair& pair, StructPartManager& manager) {
333  StructPartCollection new_folded_parts_;
334  bool out = folded_parts_.addPair(pair, manager, new_folded_parts_ );
335  swap( folded_parts_, new_folded_parts_ );
336  return out;
337  }
338 
339  /** accessor and mutator (dangerous) */
340  StructPartCollection& getFoldedParts() { return folded_parts_; }
341 
342  /** accessor */
343  const StructPartCollection& getFoldedParts() const { return folded_parts_; }
344 
345  //do debuggowania
346  friend std::ostream& operator<<(std::ostream& os, const FoldActivePoints& state);
347  private:
348  //punkty analizy (moze ich byc wiele - przy skokach)
349  std::set<ActivePoint> active_points_;
350  //czesciowo obliczone struktury drugorzedowe dla danego zbioru punktow aktywnych
351  mutable StructPartCollection folded_parts_;
352  };
353 
354  //for debugging
355  inline std::ostream& operator<<(std::ostream& os, const FoldActivePoints& state) {
356  os << "points: ";
357  std::copy(state.active_points_.begin(), state.active_points_.end(), std::ostream_iterator<ActivePoint>(os,"") );
358  os << std::endl << "structs: " << state.getFoldedParts() << std::endl;
359  return os;
360  }
361 
362  /** rozatrywane zbiory punktow, ktore tworza struktury drugorzedowe */
363  class States {
364  public:
365  typedef std::set<FoldActivePoints> StatesColection;
366 
367  bool empty() const { return states_.empty(); }
368 
369  unsigned int size() const { return states_.size(); }
370 
371  //pobiera nastepny stan do rozpatrzenia (w odpowiedniej kolejnosci!).
372  //Usuwa go z kolekcji. Kolekcja nie moze byc pusta.
373  FoldActivePoints getFirstState() {
374  assert( !states_.empty() );
375  FoldActivePoints out = *(states_.begin());
376  states_.erase( states_.begin() );
377  return out;
378  }
379 
380  //dodaje nowy stan
381  void addState(const FoldActivePoints& new_state) {
382  addOrJoin(new_state);
383  }
384 
385  //dodaje stan dla left lub up lub diag
386  void addStateMove(const FoldActivePoints& state,
387  const ActivePoint& new_point) {
388  FoldActivePoints new_state(state);
389  new_state.addActivePoint(new_point);
390  addOrJoin(new_state);
391  }
392  void addStateJump(const FoldActivePoints& state,
393  const ActivePoint& point_jump1,
394  const ActivePoint& point_jump2) {
395  FoldActivePoints new_state(state);
396  new_state.addActivePoint(point_jump1);
397  new_state.addActivePoint(point_jump2);
398  addOrJoin(new_state);
399  }
400  private:
401  StatesColection states_;
402 
403  //dodaje nowy stan do kolekcji stanow. Jezeli taki stan juz istnial - to laczy odowiednie struktury
404  void addOrJoin(const FoldActivePoints& new_state) {
405  StatesColection::iterator found = states_.find(new_state);
406  if(found != states_.end() )
407  found->join(new_state);
408  else
409  states_.insert(new_state);
410  }
411  };
412 
413  } //namespace
414 
415  //klasa, ktora przechowuje struktury drugorzedowe dla danego lancucha
416  class SecStructProxy : boost::noncopyable {
417  public:
418  SecStructProxy( const Matrix& matrix, const FoldedMatrixStrategy& strategy, int max_foldings )
419  : matrix_(matrix), strategy_(strategy)
420  {
421  StructPartManager sec_struct_manager(max_foldings);
422  SecStruct sec_struct_empty;
423  SecStructCount start_sec_struct(sec_struct_empty);
424  StructPartIter start_struct_iter = sec_struct_manager.insert(start_sec_struct);
425  ActivePoint start_point(0, strategy_.getLength() - 1);
426  States states;
427  states.addState( FoldActivePoints(start_point, start_struct_iter) );
428  find( states, sec_struct_manager );
429 
430  //kopiuje wyniki
431  std::transform( sec_struct_manager.begin(), sec_struct_manager.end(),
432  std::inserter( possible_structures_, possible_structures_.begin() ),
433  bind(&SecStructCount::get, _1) );
434  }
435 
436  const SecStructures& getStructures() const { return possible_structures_; }
437 
438  std::ostream& printStructures(std::ostream& os, int print_width) const;
439  private:
440  const Matrix& matrix_;
441  const FoldedMatrixStrategy& strategy_;
442 
443  SecStructures possible_structures_;
444 
445  //przeszukuje macierz, znajduje struktury drugorzedowe
446  void find(States& states, StructPartManager& sec_struct_manager) const;
447  };
448 
449  inline FoldedMatrix::FoldedMatrix(const FoldedMatrixStrategy& strategy, unsigned int max_foldings )
450  : strategy_(strategy), max_foldings_(max_foldings), matrix_(strategy_.getLength() ), proxy_(0L)
451  {
452  makeMatrix();
453  structure_energy_ = matrix_.get(0,matrix_.getLength()-1 );
454  }
455 
457  if( proxy_.get() == 0L )
458  proxy_.reset( new SecStructProxy(matrix_, strategy_, max_foldings_) );
459  return proxy_->getStructures();
460  }
461 
462  inline std::ostream& FoldedMatrix::printStructures(std::ostream& os, int print_width) const {
463  if(proxy_.get() != 0L )
464  proxy_->printStructures(os,print_width);
465  else
466  os << "sec struct not calculated" << std::endl;
467  return os;
468  }
469 
470  namespace {
471  /** support function to find maximum value for given call in dynamic programming algorithms */
472  inline int findMaxVal(const Matrix& matrix,
473  const FoldedMatrixStrategy& strategy,
474  int i, int j) {
475  int left=matrix.get(i,j-1);
476  int down=matrix.get(i+1,j);
477  int downleft= matrix.get(i+1,j-1) + strategy.getEnergy(i,j);
478  return (std::max)( (std::max)(left, down), downleft );
479  }
480 
481  }
482 
483  //tworzy macierz energii dla jednego lancucha
484  inline void FoldedMatrix::makeMatrix() {
485 
486  int length = matrix_.getLength();
487  int split_point = strategy_.getSplitIndex(); //first index belonging to the second chain
488  int n; //odleglosc (i,j)
489 
490  //wypelnia macierz w okolicy podzialu dwu czasteczek (split point)
491  for(n = 1; n < 4 && n < length; ++n) {
492  int i = (std::max)( split_point - n, 0);
493  int j = i + n;
494  for(;(i < split_point) && (i < length-1) && (j < length); ++i,++j) {
495  int max_v = findMaxVal( matrix_, strategy_, i, j);
496  matrix_.set(i,j,max_v);
497  }
498  }
499 
500  //wypelnia dla pozostalych
501  for(n=4; n<length; ++n){
502  int i=0;
503  int j=n;
504  for( ;(i < length-1) && ( j<length );++i, ++j) {
505  int max_val = findMaxVal( matrix_, strategy_, i, j);
506 
507  for(int k=0; k<j-i; ++k) {
508  int loopval = matrix_.get(i,i+k)+matrix_.get(k+i+1,j);
509  if( loopval > max_val)
510  max_val = loopval;
511  }
512  matrix_.set(i,j,max_val);
513  }
514  }
515  }
516 
517  //drukuje macierz na wskazany strumien
518  inline std::ostream& FoldedMatrix::printMatrix(std::ostream& os, int print_width) const {
519  for(int i=0;i < strategy_.getLength();++i) {
520  os.width(print_width);
521  os <<i;
522  }
523  os.width(7);
524  os << "j/"<< std::endl;
525  os.width(print_width);
526  for(int i=0;i < strategy_.getLength();++i){
527  os.width(print_width);
528  os <<*strategy_.getNucleotide(i);
529  }
530  os.width(7);
531  os << "i"<< std::endl;
532  {
533  int i = 0;
534  for(;i < strategy_.getSplitIndex();++i){
535  os.width(print_width);
536  os.fill('-');
537  os <<"-";
538  }
539  os << '+';
540  for(;i < strategy_.getLength(); ++i) {
541  os.width(print_width);
542  os.fill('-');
543  os <<"-";
544  }
545  }
546  os.fill(' ');
547  os << std::endl;
548  for(int i=0;i<strategy_.getLength();++i) {
549  for(int j=0;j<strategy_.getLength();++j){
550  os.width(print_width);
551  if(j>=i)
552  os << matrix_.get(i,j);
553  else
554  os << ".";
555  }
556  os<<"|";
557  os.width(2);
558  os<<*strategy_.getNucleotide(i);
559  os.width(4);
560  os<< i << std::endl;
561  }
562  return os;
563  }
564 
565 
566  //drukuje struktury na wskazany strumien
567  inline std::ostream& SecStructProxy::printStructures(std::ostream& os, int print_width) const {
568  os << "sequence length: "<< strategy_.getLength() << std::endl;
569  os <<"found: " << possible_structures_.size() << " structures" << std::endl;
570 
571  for(int i = 0; i < strategy_.getLength(); ++i ) {
572  os.width(print_width);
573  os << *strategy_.getNucleotide(i);
574  }
575  os << std::endl;
576  {
577  int i = 0;
578  for(; i < strategy_.getSplitIndex(); ++i){
579  os.width(print_width);
580  os<<i;
581  }
582  for(; i < strategy_.getLength();++i) {
583  os.width(print_width);
584  os<<i - strategy_.getSplitIndex();
585  }
586  }
587  os << std::endl;
588 
589  std::copy( possible_structures_.begin(), possible_structures_.end(), std::ostream_iterator<SecStruct>(os,"\n") );
590  return os;
591  }
592 
593  /** znajduje pierwsza strukture (przeglada wglab) */
594  inline SecStruct& FoldedMatrix::findDepthRecur(SecStruct& structure, int x, int y) const {
595 
596  EnergyValue current_energy = matrix_.get(x,y);
597 
598  //warunek stopu
599  if(current_energy == 0)
600  return structure;
601 
602  if(current_energy == matrix_.get(x,y-1) )
603  return findDepthRecur( structure, x, y-1 );
604  else if(current_energy == matrix_.get(x+1,y) )
605  return findDepthRecur( structure, x+1, y);
606  else if(current_energy == matrix_.get(x+1,y-1) + strategy_.getEnergy(x,y) ) {
607  //tutaj tworzy curr_point
608  structure.addPair( ConnectPair( strategy_.getNucleotide(x), strategy_.getNucleotide(y) ) );
609  return findDepthRecur( structure, x+1, y-1);
610  }
611  else //znajduje skok
612  for(int k=x; k < y; ++k)
613  if(current_energy == (matrix_.get(x,k)+matrix_.get(k+1,y) ) ) {
614  SecStruct struct_one;
615  findDepthRecur(struct_one, x, k);
616  SecStruct struct_two;
617  findDepthRecur(struct_two, k+1, y);
618  structure.append(struct_one);
619  structure.append(struct_two);
620  return structure;
621  }
622  //tutaj nie powinien sie nigdy znalezc
623  assert(0);
624  return structure;
625  }
626 
627  /** znajduje struktury drugorzedowe na podst. macierzy energii */
628  inline void SecStructProxy::find(States& states, StructPartManager& sec_struct_manager) const
629  {
630  while(!states.empty() ) {
631  // cout << "states:" << states.size() << " sec_structs:" << sec_struct_manager.size() << std::endl;
632  //pobiera nastepny do rozpatrzenia (w odpowiedniej kolejnosci!). Usuwa go z kolekcji.
633  FoldActivePoints state = states.getFirstState();
634  // cout << state;
635 
636  //znajduje aktywny punkt (usuwa go z aktywnych punktow dla danego stanu)
637  ActivePoint curr_point = state.getFirstActivePoint();
638 
639  int x = curr_point.first;
640  int y = curr_point.second;
641 
642  EnergyValue current_energy = matrix_.get(x,y);
643 
644  //warunek stopu
645  if(current_energy == 0) {
646 
647  if( state.hasActivePoint() ) {
648  //dodaje stan z pozostalymi punktami aktywnymi
649  states.addState(state);
650  }
651  //jezeli nie - to nie dodaje (ale tez nie zmniejsza licznikow do struktur, wiec one zostana
652  }
653  else {
654  //tutaj nie stop, czyli trzeba rozpatrywac stany nastepne
655 
656  //struktury przechowywane przez stan biezacy staja sie nieaktywne
657  state.getFoldedParts().decPartsCount();
658 
659 
660  bool left = current_energy == matrix_.get(x,y-1);
661  bool down = current_energy == matrix_.get(x+1,y);
662  bool diag = current_energy == (matrix_.get(x+1,y-1) + strategy_.getEnergy(x,y) );
663 
664  if(left) {
665  // cout << "l";
666  state.getFoldedParts().incPartsCount();
667  states.addStateMove(state, ActivePoint(x, y-1) );
668  }
669  if(down) {
670  // cout << "d";
671  state.getFoldedParts().incPartsCount();
672  states.addStateMove(state, ActivePoint(x+1, y) );
673  }
674  if(diag) {
675  // cout << "x";
676  state.getFoldedParts().incPartsCount();
677  //dodaje pare do czesciowo obliczonych struktur
678  //gdy tworzy nowe struktury to zwraca true, jezeli udalo sie je dodac
679  ConnectPair current_pair( strategy_.getNucleotide(x), strategy_.getNucleotide(y) );
680  if( state.addPair(current_pair, sec_struct_manager) )
681  states.addStateMove(state, ActivePoint(x+1, y-1) );
682  }
683 
684  if(!left && !down && !diag) {
685  //znajduje miejsce w ktorym byla petla
686  for(int k=x; k < y; ++k)
687  if(current_energy == (matrix_.get(x,k)+matrix_.get(k+1,y) ) ) {
688  // cout << "EA jump " << structure << " x = " << x << " y = " << y << " k = " << k << std::endl;
689  state.getFoldedParts().incPartsCount();
690  states.addStateJump(state, ActivePoint(x, k), ActivePoint(k+1, y) );
691  }
692  }
693  }
694  // cout << std::endl << std::endl;
695  }
696  }
697 
698 
699  } //namespace dna
700 } //namespace faif
701 
702 #endif //FOLDED_MATRIX_H
Definition: Chain.h:54
Definition: Chain.h:17
The pair of nucleotides which are join by Watson-Crick interaction.
Definition: SecStruct.h:30
int getEnergy(int index_A, int index_B) const
Definition: FoldedMatrix.h:67
int EnergyValue
Definition: EnergyNucleo.h:15
matrix - 2D array with indexing
Definition: FoldedMatrix.h:31
std::set< SecStruct > SecStructures
Definition: SecStruct.h:104
Definition: FoldedMatrix.h:52
const SecStructures & getStructures()
Definition: FoldedMatrix.h:456
the maps between pair of nucleotides and its energy
Definition: EnergyNucleo.h:37
void append(const SecStruct &s)
Definition: SecStruct.h:79
void addPair(const ConnectPair &p)
Definition: SecStruct.h:76
std::ostream & operator<<(std::ostream &os, const Chain &chain)
Definition: Chain.h:162
SecStruct findInDepth() const
Definition: FoldedMatrix.h:89
Definition: FoldedMatrix.h:416
Definition: FoldedMatrix.h:76
the secondary structure
Definition: SecStruct.h:55