📄 sequence_viewer.cpp
字号:
/* * =========================================================================== * PRODUCTION $Log: sequence_viewer.cpp,v $ * PRODUCTION Revision 1000.4 2004/06/01 18:29:12 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.67 * PRODUCTION * =========================================================================== *//* $Id: sequence_viewer.cpp,v 1000.4 2004/06/01 18:29:12 gouriano Exp $* ===========================================================================** PUBLIC DOMAIN NOTICE* National Center for Biotechnology Information** This software/database is a "United States Government Work" under the* terms of the United States Copyright Act. It was written as part of* the author's official duties as a United States Government employee and* thus cannot be copyrighted. This software/database is freely available* to the public for use. The National Library of Medicine and the U.S.* Government have not placed any restriction on its use or reproduction.** Although all reasonable efforts have been taken to ensure the accuracy* and reliability of the software and data, the NLM and the U.S.* Government do not and cannot warrant the performance or results that* may be obtained by using this software or data. The NLM and the U.S.* Government disclaim all warranties, express or implied, including* warranties of performance, merchantability or fitness for any particular* purpose.** Please cite the author in any work or product based on this material.** ===========================================================================** Authors: Paul Thiessen** File Description:* implementation of non-GUI part of main sequence/alignment viewer** ===========================================================================*/#ifdef _MSC_VER#pragma warning(disable:4018) // disable signed/unsigned mismatch warning in MSVC#endif#include <ncbi_pch.hpp>#include <corelib/ncbistd.hpp>#include <memory>#include "sequence_viewer.hpp"#include "sequence_viewer_window.hpp"#include "sequence_display.hpp"#include "messenger.hpp"#include "alignment_manager.hpp"#include "structure_set.hpp"#include "molecule_identifier.hpp"#include "cn3d_tools.hpp"#include "sequence_set.hpp"USING_NCBI_SCOPE;BEGIN_SCOPE(Cn3D)SequenceViewer::SequenceViewer(AlignmentManager *alnMgr) : // not sure why this cast is necessary, but MSVC requires it... ViewerBase(reinterpret_cast<ViewerWindowBase**>(&sequenceWindow), alnMgr), sequenceWindow(NULL){}SequenceViewer::~SequenceViewer(void){}void SequenceViewer::CreateSequenceWindow(bool showNow){ if (sequenceWindow) { sequenceWindow->Show(showNow); if (showNow) GlobalMessenger()->PostRedrawSequenceViewer(this); } else { SequenceDisplay *display = GetCurrentDisplay(); if (display) { sequenceWindow = new SequenceViewerWindow(this); sequenceWindow->NewDisplay(display, true); sequenceWindow->ScrollToColumn(display->GetStartingColumn()); sequenceWindow->Show(showNow); // ScrollTo causes immediate redraw, so don't need a second one GlobalMessenger()->UnPostRedrawSequenceViewer(this); } }}void SequenceViewer::SaveAlignment(void){ KeepCurrent(); // go back into the original pairwise alignment data and save according to the // current edited BlockMultipleAlignment and display row order vector < int > rowOrder; const SequenceDisplay *display = GetCurrentDisplay(); for (int i=0; i<display->rows.size(); ++i) { DisplayRowFromAlignment *alnRow = dynamic_cast<DisplayRowFromAlignment*>(display->rows[i]); if (alnRow) rowOrder.push_back(alnRow->row); } alignmentManager->SavePairwiseFromMultiple(GetCurrentAlignments().back(), rowOrder);}void SequenceViewer::DisplayAlignment(BlockMultipleAlignment *alignment){ SequenceDisplay *display = new SequenceDisplay(true, viewerWindow); for (int row=0; row<alignment->NRows(); ++row) display->AddRowFromAlignment(row, alignment); // set starting scroll to a few residues left of the first aligned block display->SetStartingColumn(alignment->GetFirstAlignedBlockPosition() - 5); AlignmentList alignments; alignments.push_back(alignment); InitData(&alignments, display); if (sequenceWindow) sequenceWindow->UpdateDisplay(display); else CreateSequenceWindow(false); // allow alignment export sequenceWindow->EnableExport(true);}void SequenceViewer::DisplaySequences(const SequenceList *sequenceList){ SequenceDisplay *display = new SequenceDisplay(false, viewerWindow); // populate each line of the display with one sequence, with blank lines inbetween SequenceList::const_iterator s, se = sequenceList->end(); for (s=sequenceList->begin(); s!=se; ++s) { // only do sequences from structure if this is a single-structure data file if (!(*s)->parentSet->IsMultiStructure() && (*s)->parentSet->objects.front()->mmdbID != (*s)->identifier->mmdbID) continue; if (display->NRows() > 0) display->AddRowFromString(""); // whole sequence on one row display->AddRowFromSequence(*s, 0, (*s)->Length() - 1); } InitData(NULL, display); if (sequenceWindow) sequenceWindow->UpdateDisplay(display); else CreateSequenceWindow(false); // forbid alignment export sequenceWindow->EnableExport(false);}void SequenceViewer::TurnOnEditor(void){ if (!sequenceWindow) CreateSequenceWindow(false); sequenceWindow->TurnOnEditor();}static void DumpFASTA(bool isA2M, const BlockMultipleAlignment *alignment, const vector < int >& rowOrder, BlockMultipleAlignment::eUnalignedJustification justification, CNcbiOstream& os){ // do whole alignment for now int firstCol = 0, lastCol = alignment->AlignmentWidth() - 1, nColumns = 70; if (firstCol < 0 || lastCol >= alignment->AlignmentWidth() || firstCol > lastCol || nColumns < 1) { ERRORMSG("DumpFASTA() - nonsensical display region parameters"); return; } // first fill out ids typedef map < const MoleculeIdentifier * , list < string > > IDMap; IDMap idMap; int row; bool anyRepeat = false; for (row=0; row<alignment->NRows(); ++row) { const Sequence *seq = alignment->GetSequenceOfRow(row); list < string >& titleList = idMap[seq->identifier]; CNcbiOstrstream oss; oss << '>'; if (titleList.size() == 0) { // create full title line for first instance of this sequence bool prevID = false; if (seq->identifier->gi != MoleculeIdentifier::VALUE_NOT_SET) { oss << "gi|" << seq->identifier->gi; prevID = true; } if (seq->identifier->pdbID.size() > 0) { if (prevID) oss << '|'; if (seq->identifier->pdbID == "query" || seq->identifier->pdbID == "consensus") { oss << "lcl|" << seq->identifier->pdbID; } else { oss << "pdb|" << seq->identifier->pdbID; if (seq->identifier->pdbChain != ' ') oss << '|' << (char) seq->identifier->pdbChain << " Chain " << (char) seq->identifier->pdbChain << ','; } prevID = true; } if (seq->identifier->accession.size() > 0) { if (prevID) oss << '|'; oss << seq->identifier->accession; prevID = true; } if (seq->description.size() > 0) oss << ' ' << seq->description; } else { // add repeat id oss << "lcl|instance #" << (titleList.size() + 1) << " of " << seq->identifier->ToString(); anyRepeat = true; } titleList.resize(titleList.size() + 1); oss << '\n' << '\0'; auto_ptr<char> data(oss.str()); titleList.back() = data.get(); } static const int eAllRepeats=0, eFakeRepeatIDs=1, eNoRepeats=2; int choice = eAllRepeats; if (anyRepeat) { wxArrayString choices; choices.Add("Include all repeats with normal IDs"); choices.Add("Include all repeats, but use unique IDs"); choices.Add("Include no repeated sequences"); choice = wxGetSingleChoiceIndex("How do you want to handle repeated sequences?", "Choose repeat type", choices); if (choice < 0) return; // cancelled } // output each alignment row (in order of the display) int paragraphStart, nParags = 0, i; char ch; Vector color, bgColor; bool highlighted, drawBG; for (row=0; row<alignment->NRows(); ++row) { const Sequence *seq = alignment->GetSequenceOfRow(rowOrder[row]); // output title list < string >& titleList = idMap[seq->identifier]; if (choice == eAllRepeats) { os << titleList.front(); // use full id } else if (choice == eFakeRepeatIDs) { os << titleList.front(); titleList.pop_front(); // move to next (fake) id } else if (choice == eNoRepeats) { if (titleList.size() > 0) { os << titleList.front(); titleList.clear(); // remove all ids after first instance } else { continue; } } // split alignment up into "paragraphs", each with nColumns for (paragraphStart=0; (firstCol+paragraphStart)<=lastCol; paragraphStart+=nColumns, ++nParags) { for (i=0; i<nColumns && (firstCol+paragraphStart+i)<=lastCol; ++i) { if (alignment->GetCharacterTraitsAt(firstCol+paragraphStart+i, rowOrder[row], justification, &ch, &color, &highlighted, &drawBG, &bgColor)) { if (ch == '~') os << (isA2M ? '.' : '-'); else os << (isA2M ? ch : (char) toupper(ch)); } else ERRORMSG("GetCharacterTraitsAt failed!"); } os << '\n'; } }}static void DumpText(bool doHTML, const BlockMultipleAlignment *alignment, const vector < int >& rowOrder, BlockMultipleAlignment::eUnalignedJustification justification, CNcbiOstream& os){#define LEFT_JUSTIFY resetiosflags(IOS_BASE::right) << setiosflags(IOS_BASE::left)#define RIGHT_JUSTIFY resetiosflags(IOS_BASE::left) << setiosflags(IOS_BASE::right) // do whole alignment for now int firstCol = 0, lastCol = alignment->AlignmentWidth() - 1, nColumns = 60; if (firstCol < 0 || lastCol >= alignment->AlignmentWidth() || firstCol > lastCol || nColumns < 1) { ERRORMSG("DumpText() - nonsensical display region parameters"); return; } // HTML colors static const string bgColor("#FFFFFF"), rulerColor("#700777"), numColor("#229922"); // set up the titles and uids, figure out how much space any seqLoc string will take vector < string > titles(alignment->NRows()), uids(doHTML ? alignment->NRows() : 0); int alnRow, row, maxTitleLength = 0, maxSeqLocStrLength = 0, leftMargin, decimalLength; for (alnRow=0; alnRow<alignment->NRows(); ++alnRow) { row = rowOrder[alnRow]; // translate display row -> data row const Sequence *sequence = alignment->GetSequenceOfRow(row); titles[row] = sequence->identifier->ToString(); if (titles[row].size() > maxTitleLength) maxTitleLength = titles[row].size(); decimalLength = ((int) log10((double) sequence->Length())) + 1; if (decimalLength > maxSeqLocStrLength) maxSeqLocStrLength = decimalLength; // uid for link to entrez if (doHTML) { // prefer gi's, since accessions can be outdated if (sequence->identifier->gi != MoleculeIdentifier::VALUE_NOT_SET) { CNcbiOstrstream uidoss; uidoss << sequence->identifier->gi << '\0'; uids[row] = uidoss.str(); delete uidoss.str(); } else if (sequence->identifier->pdbID.size() > 0) { if (sequence->identifier->pdbID != "query" && sequence->identifier->pdbID != "consensus") { uids[row] = sequence->identifier->pdbID; if (sequence->identifier->pdbChain != ' ') uids[row] += (char) sequence->identifier->pdbChain; } } else if (sequence->identifier->accession.size() > 0) { uids[row] = sequence->identifier->accession; } } } leftMargin = maxTitleLength + maxSeqLocStrLength + 2; // need to keep track of first, last seqLocs for each row in each paragraph; // find seqLoc of first residue >= firstCol vector < int > lastShownSeqLocs(alignment->NRows()); int alnLoc, i; char ch; Vector color, bgCol; bool highlighted, drawBG; for (alnRow=0; alnRow<alignment->NRows(); ++alnRow) { row = rowOrder[alnRow]; // translate display row -> data row lastShownSeqLocs[row] = -1; for (alnLoc=0; alnLoc<firstCol; ++alnLoc) { if (!alignment->GetCharacterTraitsAt(alnLoc, row, justification, &ch, &color, &highlighted, &drawBG, &bgCol)) ch = '~'; if (ch != '~') lastShownSeqLocs[row]++; } } // header if (doHTML) os << "<HTML><TITLE>Alignment Exported From Cn3D</TITLE>\n" << "<BODY BGCOLOR=" << bgColor << ">\n"; // split alignment up into "paragraphs", each with nColumns if (doHTML) os << "<TABLE>\n"; int paragraphStart, nParags = 0; for (paragraphStart=0; (firstCol+paragraphStart)<=lastCol; paragraphStart+=nColumns, ++nParags) { // start table row if (doHTML) os << "<tr><td><pre>\n"; else if (paragraphStart > 0) os << '\n'; // do ruler int nMarkers = 0, width; if (doHTML) os << "<font color=" << rulerColor << '>'; for (i=0; i<nColumns && (firstCol+paragraphStart+i)<=lastCol; ++i) { if ((paragraphStart+i+1)%10 == 0) { if (nMarkers == 0) width = leftMargin + i + 1; else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -