source: branches/lib/SECEDIT/SEC_root.hxx

Last change on this file was 19393, checked in by westram, 2 years ago
  • reintegrates 'ali' into 'trunk'
    • refactored misused enum
    • support for helix pairs:
      • drop non-standard defs
      • add more user defs
    • change defaults
    • add several predefined configs (esp. for IUPAC ambiguity codes)
  • adds: log:branches/ali@19376:19392
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 32.8 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : SEC_root.hxx                                      //
4//   Purpose   : secondary structure representation                //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#ifndef SEC_ROOT_HXX
12#define SEC_ROOT_HXX
13
14#ifndef _GLIBCXX_IOSFWD
15#include <iosfwd>
16#endif
17
18#ifndef AW_FONT_GROUP_HXX
19#include <aw_font_group.hxx>
20#endif
21
22#ifndef SEC_ABSPOS_HXX
23#include "SEC_abspos.hxx"
24#endif
25#ifndef SEC_GC_HXX
26#include "SEC_gc.hxx"
27#endif
28#ifndef SEC_DB_HXX
29#include "SEC_db.hxx"
30#endif
31#ifndef SECEDIT_EXTERN_HXX
32#include "secedit_extern.hxx"
33#endif
34#ifndef BI_HELIX_HXX
35#include <BI_helix.hxx>
36#endif
37#ifndef ARB_GLOBAL_DEFS_H
38#include <arb_global_defs.h>
39#endif
40
41using namespace AW;
42
43#define DATA_VERSION 3
44
45inline bool SEC_is_gap(char c) {
46    return GAP::is_std_gap(c); // @@@ use AWAR defined gap here?
47}
48
49// ------------------
50//      Debugging
51
52#if defined(DEBUG)
53
54#define CHECK_INTEGRITY         // check structure integrity after changes
55#define PAINT_ABSOLUTE_POSITION // paint some positions near center (range = 0..len-1)
56
57#endif // DEBUG
58
59#ifdef CHECK_INTEGRITY
60enum SEC_CHECK_TYPE {
61    CHECK_STRUCTURE = 1,
62    CHECK_SIZE      = 2,
63    CHECK_POSITIONS = 4,
64    CHECK_ALL       = CHECK_STRUCTURE|CHECK_SIZE|CHECK_POSITIONS,
65};
66#endif
67
68// -------------------
69//      SEC_region
70
71class SEC_root;
72
73class SEC_region : virtual Noncopyable {
74private:
75    // non redundant values
76    int sequence_start, sequence_end; // sequence_end is exclusive
77
78    // cached values
79    int baseCount;             // number of real bases (-1 = uninitialized)
80
81    int * abspos_array;
82#if defined(ASSERTION_USED)
83    int   abspos_array_size;
84#endif // ASSERTION_USED
85
86    void create_abspos_array(const int *static_array);
87
88    void set_base_count(int bc) {
89        sec_assert(bc>0);
90        baseCount = bc;
91    }
92
93    void count_bases(SEC_root *root); // updates abspos_array
94
95public:
96    SEC_region(int start, int end);
97    virtual ~SEC_region();
98
99    // methods
100    void save(std::ostream & out, int indent, const XString& x_string);
101    GB_ERROR read(std::istream & in, SEC_root *root, int version);
102
103    void update_base_count(SEC_root *root) { if (baseCount == -1) count_bases(root); }
104    void invalidate_base_count();
105
106    // selector-methods
107    int get_sequence_start() const { return sequence_start; }
108    int get_sequence_end() const { return sequence_end; }
109
110    int get_base_count() const { sec_assert(baseCount != -1); return baseCount; }
111
112    bool contains_seq_position(int pos) const {
113        if (sequence_end<sequence_start) {
114            return pos<sequence_end || sequence_start <= pos;
115        }
116        return sequence_start <= pos && pos < sequence_end;
117    }
118
119    void set_sequence_portion(int start, int end) {
120        sequence_start = start;
121        sequence_end = end;
122        invalidate_base_count();
123    }
124    void generate_x_string(XString& x_string);
125    void align_helix_strands(SEC_root *root, SEC_region *other_region);
126
127    int getBasePos(int basenr) const {
128        // some helix positions do not have an absolute position
129        // in that case getBasePos() returns a neighbour position
130        int pos;
131
132        if (basenr >= 0 && basenr<get_base_count()) {
133            sec_assert(basenr >= 0);
134            sec_assert(abspos_array);
135            sec_assert(basenr<abspos_array_size);
136            pos = abspos_array[basenr];
137        }
138        else { // special case for empty strands
139            sec_assert(get_base_count() == 0);
140            sec_assert(basenr <= 0); // 0 or -1
141
142            pos = (basenr == 0) ? get_sequence_start() : get_sequence_end();
143        }
144        return pos;
145    }
146
147#if defined(CHECK_INTEGRITY)
148    void check_integrity(const SEC_root *root, SEC_CHECK_TYPE what) const;
149#endif // CHECK_INTEGRITY
150};
151
152// -------------------------
153//      SEC_constrainted
154
155class SEC_constrainted {
156    double sSize;               // standard size
157    double dSize;               // constrainted size ( = drawn size)
158    double Min, Max;            // limits for dSize (0 means : do not limitate)
159
160    void refreshDrawnSize() { dSize = (sSize<Min && Min>0) ? Min : ((sSize>Max && Max>0) ? Max : sSize); }
161
162public:
163    SEC_constrainted() : sSize(0), dSize(0), Min(0), Max(0) {}
164
165    double drawnSize() const { return dSize; } // constrainted size
166    double standardSize() const { return sSize; } // // unconstrainted size
167
168    double minSize() const { return Min; } // constraints
169    double maxSize() const { return Max; }
170
171    void setDrawnSize(double size) { // calculate constraints as needed
172        if (sSize < size) {
173            Min = size;
174            if (Min>Max) Max = 0;
175            refreshDrawnSize();
176        }
177        else if (sSize > size) {
178            Max = size;
179            if (Max<Min) Min = 0;
180            refreshDrawnSize();
181        }
182
183#if defined(DEBUG) && 0
184        printf("setDrawnSize(%.2f) -> sSize=%.2f dSize=%.2f Min=%.2f Max=%.2f\n", size, sSize, dSize, Min, Max);
185#endif // DEBUG
186    }
187
188    void setStandardSize(double size) { // set standard size (calculated from base counts)
189        sSize = size;
190        refreshDrawnSize();
191    }
192
193    void setConstraints(double low, double high) {
194        Min = low;
195        Max = high;
196        refreshDrawnSize();
197    }
198};
199
200// ---------------------
201//      SEC_oriented
202
203class SEC_base;
204
205class SEC_oriented {
206    Angle rel_angle;
207
208    mutable Angle abs_angle;
209    mutable bool  abs_angle_valid;
210
211    const Angle& calc_abs_angle() const;
212    const Angle& calc_rel_angle();
213
214    virtual SEC_base *get_parent() = 0;
215public:
216    SEC_oriented() : abs_angle_valid(false) {}
217    virtual ~SEC_oriented() {}
218
219    virtual void invalidate_sub_angles() = 0;
220    void invalidate(); // invalidates cached abs_angle of this and substructure
221
222    const Angle& get_abs_angle() const { return abs_angle_valid ? abs_angle : calc_abs_angle(); }
223    const Angle& get_rel_angle() const { return rel_angle; }
224
225    void set_rel_angle(const Angle& rel) {
226        rel_angle = rel;
227        abs_angle_valid = false;
228        invalidate_sub_angles();
229    }
230    void set_abs_angle(const Angle& abs) {
231        if (abs_angle_valid) {
232            Angle diff  = abs-get_abs_angle();
233            sec_assert(rel_angle.normal().is_normalized());
234            rel_angle  += diff;
235            abs_angle   = abs;
236        }
237        else {
238            abs_angle = abs;
239            calc_rel_angle();
240        }
241        invalidate_sub_angles();
242    }
243
244    void set_rel_angle(const double& rel) { set_rel_angle(Angle(rel)); }
245    void set_abs_angle(const double& abs) { set_abs_angle(Angle(abs)); }
246
247    void mark_angle_absolute() { abs_angle = rel_angle; abs_angle_valid = true; } // used for root-loop (rel == abs!!)
248
249    SEC_base *parent() { return get_parent(); }
250    const SEC_base *parent() const { return const_cast<SEC_oriented*>(this)->get_parent(); }
251};
252
253
254// ----------------------
255//      SEC_BASE_TYPE
256
257enum SEC_BASE_TYPE {
258    SEC_NO_TYPE  = 0,
259    SEC_LOOP     = 1,
260    SEC_HELIX    = 2,
261    SEC_ANY_TYPE = SEC_LOOP|SEC_HELIX,
262};
263
264// -----------------
265//      SEC_base
266
267class SEC_base : public SEC_constrainted, public SEC_oriented, virtual Noncopyable { // loop or helix
268    SEC_root *root;
269
270    SEC_base *get_parent() OVERRIDE = 0;
271public:
272    SEC_base(SEC_root *Root) : root(Root) {}
273    ~SEC_base() OVERRIDE {}
274
275    virtual SEC_BASE_TYPE getType() const        = 0;
276    virtual const Position& get_fixpoint() const = 0;
277    virtual void reset_angles()                  = 0; // resets all strand-loop angles (of substructure)
278
279    virtual void orientationChanged() = 0; // recalc coordinates
280    virtual void sizeChanged() = 0; // recalc size and coordinates
281
282    AW_CL self() const { return (AW_CL)this; }
283    SEC_root *get_root() const { return root; }
284};
285
286class SEC_base_part : virtual Noncopyable { // segment or strand
287    SEC_region region;
288
289    virtual SEC_base *get_parent()    = 0;
290    virtual SEC_base_part *get_next() = 0;
291public:
292    SEC_base_part() : region(-1, -1) {}
293    virtual ~SEC_base_part() {}
294
295    SEC_base *parent() { return get_parent(); }
296    const SEC_base *parent() const { return const_cast<SEC_base_part*>(this)->get_parent(); }
297
298    AW_CL self() const { return parent()->self(); }
299    SEC_root *get_root() const { return parent()->get_root(); }
300
301    SEC_base_part *next() { return get_next(); } // iterates through whole structure
302    const SEC_base_part *next() const { return const_cast<SEC_base_part*>(this)->get_next(); }
303
304    const SEC_region *get_region() const { return &region; }
305    SEC_region *get_region() { return &region; }
306
307    void set_sequence_portion(int start, int end) { get_region()->set_sequence_portion(start, end); }
308    size_t getNextAbspos() const;
309};
310
311
312// ------------------
313//      SEC_helix
314
315class SEC_helix_strand;
316class SEC_loop;
317
318class SEC_helix FINAL_TYPE : public SEC_base { // derived from a Noncopyable
319
320    SEC_helix_strand *strand_to_root;
321    size_t base_length; // max. # of bases in any strand
322
323    SEC_base *get_parent() OVERRIDE;
324public:
325
326    SEC_helix(SEC_root *root, SEC_helix_strand *to_root, SEC_helix_strand *from_root);
327    ~SEC_helix() OVERRIDE {}
328
329    void calculate_helix_size();
330    void calculate_helix_coordinates(); // assumes root-side loop has correct coordinates
331
332    void save(std::ostream & out, int indent, const XString& x_string);
333    GB_ERROR read(std::istream & in, int version, double& old_angle_in);
334
335    size_t get_base_length()            { return base_length; }
336
337    SEC_helix_strand *strandToRoot() const { return strand_to_root; } // strand pointing to root
338    SEC_helix_strand *strandToOutside() const; // strand pointing away from root
339
340    SEC_helix_strand *strandAwayFrom(const SEC_loop *loop) const; // strand pointing away from loop
341    SEC_helix_strand *strandTowards(const SEC_loop *loop) const; // strand pointing to loop
342
343    SEC_loop *otherLoop(const SEC_loop *loop) const; // returns the other loop
344    SEC_loop *rootsideLoop() const;
345    SEC_loop *outsideLoop() const;
346
347    bool hasLoop(SEC_loop *loop) const { return loop == rootsideLoop() || loop == outsideLoop(); }
348
349    void setFixpoints(const Position& rootside, const Position& outside);
350
351    void flip();
352
353    void fixAngleBugs(int version);
354
355#if defined(CHECK_INTEGRITY)
356    void check_integrity(SEC_CHECK_TYPE what) const;
357#endif // CHECK_INTEGRITY
358
359    // SEC_oriented interface:
360    void invalidate_sub_angles() OVERRIDE;
361
362    // SEC_base interface :
363    SEC_BASE_TYPE getType() const OVERRIDE { return SEC_HELIX; }
364    void reset_angles() OVERRIDE;
365    const Position& get_fixpoint() const OVERRIDE;
366
367    void orientationChanged() OVERRIDE; // recalc coordinates
368    void sizeChanged() OVERRIDE; // recalc size and coordinates
369};
370
371// -------------------------
372//      SEC_helix_strand
373
374class SEC_segment;
375
376class SEC_helix_strand FINAL_TYPE : public SEC_base_part { // derived from a Noncopyable
377    friend class SEC_helix;
378
379    SEC_loop         *origin_loop;     // Pointer to loop where strand comes from
380    SEC_helix_strand *other_strand;
381    SEC_helix        *helix_info; // used by both strands
382    SEC_segment      *next_segment; // next segment in origin_loop
383
384    // redundant values
385
386    Position fixpoint;
387    Position rightAttach, leftAttach; // rightAttach was ap1, leftAttach was ap2
388
389    void set_helix_info(SEC_helix *helix_info_)            { helix_info = helix_info_; }
390    void set_other_strand(SEC_helix_strand *other_strand_) { other_strand = other_strand_; }
391
392    // SEC_base_part interface
393    SEC_base *get_parent()  OVERRIDE { return helix_info; }
394    SEC_base_part *get_next() OVERRIDE;
395
396public:
397
398    SEC_helix_strand();
399    ~SEC_helix_strand() OVERRIDE;
400
401    GB_ERROR read(SEC_loop *loop_, std::istream & in, int version);
402
403    void paint(AW_device *device);
404    void unlink(bool fromOtherStrandAsWell);
405
406    void paint_strands(AW_device *device, const Vector& strand_dir, const double& strand_length);
407    void paint_constraints(AW_device *device);
408
409    const SEC_root *get_root() const { return helix_info->get_root(); }
410    SEC_root *get_root() { return helix_info->get_root(); }
411
412    const SEC_helix *get_helix() const { return helix_info; }
413    SEC_helix *get_helix() { return helix_info; }
414
415    const SEC_helix_strand *get_other_strand() const { return other_strand; }
416    SEC_helix_strand *get_other_strand() { return other_strand; }
417
418    // fix- and attach points
419
420    const Position& get_fixpoint() const { return fixpoint; }
421    bool isRootsideFixpoint() const { return helix_info->strandToOutside() == this; }
422
423    bool pointsToRoot() const { return !isRootsideFixpoint(); }
424    bool pointsToOutside() const { return isRootsideFixpoint(); }
425
426    bool is3end() const { return get_region()->get_sequence_start() > other_strand->get_region()->get_sequence_start(); }
427
428    // Attach point (left/right when looking towards the strand from its origin loop)
429    const Position& rightAttachPoint() const { return rightAttach; }
430    const Position& leftAttachPoint() const { return leftAttach; }
431
432    const Position& startAttachPoint() const { return leftAttach; }
433    const Position& endAttachPoint() const { return other_strand->rightAttach; }
434
435    int rightAttachAbspos() const {
436        const SEC_region *reg   = get_other_strand()->get_region();
437        int               count = reg->get_base_count();
438
439        return reg->getBasePos(count ? count-1 : 0);
440    }
441    int leftAttachAbspos() const { return get_region()->getBasePos(0); }
442
443    int startAttachAbspos() const { return leftAttachAbspos(); }
444    int endAttachAbspos() const { return other_strand->rightAttachAbspos(); }
445
446    void setFixpoint(const Position& p) { fixpoint = p; }
447    void setAttachPoints(const Position& left, const Position& right) { rightAttach = right; leftAttach = left; }
448
449    // iterator methods
450
451    const SEC_segment *get_next_segment() const { return next_segment; }
452    SEC_segment *get_next_segment() { return next_segment; }
453    SEC_segment * get_previous_segment(); // expensive!
454
455    const SEC_loop *get_origin_loop() const { return origin_loop; }
456    SEC_loop *get_origin_loop() { return origin_loop; }
457    SEC_loop *get_destination_loop() { return get_other_strand()->get_origin_loop(); }
458
459    SEC_loop *get_rootside_loop() { return isRootsideFixpoint() ? get_origin_loop() : get_destination_loop(); }
460
461    void set_origin_loop(SEC_loop *loop_)                       { origin_loop = loop_; }
462    void set_next_segment(SEC_segment *next_segment_)           { next_segment=next_segment_; }
463
464#if defined(CHECK_INTEGRITY)
465    void check_integrity(SEC_CHECK_TYPE what) const;
466#endif // CHECK_INTEGRITY
467};
468
469
470// --------------------
471//      SEC_segment
472
473class SEC_segment FINAL_TYPE : public SEC_base_part { // derived from a Noncopyable
474private:
475    double   alpha;             // angle of segment (i.e. how much of the loop is used by this segment)
476    Position center1, center2; // segments are not circles, they are ellipsoids
477    // center1 is used for rightAttach (of previous helix)
478    // center2 is used for leftAttach (of next helix)
479
480    SEC_helix_strand *next_helix_strand; // next helix strand after segment (pointing away from segments loop)
481    SEC_loop *loop; // the loop containing 'this'
482
483    // SEC_base_part interface
484    SEC_base *get_parent() OVERRIDE;
485    SEC_base_part *get_next() OVERRIDE { return get_next_strand(); }
486
487public:
488
489    SEC_segment();
490    ~SEC_segment() OVERRIDE;
491
492    void save(std::ostream & out, int indent, const XString& x_string);
493    GB_ERROR read(SEC_loop *loop_, std::istream & in, int version);
494
495    void calculate_segment_size();
496    void calculate_segment_coordinates(const Position& start, const Position& end);
497
498    void paint(AW_device *device, SEC_helix_strand *previous_strand_pointer);
499    void unlink();
500
501    void prepare_paint(SEC_helix_strand *previous_strand_pointer, double &gamma, double &eta, double &radius, int &base_count, double &angle_step);
502
503    void mergeWith(SEC_segment *other, SEC_loop *target_loop);
504    SEC_helix_strand *split(size_t start, size_t end, SEC_segment **new_segment);
505
506
507    int is_endings_segment() {
508        int seq_start = get_region()->get_sequence_start();
509        int seq_end = get_region()->get_sequence_end();
510
511        return seq_start>seq_end;
512    }
513
514    void delete_pointer_2(SEC_helix_strand *strand) {
515        SEC_segment *segment = this;
516        while (1) {
517            SEC_helix_strand *next_strand = segment->next_helix_strand;
518
519            if (!next_strand) break;
520            if (next_strand == strand) { segment->next_helix_strand = NULp; break; }
521
522            segment = next_strand->get_next_segment();
523            if (!segment || segment==this) {
524#if defined(DEBUG)
525                printf("SEC_segment %p did not contain pointer to SEC_helix_strand %p\n", this, strand);
526#endif // DEBUG
527                break;
528            }
529        }
530    }
531
532    SEC_helix_strand *get_previous_strand();
533
534    const SEC_helix_strand *get_next_strand() const { return next_helix_strand; }
535    SEC_helix_strand *get_next_strand() { return next_helix_strand; }
536
537    const SEC_loop *get_loop() const { return loop; }
538    SEC_loop *get_loop() { return loop; }
539
540    double get_alpha() { return alpha; }
541
542    void set_next_strand(SEC_helix_strand *strand) { next_helix_strand = strand; }
543    void set_loop(SEC_loop *loop_) { loop = loop_; }
544
545#if defined(CHECK_INTEGRITY)
546    void check_integrity(SEC_CHECK_TYPE what) const;
547#endif // CHECK_INTEGRITY
548};
549
550// -----------------
551//      SEC_loop
552
553class SEC_loop FINAL_TYPE : public SEC_base { // derived from a Noncopyable
554    double   Circumference;     // unit is in "segment-base-distances"
555    Position center;            // center point of loop
556    SEC_helix_strand *primary_strand; // primary strand of loop
557    // loop orientation points towards that strand
558    // for non-root-loops, this strand points towards root
559
560    void compute_circumference();
561    void compute_radius();
562
563    SEC_base *get_parent() OVERRIDE { return is_root_loop() ? NULp : get_rootside_helix(); }
564
565public:
566
567    SEC_loop(SEC_root *root_);
568    ~SEC_loop() OVERRIDE;
569
570    void save(std::ostream & out, int indent, const XString& x_string);
571    GB_ERROR read(SEC_helix_strand *rootside_strand, std::istream & in, int version, double loop_angle);
572
573    void calculate_loop_size();
574    void calculate_loop_coordinates();
575
576    void paint(AW_device *device);
577    void paint_constraints(AW_device *device);
578
579    const Position& get_center() const { return center; }
580    const double& get_circumference() const { return Circumference; }
581
582    bool is_root_loop() const;
583
584    SEC_helix_strand *get_rootside_strand() const { return is_root_loop() ? NULp : primary_strand; }
585    SEC_helix *get_rootside_helix() const { return is_root_loop() ? NULp : primary_strand->get_helix(); }
586    SEC_helix_strand *get_fixpoint_strand() const { return primary_strand; }
587    SEC_helix *get_fixpoint_helix() const { return primary_strand->get_helix(); }
588
589    void set_fixpoint_strand(SEC_helix_strand *strand) { primary_strand = strand; }
590
591    void toggle_root(SEC_loop *root_loop);
592
593    void set_center(const Position& p) { center = p; }
594
595    void fixAngleBugs(int version);
596
597#if defined(CHECK_INTEGRITY)
598    void check_integrity(SEC_CHECK_TYPE what) const;
599#endif // CHECK_INTEGRITY
600
601    // SEC_oriented interface:
602    void invalidate_sub_angles() OVERRIDE;
603
604    // SEC_base interface :
605    SEC_BASE_TYPE getType() const OVERRIDE { return SEC_LOOP; }
606    void reset_angles() OVERRIDE;
607
608    const Position& get_fixpoint() const OVERRIDE {
609        // Note: does not return center for root-loop.
610        SEC_helix *helix = get_fixpoint_helix();
611        return helix->strandAwayFrom(this)->get_fixpoint();
612    }
613
614    void orientationChanged() OVERRIDE;  // recalc coordinates
615    void sizeChanged() OVERRIDE; // recalc size and coordinates
616};
617
618// --------------------------
619//      SEC_displayParams
620
621enum ShowBonds {
622    SHOW_NO_BONDS     = 0,
623    SHOW_HELIX_BONDS  = 1,
624    SHOW_NHELIX_BONDS = 2,
625};
626
627enum ShowCursorPos {
628    SHOW_NO_CURPOS    = 0,
629    SHOW_ABS_CURPOS   = 1,
630    SHOW_ECOLI_CURPOS = 2,
631    SHOW_BASE_CURPOS  = 3,
632};
633
634struct SEC_displayParams {
635    bool   show_helixNrs;       // display helix number information?
636    double distance_between_strands; // distance between strands (1.0 => strand distance == normal distance of bases in loop)
637
638    ShowBonds show_bonds;       // which bonds to show
639    short     bond_thickness;   // linewidth for bonds
640
641    bool hide_bases;            // hide bases?
642
643    ShowCursorPos show_curpos;  // which position to show at cursor
644    bool          show_ecoli_pos; // show ecoli positions?
645
646    bool display_search;        // show search results
647    bool display_sai;           // visualize SAIs
648
649    bool  show_strSkeleton;     // display the skeleton?
650    short skeleton_thickness;
651
652    bool edit_rightward;        // true = 5'->3', false = 5'<-3'
653
654#if defined(DEBUG)
655    bool show_debug;            // show debug info in structure display
656#endif // DEBUG
657
658    SEC_displayParams() { memset(this, 0, sizeof(*this)); }
659
660    void reread(AW_root *aw_root, const ED4_plugin_host& host);
661};
662
663
664// -----------------
665//      SEC_root
666
667class AWT_canvas;
668class SEC_drawn_positions;
669class SEC_db_interface;
670class SEC_graphic;
671
672enum SEC_bgpaint_mode {
673    BG_PAINT_NONE   = 0,
674    BG_PAINT_FIRST  = 1,
675    BG_PAINT_SECOND = 2,
676    BG_PAINT_BOTH   = BG_PAINT_FIRST | BG_PAINT_SECOND,
677};
678
679class SEC_root : virtual Noncopyable {
680    SEC_loop *root_loop;
681    int       cursorAbsPos;     // cursor position (-1 == unset)
682    XString  *xString;
683
684    bool constructing; // whether structure is under construction or a complete ring-structure
685
686    SEC_displayParams  displayParams;
687    SEC_db_interface  *db;
688
689    // -----------------------------
690    //      updated before paint
691
692    AW_font_group font_group;
693
694    double charRadius[SEC_GC_DATA_COUNT];  // radius and..
695    short  bg_linewidth[SEC_GC_DATA_COUNT]; // ..linewidth for drawing background (index = gc)
696    Vector center_char[SEC_GC_FONT_COUNT]; // correction vector to center the base character at its position (world coordinates)
697
698    // see SEC_paint.cxx@LINE_THICKNESS
699    double skelThickWorld; // skeleton_thickness as world-size
700    double bondThickWorld; // bond_thickness as world-size
701
702    char *bg_color;       // only valid after paint (contains EDIT4 GCs), may be NULp
703
704    Vector   *autoscroll;       // if non-zero, scroll canvas before next paint
705    int       nailedAbsPos;     // if not -1, auto-scroll such that position does not move
706    Position  drawnAbsPos;      // position where nailedAbsPos was drawn before
707
708    // --------------------------
709    //      valid after paint
710
711    SEC_drawn_positions *drawnPositions; // after paint this contains draw positions for every absolute position
712    LineVector           cursor_line; // main line of the cursor
713
714    SEC_BASE_TYPE show_constraints;
715
716
717    void paintHelixNumbers(AW_device *device);
718    void paintEcoliPositions(AW_device *device);
719#if defined(PAINT_ABSOLUTE_POSITION)
720    void showSomeAbsolutePositions(AW_device *device);
721#endif
722    void fixStructureBugs(int version);
723
724    void cacheBackgroundColor();
725
726    static bool hasBase(int pos, const char *seq, int len) {
727        sec_assert(pos<len);
728        if (pos<len) {
729            return !SEC_is_gap(seq[pos]);
730        }
731        return false;
732    }
733
734    void delete_root_loop() { SEC_loop *old_root_loop = root_loop; root_loop = NULp; delete old_root_loop; }
735    void delete_announced_positions();
736
737public:
738
739    SEC_root();
740    ~SEC_root();
741
742    void init(SEC_graphic *gfx, AWT_canvas *scr, ED4_plugin_host& host);
743
744    bool under_construction() const { return constructing; }
745    void set_under_construction(bool construct) { constructing = construct; }
746
747    const SEC_db_interface *get_db() const { return db; }
748    const ED4_plugin_host& host() const { return db->host(); }
749    bool canDisplay() const { return db && db->canDisplay(); }
750    const BI_helix *get_helixDef() const { sec_assert(db); return db->helix(); }
751    bool is_pairpos(int abspos) const {
752        const BI_helix *h = get_helixDef();
753        return h && h->is_pairpos(abspos);
754    }
755    const char *helixNrAt(int abspos) const { return get_helixDef()->helixNr(abspos); }
756
757    const size_t *getHelixPositions(const char *helixNr) const;
758    const double& get_char_radius(int gc) const { return charRadius[gc]; }
759
760    void reread_display_params(AW_root *aw_root, const ED4_plugin_host& Host) { displayParams.reread(aw_root, Host); }
761    const SEC_displayParams& display_params() const { return displayParams; }
762
763    bool has_xString() const { return xString; }
764    const XString& get_xString() const {
765        sec_assert(xString);
766        return *xString;
767    }
768
769#if defined(CHECK_INTEGRITY)
770    void check_integrity(SEC_CHECK_TYPE what) const;
771#endif // CHECK_INTEGRITY
772
773    // ------------------------------
774
775    void paintBackgroundColor(AW_device *device, SEC_bgpaint_mode mode, const Position& p1, int color1, int gc1, const Position& p2, int color2, int gc2, int skel_gc);
776    void paintSearchPatternStrings(AW_device *device, int clickedPos,  AW_pos xPos,  AW_pos yPos);
777
778    char *buildStructureString();
779    GB_ERROR read_data(const char *input_string, const char *x_string_in);
780
781    void add_autoscroll(const Vector& scroll);
782    void nail_position(size_t absPos); // re-position on absPos
783    void nail_cursor(); // re-position on cursor
784    void position_cursor(bool toCenter, bool evenIfVisible); // scroll/center cursor (screen-only)
785    void set_cursor(int abspos); // sets new cursor position
786
787    bool perform_autoscroll();
788
789private:
790    void calculate_size();
791    void calculate_coordinates();
792public:
793
794#if defined(CHECK_INTEGRITY)
795    void recalc() {                     check_integrity(static_cast<SEC_CHECK_TYPE>(CHECK_STRUCTURE|CHECK_SIZE));
796        calculate_coordinates();        check_integrity(CHECK_POSITIONS);
797    }
798    void relayout() {                   check_integrity(CHECK_STRUCTURE);
799        calculate_size();               check_integrity(CHECK_SIZE);
800        calculate_coordinates();        check_integrity(CHECK_POSITIONS);
801    }
802#else
803    void recalc() {
804        calculate_coordinates();
805    }
806    void relayout() {
807        calculate_size();
808        calculate_coordinates();
809    }
810#endif
811
812    GB_ERROR split_loop(int start1, int end1, int start2, int end2);
813
814    GB_ERROR paint(AW_device *device);
815    GB_ERROR unsplit_loop(SEC_helix_strand *delete_strand);
816    void     set_root(SEC_loop *loop);
817    void     create_default_bone();
818    void     generate_x_string();
819
820    void update_shown_positions();
821    bool shallDisplayPosition(int abspos) const { return db->shallDisplayPosition(abspos); }
822    void invalidate_base_positions(); // force base counts of all regions to be refreshed
823
824    int getBackgroundColor(int abspos) { return bg_color ? bg_color[abspos] : 0; }
825    const Vector& get_center_char_vector(int gc) {
826        sec_assert(gc >= SEC_GC_FIRST_FONT && gc <= SEC_GC_LAST_FONT);
827        return center_char[gc];
828    }
829
830    size_t max_index() {
831        size_t len = db->length();
832        sec_assert(len); // zero len -> no index exists
833        return len-1;
834    }
835
836    int get_cursor() const { return cursorAbsPos; }
837
838    SEC_loop *get_root_loop() const { return root_loop; }
839    void set_root_loop(SEC_loop *loop) { root_loop = loop; }
840
841    SEC_BASE_TYPE get_show_constraints() { return show_constraints; }
842    void set_show_constraints(SEC_BASE_TYPE show) { show_constraints = show; }
843
844    void set_last_drawed_cursor_position(const LineVector& line) { cursor_line = line; }
845    const LineVector& get_last_drawed_cursor_position() const { return cursor_line; }
846    void clear_last_drawed_cursor_position() { set_last_drawed_cursor_position(LineVector()); } // invalidate cursor_line
847
848    SEC_base_part *find(int pos); // find part containing position pos
849
850    void announce_base_position(int base_pos, const Position& draw_pos);
851    void clear_announced_positions();
852
853    const AW_font_group& get_font_group() const { return font_group; }
854
855
856    // draw annotation to explicit coordinates (annotation is drawn "above" line left->right)
857    void paintAnnotation(AW_device *device, int gc,
858                         const Position& annotate, const Position& left, const Position& right,
859                         double noteDistance, const char *text,
860                         bool lineToAnnotated, bool linesToLeftRight, bool boxText);
861
862    // draw a annotation next to a base (only works after paint())
863    void paintPosAnnotation(AW_device *device, int gc, size_t absPos, const char *text, bool lineToBase, bool boxText);
864
865    double get_bondThickWorld() const { return bondThickWorld; }
866};
867
868
869// --------------------------------------------------------------------------------
870// inlines:
871
872inline void SEC_helix::flip() {
873    strand_to_root = strand_to_root->get_other_strand();
874}
875
876inline SEC_helix_strand *SEC_helix::strandToOutside() const { // strand pointing away from root
877    return strandToRoot()->get_other_strand();
878}
879
880inline SEC_helix_strand *SEC_helix::strandAwayFrom(const SEC_loop *loop) const { // strand pointing away from loop
881    if (strandToRoot()->get_origin_loop() == loop) {
882        return strandToRoot();
883    }
884    sec_assert(strandToOutside()->get_origin_loop() == loop);
885    return strandToOutside();
886}
887
888inline SEC_helix_strand *SEC_helix::strandTowards(const SEC_loop *loop) const { // strand pointing to loop
889    return strandAwayFrom(loop)->get_other_strand();
890}
891
892inline SEC_loop *SEC_helix::otherLoop(const SEC_loop *loop) const { // returns loop on other side of strand
893    return strandTowards(loop)->get_origin_loop();
894}
895
896inline SEC_loop *SEC_helix::rootsideLoop() const { return strandToOutside()->get_origin_loop(); }
897inline SEC_loop *SEC_helix::outsideLoop() const { return strandToRoot()->get_origin_loop(); }
898
899inline const Position& SEC_helix::get_fixpoint() const { return strandToOutside()->get_fixpoint(); }
900
901inline void SEC_helix::setFixpoints(const Position& rootside, const Position& outside) {
902    strandToRoot()->setFixpoint(outside);
903    strandToOutside()->setFixpoint(rootside);
904}
905
906inline void SEC_helix::orientationChanged() { // recalc coordinates
907    // we need to recalculate the rootside loop, cause changing the
908    // helix-orientation affects the attached loop segments.
909
910    SEC_loop *loop = rootsideLoop();
911
912    if (loop->is_root_loop()) {
913        // at root-loop do a complete recalc
914        // (fixpoint-strand is not relayouted otherwise)
915        get_root()->recalc();
916    }
917    else {
918#if defined(CHECK_INTEGRITY)
919        loop->check_integrity(CHECK_STRUCTURE);
920        loop->check_integrity(CHECK_SIZE);
921#endif // CHECK_INTEGRITY
922        loop->calculate_loop_coordinates();
923#if defined(CHECK_INTEGRITY)
924        loop->check_integrity(CHECK_POSITIONS);
925#endif // CHECK_INTEGRITY
926    }
927}
928inline void SEC_helix::sizeChanged() { // recalc size and coordinates
929#if defined(CHECK_INTEGRITY)
930    check_integrity(CHECK_STRUCTURE);
931#endif // CHECK_INTEGRITY
932    calculate_helix_size();
933#if defined(CHECK_INTEGRITY)
934    check_integrity(CHECK_SIZE);
935#endif // CHECK_INTEGRITY
936    calculate_helix_coordinates();
937#if defined(CHECK_INTEGRITY)
938    check_integrity(CHECK_POSITIONS);
939#endif // CHECK_INTEGRITY
940}
941
942inline SEC_base *SEC_helix::get_parent() { return rootsideLoop(); }
943
944// --------------------
945
946inline SEC_base_part *SEC_helix_strand::get_next() { return get_other_strand()->get_next_segment(); }
947
948// --------------------
949
950inline bool SEC_loop::is_root_loop() const { return get_root()->get_root_loop() == this; }
951
952inline void SEC_loop::orientationChanged() { // recalc coordinates
953    if (is_root_loop()) {
954        get_root()->recalc();
955    }
956    else {
957        // loop center is calculated by helix, that is why we recalc the helix here
958
959        SEC_helix *helix = get_fixpoint_helix();
960#if defined(CHECK_INTEGRITY)
961        helix->check_integrity(CHECK_STRUCTURE);
962        helix->check_integrity(CHECK_SIZE);
963#endif // CHECK_INTEGRITY
964        helix->calculate_helix_coordinates();
965#if defined(CHECK_INTEGRITY)
966        helix->check_integrity(CHECK_POSITIONS);
967#endif // CHECK_INTEGRITY
968    }
969}
970inline void SEC_loop::sizeChanged() { // recalc size and coordinates
971    if (is_root_loop()) {
972        get_root()->relayout();
973    }
974    else {
975        SEC_helix *helix = get_fixpoint_helix();
976#if defined(CHECK_INTEGRITY)
977        helix->check_integrity(CHECK_STRUCTURE);
978#endif // CHECK_INTEGRITY
979        helix->calculate_helix_size();
980#if defined(CHECK_INTEGRITY)
981        helix->check_integrity(CHECK_SIZE);
982#endif // CHECK_INTEGRITY
983        helix->calculate_helix_coordinates();
984#if defined(CHECK_INTEGRITY)
985        helix->check_integrity(CHECK_POSITIONS);
986#endif // CHECK_INTEGRITY
987    }
988}
989
990// --------------------
991
992inline SEC_base *SEC_segment::get_parent() { return loop; }
993
994// --------------------
995
996inline bool are_adjacent_regions(const SEC_region *reg1, const SEC_region *reg2) {
997    int end1   = reg1->get_sequence_end();
998    int start2 = reg2->get_sequence_start();
999
1000    if (end1 == start2) return true;
1001
1002    return start2 == 0;
1003}
1004
1005
1006#else
1007#error SEC_root.hxx included twice
1008#endif
1009
Note: See TracBrowser for help on using the repository browser.