⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 block_multiple_alignment.cpp

📁 ncbi源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    if (to >= totalWidth) to = totalWidth - 1;    // find first residue within range    while (from <= to) {        GetSequenceAndIndexAt(from, row, justification, &sequence, &fromIndex, &ignored);        if (fromIndex >= 0) break;        ++from;    }    if (from > to) return;    // find last residue within range    while (to >= from) {        GetSequenceAndIndexAt(to, row, justification, &sequence, &toIndex, &ignored);        if (toIndex >= 0) break;        --to;    }    if (toggle)        GlobalMessenger()->ToggleHighlights(sequence, fromIndex, toIndex);    else        GlobalMessenger()->AddHighlights(sequence, fromIndex, toIndex);}void BlockMultipleAlignment::GetAlignedBlockPosition(int alignmentIndex,    int *blockColumn, int *blockWidth) const{    *blockColumn = *blockWidth = -1;    const BlockInfo& info = blockMap[alignmentIndex];    if (info.block->IsAligned()) {        *blockColumn = info.blockColumn;        *blockWidth = info.block->width;    }}Block * BlockMultipleAlignment::GetBlockBefore(const Block *block) const{    Block *prevBlock = NULL;    BlockList::const_iterator b, be = blocks.end();    for (b=blocks.begin(); b!=be; ++b) {        if (*b == block) break;        prevBlock = *b;    }    return prevBlock;}const UnalignedBlock * BlockMultipleAlignment::GetUnalignedBlockBefore(    const UngappedAlignedBlock *aBlock) const{    const Block *prevBlock;    if (aBlock)        prevBlock = GetBlockBefore(aBlock);    else        prevBlock = blocks.back();    return dynamic_cast<const UnalignedBlock*>(prevBlock);}Block * BlockMultipleAlignment::GetBlockAfter(const Block *block) const{    BlockList::const_iterator b, be = blocks.end();    for (b=blocks.begin(); b!=be; ++b) {        if (*b == block) {            ++b;            if (b == be) break;            return *b;        }    }    return NULL;}void BlockMultipleAlignment::InsertBlockBefore(Block *newBlock, const Block *insertAt){    BlockList::iterator b, be = blocks.end();    for (b=blocks.begin(); b!=be; ++b) {        if (*b == insertAt) {            blocks.insert(b, newBlock);            return;        }    }    WARNINGMSG("BlockMultipleAlignment::InsertBlockBefore() - couldn't find insertAt block");}void BlockMultipleAlignment::InsertBlockAfter(const Block *insertAt, Block *newBlock){    BlockList::iterator b, be = blocks.end();    for (b=blocks.begin(); b!=be; ++b) {        if (*b == insertAt) {            ++b;            blocks.insert(b, newBlock);            return;        }    }    WARNINGMSG("BlockMultipleAlignment::InsertBlockBefore() - couldn't find insertAt block");}void BlockMultipleAlignment::RemoveBlock(Block *block){    BlockList::iterator b, be = blocks.end();    for (b=blocks.begin(); b!=be; ++b) {        if (*b == block) {            delete *b;            blocks.erase(b);            InitCache();            return;        }    }    WARNINGMSG("BlockMultipleAlignment::RemoveBlock() - couldn't find block");}bool BlockMultipleAlignment::MoveBlockBoundary(int columnFrom, int columnTo){    int blockColumn, blockWidth;    GetAlignedBlockPosition(columnFrom, &blockColumn, &blockWidth);    if (blockColumn < 0 || blockWidth <= 0) return false;    TRACEMSG("trying to move block boundary from " << columnFrom << " to " << columnTo);    const BlockInfo& info = blockMap[columnFrom];    int row, requestedShift = columnTo - columnFrom, actualShift = 0;    const Block::Range *range;    // shrink block from left    if (blockColumn == 0 && requestedShift > 0 && requestedShift < info.block->width) {        actualShift = requestedShift;        TRACEMSG("shrinking block from left");        for (row=0; row<NRows(); ++row) {            range = info.block->GetRangeOfRow(row);            info.block->SetRangeOfRow(row, range->from + requestedShift, range->to);        }        info.block->width -= requestedShift;        Block *prevBlock = GetBlockBefore(info.block);        if (prevBlock && !prevBlock->IsAligned()) {            for (row=0; row<NRows(); ++row) {                range = prevBlock->GetRangeOfRow(row);                prevBlock->SetRangeOfRow(row, range->from, range->to + requestedShift);            }            prevBlock->width += requestedShift;        } else {            Block *newUnalignedBlock = CreateNewUnalignedBlockBetween(prevBlock, info.block);            if (newUnalignedBlock) InsertBlockBefore(newUnalignedBlock, info.block);            TRACEMSG("added new unaligned block");        }    }    // shrink block from right (requestedShift < 0)    else if (blockColumn == info.block->width - 1 &&                requestedShift < 0 && requestedShift > -info.block->width) {        actualShift = requestedShift;        TRACEMSG("shrinking block from right");        for (row=0; row<NRows(); ++row) {            range = info.block->GetRangeOfRow(row);            info.block->SetRangeOfRow(row, range->from, range->to + requestedShift);        }        info.block->width += requestedShift;        Block *nextBlock = GetBlockAfter(info.block);        if (nextBlock && !nextBlock->IsAligned()) {            for (row=0; row<NRows(); ++row) {                range = nextBlock->GetRangeOfRow(row);                nextBlock->SetRangeOfRow(row, range->from + requestedShift, range->to);            }            nextBlock->width -= requestedShift;        } else {            Block *newUnalignedBlock = CreateNewUnalignedBlockBetween(info.block, nextBlock);            if (newUnalignedBlock) InsertBlockAfter(info.block, newUnalignedBlock);            TRACEMSG("added new unaligned block");        }    }    // grow block to right    else if (blockColumn == info.block->width - 1 && requestedShift > 0) {        Block *nextBlock = GetBlockAfter(info.block);        if (nextBlock && !nextBlock->IsAligned()) {            int nRes;            actualShift = requestedShift;            for (row=0; row<NRows(); ++row) {                range = nextBlock->GetRangeOfRow(row);                nRes = range->to - range->from + 1;                if (nRes < actualShift) actualShift = nRes;            }            if (actualShift) {                TRACEMSG("growing block to right");                for (row=0; row<NRows(); ++row) {                    range = info.block->GetRangeOfRow(row);                    info.block->SetRangeOfRow(row, range->from, range->to + actualShift);                    range = nextBlock->GetRangeOfRow(row);                    nextBlock->SetRangeOfRow(row, range->from + actualShift, range->to);                }                info.block->width += actualShift;                nextBlock->width -= actualShift;                if (nextBlock->width == 0) {                    RemoveBlock(nextBlock);                    TRACEMSG("removed empty block");                }            }        }    }    // grow block to left (requestedShift < 0)    else if (blockColumn == 0 && requestedShift < 0) {        Block *prevBlock = GetBlockBefore(info.block);        if (prevBlock && !prevBlock->IsAligned()) {            int nRes;            actualShift = requestedShift;            for (row=0; row<NRows(); ++row) {                range = prevBlock->GetRangeOfRow(row);                nRes = range->to - range->from + 1;                if (nRes < -actualShift) actualShift = -nRes;            }            if (actualShift) {                TRACEMSG("growing block to left");                for (row=0; row<NRows(); ++row) {                    range = info.block->GetRangeOfRow(row);                    info.block->SetRangeOfRow(row, range->from + actualShift, range->to);                    range = prevBlock->GetRangeOfRow(row);                    prevBlock->SetRangeOfRow(row, range->from, range->to + actualShift);                }                info.block->width -= actualShift;                prevBlock->width += actualShift;                if (prevBlock->width == 0) {                    RemoveBlock(prevBlock);                    TRACEMSG("removed empty block");                }            }        }    }    if (actualShift != 0) {        UpdateBlockMapAndColors();        return true;    } else        return false;}bool BlockMultipleAlignment::ShiftRow(int row, int fromAlignmentIndex, int toAlignmentIndex,    eUnalignedJustification justification){    if (fromAlignmentIndex == toAlignmentIndex) return false;    Block        *blockFrom = blockMap[fromAlignmentIndex].block,        *blockTo = blockMap[toAlignmentIndex].block;    // at least one end of the drag must be in an aligned block    UngappedAlignedBlock *ABlock =        dynamic_cast<UngappedAlignedBlock*>(blockFrom);    if (ABlock) {        if (blockTo != blockFrom && blockTo->IsAligned()) return false;    } else {        ABlock = dynamic_cast<UngappedAlignedBlock*>(blockTo);        if (!ABlock) return false;    }    // and the other must be in the same aligned block or an adjacent unaligned block    UnalignedBlock        *prevUABlock = dynamic_cast<UnalignedBlock*>(GetBlockBefore(ABlock)),        *nextUABlock = dynamic_cast<UnalignedBlock*>(GetBlockAfter(ABlock));    if (blockFrom != blockTo &&        ((ABlock == blockFrom && prevUABlock != blockTo && nextUABlock != blockTo) ||         (ABlock == blockTo && prevUABlock != blockFrom && nextUABlock != blockFrom)))        return false;    int requestedShift, actualShift = 0, width = 0;    // slightly different behaviour when dragging from unaligned to aligned...    if (!blockFrom->IsAligned()) {        int fromSeqIndex, toSeqIndex;        GetSequenceAndIndexAt(fromAlignmentIndex, row, justification, NULL, &fromSeqIndex, NULL);        GetSequenceAndIndexAt(toAlignmentIndex, row, justification, NULL, &toSeqIndex, NULL);        if (fromSeqIndex < 0 || toSeqIndex < 0) return false;        requestedShift = toSeqIndex - fromSeqIndex;    }    // vs. dragging from aligned    else {        requestedShift = toAlignmentIndex - fromAlignmentIndex;    }    const Block::Range *prevRange = NULL, *nextRange = NULL,        *range = ABlock->GetRangeOfRow(row);    if (prevUABlock) prevRange = prevUABlock->GetRangeOfRow(row);    if (nextUABlock) nextRange = nextUABlock->GetRangeOfRow(row);    if (requestedShift > 0) {        if (prevUABlock) width = prevRange->to - prevRange->from + 1;        actualShift = (width > requestedShift) ? requestedShift : width;    } else {        if (nextUABlock) width = nextRange->to - nextRange->from + 1;        actualShift = (width > -requestedShift) ? requestedShift : -width;    }    if (actualShift == 0) return false;    TRACEMSG("shifting row " << row << " by " << actualShift);    ABlock->SetRangeOfRow(row, range->from - actualShift, range->to - actualShift);    if (prevUABlock) {        prevUABlock->SetRangeOfRow(row, prevRange->from, prevRange->to - actualShift);        prevUABlock->width = 0;        for (int i=0; i<NRows(); ++i) {            prevRange = prevUABlock->GetRangeOfRow(i);            width = prevRange->to - prevRange->from + 1;            if (width < 0) ERRORMSG("BlockMultipleAlignment::ShiftRow() - negative width on left");            if (width > prevUABlock->width) prevUABlock->width = width;        }        if (prevUABlock->width == 0) {            TRACEMSG("removing zero-width unaligned block on left");            RemoveBlock(prevUABlock);        }    } else {        TRACEMSG("creating unaligned block on left");        prevUABlock = CreateNewUnalignedBlockBetween(GetBlockBefore(ABlock), ABlock);        InsertBlockBefore(prevUABlock, ABlock);    }    if (nextUABlock) {        nextUABlock->SetRangeOfRow(row, nextRange->from - actualShift, nextRange->to);        nextUABlock->width = 0;        for (int i=0; i<NRows(); ++i) {            nextRange = nextUABlock->GetRangeOfRow(i);            width = nextRange->to - nextRange->from + 1;            if (width < 0) ERRORMSG("BlockMultipleAlignment::ShiftRow() - negative width on right");            if (width > nextUABlock->width) nextUABlock->width = width;        }        if (nextUABlock->width == 0) {            TRACEMSG("removing zero-width unaligned block on right");            RemoveBlock(nextUABlock);        }    } else {        TRACEMSG("creating unaligned block on right");        nextUABlock = CreateNewUnalignedBlockBetween(ABlock, GetBlockAfter(ABlock));        InsertBlockAfter(ABlock, nextUABlock);    }    if (!CheckAlignedBlock(ABlock))        ERRORMSG("BlockMultipleAlignment::ShiftRow() - shift failed to create valid aligned block");    UpdateBlockMapAndColors();    return true;}bool BlockMultipleAlignment::SplitBlock(int alignmentIndex){    const BlockInfo& info = blockMap[alignmentIndex];    if (!info.block->IsAligned() || info.block->width < 2 || info.blockColumn == 0)        return false;    TRACEMSG("splitting block");    UngappedAlignedBlock *newAlignedBlock = new UngappedAlignedBlock(this);    newAlignedBlock->width = info.block->width - info.blockColumn;    info.block->width = info.blockColumn;    const Block::Range *range;    int oldTo;    for (int row=0; row<NRows(); ++row) {        range = info.block->GetRangeOfRow(row);        oldTo = range->to;        info.block->SetRangeOfRow(row, range->from, range->from + info.block->width - 1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -