// If true, _leftParent will store the swapped segment (and _cur will store) // the other half // NEED TO REVISE WITH STRONGER CRITERIA -- right now any operation // next to an endpoint can get confused with a translocation. bool DefaultRearrangement::scanTranslocationCycle( TopSegmentIteratorConstPtr topSegment) { assert(topSegment.get()); resetStatus(topSegment); bool first = _cur->isFirst(); bool last = _cur->isLast(); if (_cur->hasParent() == false || (!first && !last)) { return false; } _leftParent->toParent(_cur); bool pFirst = _leftParent->isFirst(); //bool pLast = _leftParent->isLast(); _rightParent->copy(_leftParent); first ? _right->toRight() : _right->toLeft(); pFirst ? _rightParent->toRight() : _rightParent->toLeft(); if (_right->hasParent() == false) { return true; } else { _curParent->toParent(_right); return _curParent->equals(_rightParent); } return false; }
void DefaultRearrangement::resetStatus(TopSegmentIteratorConstPtr topSegment) { _id = Invalid; assert(topSegment.get()); _genome = topSegment->getTopSegment()->getGenome(); _parent = _genome->getParent(); assert(_parent != NULL); _cur->setLeft(topSegment); _next->copy(_cur); _left->copy(_cur); _right->copy(_left); assert(_cur->getGapThreshold() == _gapThreshold); assert(_next->getGapThreshold() == _gapThreshold); assert(_left->getGapThreshold() == _gapThreshold); assert(_right->getGapThreshold() == _gapThreshold); assert(_leftParent->getGapThreshold() == _gapThreshold); assert(_rightParent->getGapThreshold() == _gapThreshold); assert(_curParent->getGapThreshold() == _gapThreshold); assert(_cur->getAtomic() == _atomic); assert(_next->getAtomic() == _atomic); assert(_left->getAtomic() == _atomic); assert(_right->getAtomic() == _atomic); assert(_leftParent->getAtomic() == _atomic); assert(_rightParent->getAtomic() == _atomic); assert(_curParent->getAtomic() == _atomic); }
// leaves duplication on _cur and _right bool DefaultRearrangement::scanDuplicationCycle( TopSegmentIteratorConstPtr topSegment) { assert(topSegment.get()); resetStatus(topSegment); return _cur->hasNextParalogy() == true && _cur->isCanonicalParalog() == false; }
// Segment is an inverted descendant of another Segment but // otherwise no rearrangement. bool DefaultRearrangement::scanInversionCycle( TopSegmentIteratorConstPtr topSegment) { assert(topSegment.get()); resetStatus(topSegment); bool first = _cur->isFirst(); bool last = _cur->isLast(); if (_cur->hasParent() == false) { return false; } _curParent->toParent(_cur); if (first == false) { _left->toLeft(); if (_left->hasParent() == false) { return false; } _leftParent->toParent(_left); if (_leftParent->adjacentTo(_curParent) == false) { return false; } } if (last == false) { _right->toRight(); if (_right->hasParent() == false) { return false; } _rightParent->toParent(_right); if (_rightParent->adjacentTo(_curParent) == false) { return false; } } return _cur->getParentReversed(); }
// If true, _leftParent will store the deletion 'candidate' // It must be further verified that this segment has no child to // distinguish between source of transposition and deletion. bool DefaultRearrangement::scanDeletionCycle( TopSegmentIteratorConstPtr topSegment) { assert(topSegment.get()); resetStatus(topSegment); assert(_atomic != true || _cur->getNumSegments() == 1); bool first = _cur->isFirst(); bool last = _cur->isLast(); if (_cur->hasParent() == false || (first && last)) { return false; } // Case 1) current segment is a right endpoint. we consider delection // if parent has neighbour // FIXME: the edge cases are probably very wrong. if (last) { _leftParent->toParent(_cur); if (_leftParent->isFirst() == false) { _leftParent->toLeft(); return true; } if (_leftParent->isLast() == false) { _leftParent->toRight(); return true; } } // Case 2) Try to find deletion cycle by going right-up-left-left-down else { _rightParent->toParent(_cur); // FIXME: the edge cases are probably very wrong. if (first) { return false; } _left->toLeft(); assert(_rightParent->getGapThreshold() == _gapThreshold); assert(_cur->getGapThreshold() == _gapThreshold); assert(_atomic != true || _rightParent->getNumSegments() == 1); assert(_atomic != true || _left->getNumSegments() == 1); if (_left->hasParent() == false) { return false; } _leftParent->toParent(_left); if (_leftParent->getSequence() == _rightParent->getSequence()) { // don't care about inversions // so we make sure left is left of right and they are both positive if (_leftParent->getReversed() == true) { _leftParent->toReverse(); } if (_rightParent->getReversed() == true) { _rightParent->toReverse(); } if (_rightParent->getLeftArrayIndex() < _leftParent->getLeftArrayIndex()) { swap(_leftParent, _rightParent); } if (_leftParent->isLast()) { return false; } _leftParent->toRight(); return _leftParent->adjacentTo(_rightParent); } } return false; }
// If true, _cur will store the insertion 'candidate' // It must be further verified that this segment has no parent to // distinguish between destination of transposition and insertion. bool DefaultRearrangement::scanInsertionCycle( TopSegmentIteratorConstPtr topSegment) { assert(topSegment.get()); resetStatus(topSegment); // eat up any adjacent insertions so they don't get double counted while (_next->hasParent() == false && _next->isLast() == false) { _right->copy(_next); _right->toRight(); if (_right->hasParent() == false) { _next->copy(_right); } else { break; } } _right->copy(_next); assert(_next->equals(_cur) || _next->hasParent() == false); bool first = _cur->isFirst(); bool last = _right->isLast(); if (first && last) { return false; } // Case 1a) current segment is left endpoint. we consider insertion // if right neighbour has parent if (first) { _right->toRight(); if (_cur->hasParent() == false) { return true; } else if (_right->hasParent()) { _curParent->toParent(_cur); _rightParent->toParent(_right); return _rightParent->adjacentTo(_curParent) == false; } } // Case 1b) current segment is right endpoint. we consider insertion // if left neighbour has parent else if (last) { _left->toLeft(); if (_cur->hasParent() == false) { return true; } else if (_left->hasParent()) { _curParent->toParent(_cur); _leftParent->toParent(_left); return _leftParent->adjacentTo(_curParent) == false; } } // Case 2) current segment has a left neigbhour and a right neigbour else { _left->toLeft(); _right->toRight(); if (_left->hasParent() == true && _right->hasParent() == true) { _leftParent->toParent(_left); _rightParent->toParent(_right); // Case 2a) Parents are adjacent if (_leftParent->adjacentTo(_rightParent)) { return true; } // Case 2b) Left parent is endpoint else if (_leftParent->isFirst() || _leftParent->isLast()) { return _leftParent->getSequence() == _rightParent->getSequence(); } // Case 2c) Right parent is endpoint else if (_rightParent->isFirst() || _rightParent->isLast()) { return _leftParent->getSequence() == _rightParent->getSequence(); } } } return false; }
// Segment corresponds to no rearrangemnt. This will happen when // there is a rearrangement in the homolgous segment in its sibling // genome. In general, we can expect about half of segments to correspond // to such cases. bool DefaultRearrangement::scanNothingCycle( TopSegmentIteratorConstPtr topSegment) { assert(topSegment.get()); resetStatus(topSegment); bool first = _cur->isFirst(); bool last = _cur->isLast(); if (_cur->hasParent() == false) { return false; } _curParent->toParent(_cur); if (first == false) { _left->toLeft(); if (_left->hasParent() == false) { return false; } _leftParent->toParent(_left); if (_leftParent->adjacentTo(_curParent) == false) { return false; } if (_left->getParentReversed() == true) { if (_cur->getParentReversed() == false || _leftParent->rightOf(_curParent->getStartPosition()) == false) { return false; } } else { if (_cur->getParentReversed() == true || _leftParent->leftOf(_curParent->getStartPosition()) == false) { return false; } } } if (last == false) { _right->toRight(); if (_right->hasParent() == false) { return false; } _rightParent->toParent(_right); if (_rightParent->adjacentTo(_curParent) == false) { return false; } if (_right->getParentReversed() == true) { if (_cur->getParentReversed() == false || _rightParent->leftOf(_curParent->getStartPosition()) == false) { return false; } } else { if (_cur->getParentReversed() == true || _rightParent->rightOf(_curParent->getStartPosition()) == false) { return false; } } } return last && first ? _cur->getParentReversed() : true; }