| 1 | // =============================================================== // |
|---|
| 2 | // // |
|---|
| 3 | // File : SEC_structure.cxx // |
|---|
| 4 | // Purpose : general implementation of classes in SEC_root.hxx // |
|---|
| 5 | // // |
|---|
| 6 | // Coded by Ralf Westram (coder@reallysoft.de) in August 2007 // |
|---|
| 7 | // Institute of Microbiology (Technical University Munich) // |
|---|
| 8 | // http://www.arb-home.de/ // |
|---|
| 9 | // // |
|---|
| 10 | // =============================================================== // |
|---|
| 11 | |
|---|
| 12 | #include "SEC_root.hxx" |
|---|
| 13 | #include "SEC_iter.hxx" |
|---|
| 14 | |
|---|
| 15 | using namespace std; |
|---|
| 16 | |
|---|
| 17 | // ---------------------- |
|---|
| 18 | // Constructors |
|---|
| 19 | |
|---|
| 20 | SEC_segment::SEC_segment() |
|---|
| 21 | : alpha(0), |
|---|
| 22 | center1(Origin), |
|---|
| 23 | center2(Origin), |
|---|
| 24 | next_helix_strand(NULp), |
|---|
| 25 | loop(NULp) |
|---|
| 26 | {} |
|---|
| 27 | |
|---|
| 28 | SEC_helix_strand::SEC_helix_strand() |
|---|
| 29 | : origin_loop(NULp), |
|---|
| 30 | other_strand(NULp), |
|---|
| 31 | helix_info(NULp), |
|---|
| 32 | next_segment(NULp), |
|---|
| 33 | fixpoint(Origin), |
|---|
| 34 | rightAttach(Origin), |
|---|
| 35 | leftAttach(Origin) |
|---|
| 36 | {} |
|---|
| 37 | |
|---|
| 38 | SEC_loop::SEC_loop(SEC_root *root_) |
|---|
| 39 | : SEC_base(root_), |
|---|
| 40 | Circumference(0), |
|---|
| 41 | center(0, 0), |
|---|
| 42 | primary_strand(NULp) |
|---|
| 43 | {} |
|---|
| 44 | |
|---|
| 45 | SEC_helix::SEC_helix(SEC_root *root_, SEC_helix_strand *to_root, SEC_helix_strand *from_root) |
|---|
| 46 | : SEC_base(root_), |
|---|
| 47 | strand_to_root(to_root), |
|---|
| 48 | base_length(0) |
|---|
| 49 | { |
|---|
| 50 | sec_assert(!to_root->get_helix()); |
|---|
| 51 | sec_assert(!from_root->get_helix()); |
|---|
| 52 | sec_assert(!to_root->get_other_strand()); |
|---|
| 53 | sec_assert(!from_root->get_other_strand()); |
|---|
| 54 | |
|---|
| 55 | to_root->set_other_strand(from_root); |
|---|
| 56 | from_root->set_other_strand(to_root); |
|---|
| 57 | |
|---|
| 58 | to_root->set_helix_info(this); |
|---|
| 59 | from_root->set_helix_info(this); |
|---|
| 60 | } |
|---|
| 61 | |
|---|
| 62 | |
|---|
| 63 | SEC_root::SEC_root() |
|---|
| 64 | : root_loop(NULp), |
|---|
| 65 | cursorAbsPos(-1), |
|---|
| 66 | xString(NULp), |
|---|
| 67 | constructing(false), |
|---|
| 68 | db(NULp), |
|---|
| 69 | bg_color(NULp), |
|---|
| 70 | autoscroll(NULp), |
|---|
| 71 | nailedAbsPos(-1), |
|---|
| 72 | drawnPositions(NULp), |
|---|
| 73 | cursor_line(LineVector(Origin, ZeroVector)), |
|---|
| 74 | show_constraints(SEC_NO_TYPE) |
|---|
| 75 | { |
|---|
| 76 | for (int i = 0; i<SEC_GC_DATA_COUNT; ++i) { |
|---|
| 77 | charRadius[i] = -1.0; |
|---|
| 78 | bg_linewidth[i] = -1.0; |
|---|
| 79 | } |
|---|
| 80 | } |
|---|
| 81 | |
|---|
| 82 | void SEC_root::init(SEC_graphic *gfx, AWT_canvas *scr, ED4_plugin_host& Host) { |
|---|
| 83 | db = new SEC_db_interface(gfx, scr, Host); |
|---|
| 84 | } |
|---|
| 85 | |
|---|
| 86 | // --------------------- |
|---|
| 87 | // Destructors |
|---|
| 88 | |
|---|
| 89 | SEC_region::SEC_region(int start, int end) : |
|---|
| 90 | sequence_start(start), |
|---|
| 91 | sequence_end(end), |
|---|
| 92 | baseCount(-1), |
|---|
| 93 | abspos_array(NULp) |
|---|
| 94 | #if defined(ASSERTION_USED) |
|---|
| 95 | ,abspos_array_size(0) |
|---|
| 96 | #endif // ASSERTION_USED |
|---|
| 97 | { |
|---|
| 98 | sec_assert((start == -1 && end == -1) || start != end); |
|---|
| 99 | } |
|---|
| 100 | |
|---|
| 101 | SEC_region::~SEC_region() { |
|---|
| 102 | invalidate_base_count(); // frees abspos_array |
|---|
| 103 | delete [] abspos_array; |
|---|
| 104 | } |
|---|
| 105 | |
|---|
| 106 | SEC_segment::~SEC_segment() { |
|---|
| 107 | } |
|---|
| 108 | |
|---|
| 109 | |
|---|
| 110 | SEC_helix_strand::~SEC_helix_strand() { |
|---|
| 111 | if (next_segment) { |
|---|
| 112 | next_segment->delete_pointer_2(this); |
|---|
| 113 | } |
|---|
| 114 | |
|---|
| 115 | delete helix_info; |
|---|
| 116 | |
|---|
| 117 | if (other_strand) { |
|---|
| 118 | if (other_strand->next_segment) { |
|---|
| 119 | other_strand->next_segment->delete_pointer_2(other_strand); |
|---|
| 120 | } |
|---|
| 121 | other_strand->helix_info = NULp; |
|---|
| 122 | other_strand->other_strand = NULp; |
|---|
| 123 | other_strand->next_segment = NULp; |
|---|
| 124 | delete other_strand; |
|---|
| 125 | } |
|---|
| 126 | |
|---|
| 127 | delete origin_loop; |
|---|
| 128 | } |
|---|
| 129 | |
|---|
| 130 | |
|---|
| 131 | #define SEG_MAX 20 |
|---|
| 132 | |
|---|
| 133 | SEC_loop::~SEC_loop() { |
|---|
| 134 | if (primary_strand) { |
|---|
| 135 | sec_assert(get_root()->get_root_loop() != this); |
|---|
| 136 | |
|---|
| 137 | // collect all segments in an array |
|---|
| 138 | SEC_segment *segment[SEG_MAX]; |
|---|
| 139 | int i = 0; |
|---|
| 140 | |
|---|
| 141 | for (SEC_strand_iterator strand(this); strand; ++strand) { |
|---|
| 142 | SEC_segment *seg = strand->get_next_segment(); |
|---|
| 143 | if (seg) { |
|---|
| 144 | sec_assert(i < SEG_MAX); |
|---|
| 145 | sec_assert(seg->get_loop() == this); |
|---|
| 146 | |
|---|
| 147 | segment[i++] = seg; |
|---|
| 148 | } |
|---|
| 149 | } |
|---|
| 150 | |
|---|
| 151 | set_fixpoint_strand(NULp); // disconnect from loop |
|---|
| 152 | |
|---|
| 153 | // delete all strands connected to loop |
|---|
| 154 | int j; |
|---|
| 155 | for (j=0; j<i; j++) { |
|---|
| 156 | SEC_helix_strand *strand = segment[j]->get_next_strand(); |
|---|
| 157 | if (strand) { |
|---|
| 158 | sec_assert(strand->get_origin_loop() == this); |
|---|
| 159 | strand->set_origin_loop(NULp); |
|---|
| 160 | delete strand; |
|---|
| 161 | } |
|---|
| 162 | } |
|---|
| 163 | // delete all segments connected to loop |
|---|
| 164 | for (j=0; j<i; j++) delete segment[j]; |
|---|
| 165 | } |
|---|
| 166 | } |
|---|
| 167 | |
|---|
| 168 | SEC_root::~SEC_root() { |
|---|
| 169 | delete db; |
|---|
| 170 | delete autoscroll; |
|---|
| 171 | |
|---|
| 172 | delete_root_loop(); |
|---|
| 173 | |
|---|
| 174 | free(bg_color); |
|---|
| 175 | |
|---|
| 176 | delete_announced_positions(); |
|---|
| 177 | } |
|---|
| 178 | |
|---|
| 179 | // -------------------------- |
|---|
| 180 | // integrity checks |
|---|
| 181 | |
|---|
| 182 | #if defined(CHECK_INTEGRITY) |
|---|
| 183 | |
|---|
| 184 | void SEC_region::check_integrity(const SEC_root *root, SEC_CHECK_TYPE what) const { |
|---|
| 185 | if (what&CHECK_SIZE) { |
|---|
| 186 | sec_assert(baseCount >= 0); |
|---|
| 187 | if (baseCount>0) { |
|---|
| 188 | sec_assert(abspos_array || !root->get_db()->canDisplay()); |
|---|
| 189 | } |
|---|
| 190 | } |
|---|
| 191 | } |
|---|
| 192 | |
|---|
| 193 | void SEC_segment::check_integrity(SEC_CHECK_TYPE what) const { |
|---|
| 194 | if (what&CHECK_STRUCTURE) { |
|---|
| 195 | sec_assert(next_helix_strand); |
|---|
| 196 | sec_assert(loop == parent()); |
|---|
| 197 | } |
|---|
| 198 | if (what&CHECK_SIZE) { |
|---|
| 199 | sec_assert(alpha == alpha); |
|---|
| 200 | sec_assert(alpha != 0); |
|---|
| 201 | } |
|---|
| 202 | if (what&CHECK_POSITIONS) { |
|---|
| 203 | sec_assert(center1.valid()); |
|---|
| 204 | sec_assert(center2.valid()); |
|---|
| 205 | } |
|---|
| 206 | get_region()->check_integrity(get_root(), what); |
|---|
| 207 | } |
|---|
| 208 | |
|---|
| 209 | void SEC_helix_strand::check_integrity(SEC_CHECK_TYPE what) const { |
|---|
| 210 | if (what&CHECK_STRUCTURE) { |
|---|
| 211 | sec_assert(other_strand != this); |
|---|
| 212 | sec_assert(other_strand->other_strand == this); |
|---|
| 213 | sec_assert(helix_info); |
|---|
| 214 | sec_assert(helix_info == other_strand->helix_info); |
|---|
| 215 | sec_assert(parent() == helix_info); |
|---|
| 216 | } |
|---|
| 217 | if (what&CHECK_SIZE) { |
|---|
| 218 | get_region()->get_base_count(); // asserts base count is up-to-date |
|---|
| 219 | } |
|---|
| 220 | if (what&CHECK_POSITIONS) { |
|---|
| 221 | sec_assert(fixpoint.valid()); |
|---|
| 222 | sec_assert(rightAttach.valid()); |
|---|
| 223 | sec_assert(leftAttach.valid()); |
|---|
| 224 | } |
|---|
| 225 | get_region()->check_integrity(get_root(), what); |
|---|
| 226 | } |
|---|
| 227 | |
|---|
| 228 | void SEC_helix::check_integrity(SEC_CHECK_TYPE what) const { |
|---|
| 229 | sec_assert(strand_to_root); |
|---|
| 230 | |
|---|
| 231 | SEC_helix_strand *other_strand = strand_to_root->get_other_strand(); |
|---|
| 232 | sec_assert(other_strand); |
|---|
| 233 | |
|---|
| 234 | if (what&CHECK_STRUCTURE) { |
|---|
| 235 | sec_assert(strand_to_root->get_helix() == this); |
|---|
| 236 | sec_assert(other_strand->get_other_strand() == strand_to_root); |
|---|
| 237 | sec_assert(get_rel_angle().valid()); |
|---|
| 238 | sec_assert(parent() == rootsideLoop()); |
|---|
| 239 | } |
|---|
| 240 | |
|---|
| 241 | if (what&CHECK_SIZE) { |
|---|
| 242 | sec_assert(base_length >= 1); |
|---|
| 243 | sec_assert(drawnSize() >= 0); |
|---|
| 244 | } |
|---|
| 245 | |
|---|
| 246 | strand_to_root->check_integrity(what); |
|---|
| 247 | other_strand->check_integrity(what); |
|---|
| 248 | } |
|---|
| 249 | |
|---|
| 250 | void SEC_loop::check_integrity(SEC_CHECK_TYPE what) const { |
|---|
| 251 | int count = 0; |
|---|
| 252 | int rootStrands = 0; |
|---|
| 253 | |
|---|
| 254 | if (what&CHECK_STRUCTURE) { |
|---|
| 255 | sec_assert(primary_strand); |
|---|
| 256 | sec_assert(primary_strand->get_origin_loop() == this); |
|---|
| 257 | sec_assert(get_rel_angle().valid()); |
|---|
| 258 | } |
|---|
| 259 | |
|---|
| 260 | for (SEC_strand_const_iterator strand(this); strand; ++strand) { |
|---|
| 261 | if (what&CHECK_STRUCTURE) { |
|---|
| 262 | sec_assert(this == strand->get_origin_loop()); |
|---|
| 263 | } |
|---|
| 264 | |
|---|
| 265 | const SEC_helix *helix = strand->get_helix(); |
|---|
| 266 | if (this == helix->rootsideLoop()) { // test outgoing helixes |
|---|
| 267 | helix->check_integrity(what); |
|---|
| 268 | } |
|---|
| 269 | else { |
|---|
| 270 | rootStrands++; |
|---|
| 271 | } |
|---|
| 272 | |
|---|
| 273 | const SEC_segment *seg = strand->get_next_segment(); |
|---|
| 274 | |
|---|
| 275 | if (what&CHECK_STRUCTURE) { |
|---|
| 276 | sec_assert(this == seg->get_loop()); |
|---|
| 277 | } |
|---|
| 278 | seg->check_integrity(what); |
|---|
| 279 | count++; |
|---|
| 280 | sec_assert(count<100); // more than 100 segments in one loop! assume error in structure! |
|---|
| 281 | } |
|---|
| 282 | |
|---|
| 283 | if (what&CHECK_STRUCTURE) { |
|---|
| 284 | if (is_root_loop()) { |
|---|
| 285 | sec_assert(!rootStrands); |
|---|
| 286 | sec_assert(primary_strand->pointsToOutside()); |
|---|
| 287 | sec_assert(!parent()); |
|---|
| 288 | } |
|---|
| 289 | else { |
|---|
| 290 | sec_assert(rootStrands); |
|---|
| 291 | sec_assert(primary_strand->pointsToRoot()); |
|---|
| 292 | sec_assert(parent() == get_rootside_helix()); |
|---|
| 293 | } |
|---|
| 294 | } |
|---|
| 295 | |
|---|
| 296 | if (what&CHECK_SIZE) { |
|---|
| 297 | sec_assert(Circumference>0); |
|---|
| 298 | sec_assert(drawnSize()>0); |
|---|
| 299 | } |
|---|
| 300 | if (what&CHECK_POSITIONS) { |
|---|
| 301 | sec_assert(center.valid()); |
|---|
| 302 | if (is_root_loop()) { |
|---|
| 303 | sec_assert(isOrigin(center)); |
|---|
| 304 | } |
|---|
| 305 | } |
|---|
| 306 | |
|---|
| 307 | // now recurse downwards |
|---|
| 308 | for (SEC_strand_const_iterator strand(this); strand; ++strand) { |
|---|
| 309 | SEC_loop *outsideLoop = strand->get_helix()->outsideLoop(); |
|---|
| 310 | if (outsideLoop != this) outsideLoop->check_integrity(what); |
|---|
| 311 | } |
|---|
| 312 | } |
|---|
| 313 | |
|---|
| 314 | void SEC_root::check_integrity(SEC_CHECK_TYPE what) const { |
|---|
| 315 | if (root_loop) { |
|---|
| 316 | sec_assert(!under_construction()); // cannot check integrity, when structure is under construction |
|---|
| 317 | |
|---|
| 318 | root_loop->check_integrity(what); |
|---|
| 319 | |
|---|
| 320 | // check whether structure is a ring and whether regions are correct |
|---|
| 321 | |
|---|
| 322 | const SEC_base_part *start_part = root_loop->get_fixpoint_strand(); |
|---|
| 323 | const SEC_base_part *part = start_part; |
|---|
| 324 | const SEC_region *region = part->get_region(); |
|---|
| 325 | |
|---|
| 326 | int count = 0; |
|---|
| 327 | do { |
|---|
| 328 | const SEC_base_part *next_part = part->next(); |
|---|
| 329 | const SEC_region *next_region = next_part->get_region(); |
|---|
| 330 | |
|---|
| 331 | sec_assert(are_adjacent_regions(region, next_region)); |
|---|
| 332 | |
|---|
| 333 | part = next_part; |
|---|
| 334 | region = next_region; |
|---|
| 335 | |
|---|
| 336 | count++; |
|---|
| 337 | sec_assert(count<10000); // structure does not seem to be a ring |
|---|
| 338 | } |
|---|
| 339 | while (part != start_part); |
|---|
| 340 | } |
|---|
| 341 | } |
|---|
| 342 | #endif // CHECK_INTEGRITY |
|---|
| 343 | |
|---|
| 344 | // --------------------------------- |
|---|
| 345 | // unlink strands/segments |
|---|
| 346 | |
|---|
| 347 | void SEC_helix_strand::unlink(bool fromOtherStrandAsWell) { |
|---|
| 348 | // if called with fromOtherStrandAsWell == false, |
|---|
| 349 | // the strand-pair remains deletable |
|---|
| 350 | |
|---|
| 351 | next_segment = NULp; |
|---|
| 352 | origin_loop = NULp; |
|---|
| 353 | |
|---|
| 354 | if (fromOtherStrandAsWell) other_strand = NULp; |
|---|
| 355 | } |
|---|
| 356 | |
|---|
| 357 | void SEC_segment::unlink() { |
|---|
| 358 | next_helix_strand = NULp; |
|---|
| 359 | } |
|---|
| 360 | |
|---|
| 361 | // ------------------------------ |
|---|
| 362 | // split/merge segments |
|---|
| 363 | |
|---|
| 364 | SEC_helix_strand *SEC_segment::split(size_t start, size_t end, SEC_segment **segment2_ptr) { |
|---|
| 365 | // split segment into 'segment1 - strand - segment2' |
|---|
| 366 | // segment2 still points to same loop as 'this' (must be corrected by caller) |
|---|
| 367 | // strand is a single strand (must be connected by caller) |
|---|
| 368 | |
|---|
| 369 | sec_assert(get_region()->contains_seq_position(start)); |
|---|
| 370 | sec_assert(get_region()->contains_seq_position(end-1)); |
|---|
| 371 | |
|---|
| 372 | SEC_helix_strand *strand = new SEC_helix_strand; |
|---|
| 373 | SEC_segment *segment2 = new SEC_segment; |
|---|
| 374 | |
|---|
| 375 | segment2->set_sequence_portion(end, get_region()->get_sequence_end()); |
|---|
| 376 | strand->set_sequence_portion(start, end); |
|---|
| 377 | set_sequence_portion(get_region()->get_sequence_start(), start); |
|---|
| 378 | |
|---|
| 379 | segment2->set_loop(get_loop()); // set to same loop as this (must be corrected later) |
|---|
| 380 | strand->set_origin_loop(get_loop()); |
|---|
| 381 | |
|---|
| 382 | segment2->set_next_strand(get_next_strand()); |
|---|
| 383 | set_next_strand(strand); |
|---|
| 384 | |
|---|
| 385 | *segment2_ptr = segment2; |
|---|
| 386 | |
|---|
| 387 | return strand; |
|---|
| 388 | } |
|---|
| 389 | |
|---|
| 390 | void SEC_segment::mergeWith(SEC_segment *other, SEC_loop *target_loop) { |
|---|
| 391 | set_sequence_portion(get_region()->get_sequence_start(), |
|---|
| 392 | other->get_region()->get_sequence_end()); |
|---|
| 393 | |
|---|
| 394 | set_next_strand(other->get_next_strand()); |
|---|
| 395 | set_loop(target_loop); |
|---|
| 396 | delete other; |
|---|
| 397 | } |
|---|
| 398 | |
|---|
| 399 | // ---------------------- |
|---|
| 400 | // Reset angles |
|---|
| 401 | |
|---|
| 402 | void SEC_loop::reset_angles() { |
|---|
| 403 | for (SEC_strand_iterator strand(this); strand; ++strand) { |
|---|
| 404 | if (strand->pointsToOutside()) { |
|---|
| 405 | Angle abs(center, strand->get_fixpoint()); |
|---|
| 406 | strand->get_helix()->set_abs_angle(abs); |
|---|
| 407 | } |
|---|
| 408 | } |
|---|
| 409 | set_rel_angle(0); |
|---|
| 410 | } |
|---|
| 411 | |
|---|
| 412 | void SEC_helix::reset_angles() { |
|---|
| 413 | outsideLoop()->set_rel_angle(0); |
|---|
| 414 | SEC_loop *rloop = rootsideLoop(); |
|---|
| 415 | |
|---|
| 416 | Angle toFix(rloop->get_center(), strandToOutside()->get_fixpoint()); |
|---|
| 417 | set_abs_angle(toFix); |
|---|
| 418 | } |
|---|
| 419 | |
|---|
| 420 | |
|---|
| 421 | // --------------- |
|---|
| 422 | // other |
|---|
| 423 | |
|---|
| 424 | size_t SEC_base_part::getNextAbspos() const { |
|---|
| 425 | // returns the next valid abspos |
|---|
| 426 | const SEC_region *reg = get_region(); |
|---|
| 427 | int start = reg->get_sequence_start(); |
|---|
| 428 | |
|---|
| 429 | if (start != reg->get_sequence_end()) { |
|---|
| 430 | return start; |
|---|
| 431 | } |
|---|
| 432 | return next()->getNextAbspos(); |
|---|
| 433 | } |
|---|
| 434 | |
|---|
| 435 | |
|---|
| 436 | SEC_segment *SEC_helix_strand::get_previous_segment() { |
|---|
| 437 | SEC_segment *segment_before; |
|---|
| 438 | SEC_helix_strand *strand_pointer = next_segment->get_next_strand(); |
|---|
| 439 | |
|---|
| 440 | if (strand_pointer == this) { |
|---|
| 441 | segment_before = next_segment; // we are in a loop with only one segment |
|---|
| 442 | } |
|---|
| 443 | else { |
|---|
| 444 | while (strand_pointer != this) { |
|---|
| 445 | segment_before = strand_pointer->get_next_segment(); |
|---|
| 446 | strand_pointer = segment_before->get_next_strand(); |
|---|
| 447 | } |
|---|
| 448 | } |
|---|
| 449 | return segment_before; |
|---|
| 450 | } |
|---|
| 451 | |
|---|
| 452 | static void findLongestHelix(const BI_helix *helix, size_t& start1, size_t& end1, size_t& start2, size_t& end2) { |
|---|
| 453 | const char *longestHelixNr = NULp; |
|---|
| 454 | size_t longestLength = 0; |
|---|
| 455 | |
|---|
| 456 | const char *lastHelixNr = NULp; |
|---|
| 457 | size_t lastHelixLen = 0; |
|---|
| 458 | for (long pos = helix->first_pair_position(); pos != -1; pos = helix->next_pair_position(pos)) { |
|---|
| 459 | const char *currHelixNr = helix->helixNr(size_t(pos)); |
|---|
| 460 | if (currHelixNr != lastHelixNr) { |
|---|
| 461 | if (lastHelixLen>longestLength) { |
|---|
| 462 | longestLength = lastHelixLen; |
|---|
| 463 | longestHelixNr = lastHelixNr; |
|---|
| 464 | } |
|---|
| 465 | lastHelixNr = currHelixNr; |
|---|
| 466 | lastHelixLen = 1; |
|---|
| 467 | } |
|---|
| 468 | else { |
|---|
| 469 | lastHelixLen++; |
|---|
| 470 | } |
|---|
| 471 | } |
|---|
| 472 | |
|---|
| 473 | if (lastHelixLen>longestLength) longestHelixNr = lastHelixNr; |
|---|
| 474 | |
|---|
| 475 | sec_assert(longestHelixNr); |
|---|
| 476 | start1 = helix->first_position(longestHelixNr); |
|---|
| 477 | end1 = helix->last_position(longestHelixNr); |
|---|
| 478 | start2 = helix->opposite_position(end1); |
|---|
| 479 | end2 = helix->opposite_position(start1); |
|---|
| 480 | } |
|---|
| 481 | |
|---|
| 482 | void SEC_root::create_default_bone() { |
|---|
| 483 | // create default structure |
|---|
| 484 | |
|---|
| 485 | set_under_construction(true); |
|---|
| 486 | |
|---|
| 487 | SEC_loop *loop1 = new SEC_loop(this); |
|---|
| 488 | SEC_loop *loop2 = new SEC_loop(this); |
|---|
| 489 | |
|---|
| 490 | set_root_loop(loop1); |
|---|
| 491 | |
|---|
| 492 | SEC_segment *segment1 = new SEC_segment; |
|---|
| 493 | SEC_segment *segment2 = new SEC_segment; |
|---|
| 494 | |
|---|
| 495 | segment1->set_loop(loop1); |
|---|
| 496 | segment2->set_loop(loop2); |
|---|
| 497 | |
|---|
| 498 | SEC_helix_strand *strand1 = new SEC_helix_strand; |
|---|
| 499 | SEC_helix_strand *strand2 = new SEC_helix_strand; |
|---|
| 500 | |
|---|
| 501 | loop1->set_fixpoint_strand(strand1); |
|---|
| 502 | loop2->set_fixpoint_strand(strand2); |
|---|
| 503 | |
|---|
| 504 | segment1->set_next_strand(strand1); |
|---|
| 505 | segment2->set_next_strand(strand2); |
|---|
| 506 | |
|---|
| 507 | strand1->set_origin_loop(loop1); |
|---|
| 508 | strand2->set_origin_loop(loop2); |
|---|
| 509 | |
|---|
| 510 | SEC_helix *helix = new SEC_helix(this, strand1, strand2); |
|---|
| 511 | |
|---|
| 512 | strand1->set_next_segment(segment1); |
|---|
| 513 | strand2->set_next_segment(segment2); |
|---|
| 514 | |
|---|
| 515 | size_t start1, end1, start2, end2; |
|---|
| 516 | findLongestHelix(get_helixDef(), start1, end1, start2, end2); |
|---|
| 517 | |
|---|
| 518 | strand1->set_sequence_portion(start1, end1+1); segment2->set_sequence_portion(end1+1, start2); |
|---|
| 519 | strand2->set_sequence_portion(start2, end2+1); segment1->set_sequence_portion(end2+1, start1); |
|---|
| 520 | |
|---|
| 521 | root_loop = helix->rootsideLoop(); |
|---|
| 522 | |
|---|
| 523 | loop1->set_rel_angle(0); |
|---|
| 524 | loop2->set_rel_angle(0); |
|---|
| 525 | helix->set_rel_angle(0); |
|---|
| 526 | |
|---|
| 527 | root_loop->mark_angle_absolute(); |
|---|
| 528 | root_loop->set_center(Origin); |
|---|
| 529 | |
|---|
| 530 | set_under_construction(false); |
|---|
| 531 | |
|---|
| 532 | delete xString; |
|---|
| 533 | xString = NULp; |
|---|
| 534 | generate_x_string(); |
|---|
| 535 | |
|---|
| 536 | relayout(); |
|---|
| 537 | } |
|---|
| 538 | |
|---|