25 typedef std::map<SEC_helix*, Angle> AngleMap;
30 Angle loop2helix(SEC_loop *loop, SEC_helix *helix) {
31 return Angle(loop->get_center(), helix->strandAwayFrom(loop)->get_fixpoint());
37 void store(SEC_helix *helix, SEC_loop *loop) {
40 angles[helix] = helix->get_abs_angle();
43 angles[helix] = helix->get_abs_angle()-loop2helix(loop, helix);
48 void set_angle(SEC_helix *helix,
const Angle& angle) { angles[helix] = angle; }
50 void restore(SEC_helix *helix, SEC_loop *loop) {
53 helix->set_abs_angle(angles[helix]);
56 if (helix->hasLoop(loop)) {
57 helix->set_abs_angle(angles[helix]+loop2helix(loop, helix));
64 AngleMap::iterator e = angles.end();
65 for (AngleMap::iterator a = angles.begin(); a != e; ++a) {
66 restore(a->first, loop);
70 void remove(SEC_helix *helix) { angles.erase(helix); }
74 SEC_helix *helix = strand->get_helix();
75 if (helix != skip) store(helix, loop);
84 void SEC_loop::toggle_root(SEC_loop *old_root) {
87 SEC_helix *mid_helix = get_rootside_helix();
91 SEC_loop *behind = mid_helix->rootsideLoop();
92 if (behind != old_root) {
93 behind->toggle_root(old_root);
99 Angle midAngle = mid_helix->get_abs_angle();
104 thisOldAbs.storeAllHelices(
this, mid_helix);
105 otherOldAbs.storeAllHelices(old_root, mid_helix);
108 get_root()->set_root_loop(
this);
110 set_fixpoint_strand(mid_helix->strandAwayFrom(
this));
111 old_root->set_fixpoint_strand(mid_helix->strandAwayFrom(old_root));
114 set_rel_angle(
Angle(center, get_fixpoint()));
115 mark_angle_absolute();
117 old_root->set_abs_angle(
Angle(old_root->get_fixpoint(), old_root->get_center()));
120 thisOldAbs.restoreAll(
this);
121 otherOldAbs.restoreAll(old_root);
125 SEC_loop *old_root = get_root_loop();
126 if (loop != old_root) {
127 Vector new2old(loop->get_center(), old_root->get_center());
128 add_autoscroll(new2old);
129 loop->toggle_root(old_root);
139 SEC_helix_strand *start_strand = root_loop->get_fixpoint_strand();
140 SEC_helix_strand *strand = start_strand;
145 SEC_helix_strand *other_strand = strand->get_other_strand();
146 SEC_region *oreg = other_strand->get_region();
150 seg = other_strand->get_next_segment();
154 seg = strand->get_next_segment();
157 if (seg->get_region()->contains_seq_position(pos))
return seg;
158 strand = seg->get_next_strand();
160 while (strand != start_strand);
172 result =
static_cast<SEC_segment*
>(found);
190 SEC_segment *end_segment;
191 if (end == start+1) {
192 end_segment = start_segment;
199 if (end_segment != start_segment) {
200 error =
GBS_global_string(
"Positions %i and %i are in different segments", start, end);
201 start_segment =
NULp;
205 sec_assert(contradicted(start_segment, error));
206 return start_segment;
218 return split_loop(start2, end2, start1, end1);
223 error =
GBS_global_string(
"Helices overlap (%i-%i and %i-%i)", start1, end1, start2, end2);
228 SEC_segment *seg2 =
NULp;
234 SEC_loop *old_loop = seg1->get_loop();
235 if (old_loop != seg2->get_loop()) {
236 error =
"Positions are in different loops (no tertiary structures possible)";
239 SEC_loop *setRootTo =
NULp;
241 if (old_loop->is_root_loop()) {
242 set_root(seg1->get_next_strand()->get_destination_loop());
243 setRootTo = old_loop;
249 SEC_helix *new_helix =
NULp;
250 SEC_loop *new_loop =
NULp;
265 SEC_helix_strand *strand1 = seg1->split(start1, end1, &seg2);
266 SEC_helix_strand *strand2 =
NULp;
267 SEC_segment *seg3 =
NULp;
269 if (seg1->get_region()->contains_seq_position(start2)) {
272 strand1 = seg1->split(start2, end2, &seg2);
275 sec_assert(seg2->get_region()->contains_seq_position(start2));
276 strand2 = seg2->split(start2, end2, &seg3);
284 new_helix =
new SEC_helix(
this, strand2, strand1);
286 strand1->set_next_segment(seg3);
287 strand2->set_next_segment(seg2);
289 new_loop =
new SEC_loop(
this);
291 seg2->set_loop(new_loop);
293 strand2->set_origin_loop(new_loop);
294 new_loop->set_fixpoint_strand(strand2);
310 for (SEC_segment *
s = seg1;
s != seg2;) {
311 SEC_helix_strand *hs =
s->get_next_strand();
312 if (!hs->isRootsideFixpoint()) {
315 swap(start1, start2);
319 s = hs->get_next_segment();
324 SEC_helix_strand *strand1 = seg1->split(start1, end1, &seg3);
325 SEC_helix_strand *strand2 = seg2->split(start2, end2, &seg4);
327 new_helix =
new SEC_helix(
this, strand2, strand1);
329 strand1->set_next_segment(seg4);
330 strand2->set_next_segment(seg3);
332 new_loop =
new SEC_loop(
this);
334 for (SEC_segment *
s = seg3; ;) {
335 s->set_loop(new_loop);
336 SEC_helix_strand *h =
s->get_next_strand();
337 h->set_origin_loop(new_loop);
338 if (
s == seg2)
break;
339 s = h->get_next_segment();
342 new_loop->set_fixpoint_strand(strand2);
346 new_helix->set_rel_angle(0);
347 new_loop->set_rel_angle(0);
388 SEC_helix_strand *strand[2] = { remove_strand, remove_strand->get_other_strand() };
392 #if defined(CHECK_INTEGRITY)
393 check_integrity(CHECK_STRUCTURE);
394 #endif // CHECK_INTEGRITY
397 for (s = 0; s<2; s++) {
398 after[
s] = strand[
s]->get_next_segment();
399 before[
s] = strand[
s]->get_previous_segment();
400 loop[
s] = strand[
s]->get_origin_loop();
406 bool is_terminal_loop[2] = { before[0] == after[0], before[1] == after[1] };
410 if (is_terminal_loop[0]) {
411 if (is_terminal_loop[1]) {
412 error =
"You cannot delete the last helix";
418 if (is_terminal_loop[1]) i0 = 1;
422 int del = i0 >= 0 ? i0 : 1;
424 SEC_loop *setRootTo =
NULp;
428 SEC_loop *rootLoop = get_root_loop();
429 if (loop[0] == rootLoop || loop[1] == rootLoop) {
430 SEC_loop *termLoop = is_terminal_loop[0] ? loop[0] : loop[1];
431 SEC_helix_strand *toTerm = strand[0]->get_helix()->strandTowards(termLoop);
432 SEC_helix_strand *toNextLoop = toTerm->get_next_segment()->get_next_strand();
433 SEC_loop *anotherLoop = toNextLoop->get_destination_loop();
435 sec_assert(anotherLoop != loop[0] && anotherLoop != loop[1]);
437 set_root(anotherLoop);
438 setRootTo = loop[1-del];
442 SEC_helix *removed_helix = strand[0]->get_helix();
452 before[i1]->mergeWith(after[i1], loop[i1]);
460 SEC_helix_strand *rootsideStrand = strand[0]->get_helix()->rootsideLoop()->get_rootside_strand();
462 before[1]->mergeWith(after[0], loop[0]);
463 before[0]->mergeWith(after[1], loop[0]);
467 SEC_segment *seg = before[0];
468 while (seg != before[1]) {
469 SEC_helix_strand *loop1_strand = seg->get_next_strand();
470 loop1_strand->set_origin_loop(loop[0]);
472 seg = loop1_strand->get_next_segment();
473 seg->set_loop(loop[0]);
476 loop[0]->set_fixpoint_strand(rootsideStrand);
479 loop[del]->set_fixpoint_strand(
NULp);
482 for (s = 0; s<2; s++) strand[s]->unlink(
false);
490 if (setRootTo) set_root(setRootTo);
GB_ERROR unsplit_loop(SEC_helix_strand *delete_strand)
void restoreAll(SEC_loop *loop)
int get_sequence_start() const
GB_ERROR split_loop(int start1, int end1, int start2, int end2)
int get_sequence_end() const
bool are_adjacent_regions(const SEC_region *reg1, const SEC_region *reg2)
void restore(SEC_helix *helix, SEC_loop *loop)
SEC_segment * findSegmentContaining(SEC_root *root, int pos, GB_ERROR &error)
const char * GBS_global_string(const char *templat,...)
bool contains_seq_position(int pos) const
virtual SEC_BASE_TYPE getType() const =0
static HelixNrInfo * start
AliDataPtr after(AliDataPtr data, size_t pos)
AngleBuffer(AngleBufferMode Mode)
void store(SEC_helix *helix, SEC_loop *loop)
static void error(const char *msg)
CONSTEXPR_INLINE_Cxx14 void swap(unsigned char &c1, unsigned char &c2)
AliDataPtr before(AliDataPtr data, size_t pos)
SEC_base_part * find(int pos)
void set_angle(SEC_helix *helix, const Angle &angle)
void storeAllHelices(SEC_loop *loop, SEC_helix *skip)
void set_root(SEC_loop *loop)
GB_write_int const char s