cav_alndisplay.cpp
来自「ncbi源码」· C++ 代码 · 共 1,340 行 · 第 1/4 页
CPP
1,340 行
prevAligned = firstAligned; while (prevAligned < GetWidth()-2) { // find aligned res immediately followed by unaligned if (!(IsAligned(textRows[row]->GetCharAt(prevAligned)) && IsUnaligned(textRows[row]->GetCharAt(prevAligned + 1)))) { ++prevAligned; continue; } firstUnaligned = prevAligned + 1; // find last unaligned residue for (lastUnaligned = firstUnaligned; lastUnaligned < GetWidth()-1 && IsUnaligned(textRows[row]->GetCharAt(lastUnaligned + 1)); ++lastUnaligned) ; // find next aligned after this for (nextAligned = lastUnaligned + 1; nextAligned < GetWidth() && !IsAligned(textRows[row]->GetCharAt(nextAligned)); ++nextAligned) ; if (nextAligned == GetWidth()) break; // shift over the right half of the unaligned stretch nGaps = nextAligned - lastUnaligned - 1; nShift = (lastUnaligned - firstUnaligned + 1) / 2; if (nGaps > 0 && nShift > 0) { shiftRes = lastUnaligned; shiftGap = nextAligned - 1; for (i=0; i<nShift; ++i) { textRows[row]->SetCharAt(shiftGap - i, textRows[row]->GetCharAt(shiftRes - i)); textRows[row]->SetCharAt(shiftRes - i, '-'); } } prevAligned = nextAligned; } }}void AlignmentDisplay::InsertGaps(int nGaps, int beforePos){ int i; for (i=0; i<indexAlnLocToSeqLocRows.size(); ++i) indexAlnLocToSeqLocRows[i]->InsertGaps(nGaps, beforePos); for (i=0; i<textRows.size(); ++i) textRows[i]->InsertGaps(nGaps, beforePos);}char AlignmentDisplay::GetCharAt(int alnLoc, int row) const{ if (alnLoc < 0 || alnLoc >= GetWidth() || row < 0 || row >= GetNRows()) { ERR_POST(Error << "AlignmentDisplay::GetCharAt() - coordinate out of range"); return '?'; } return textRows[row]->GetCharAt(alnLoc);}class CondensedColumn : public CObject{protected: const string color; vector < int > info; CondensedColumn(int nRows, string columnColor) : color(columnColor) { info.resize(nRows, 0); }public: virtual ~CondensedColumn(void) { } string GetColor(void) const { return color; } virtual int GetDisplayWidth(void) const = 0; virtual int GetNResidues(int row) const = 0; virtual void DumpRow(CNcbiOstream& os, int row) const = 0; virtual void AddRowChar(int row, char ch) = 0;};class CondensedColumnAligned : public CondensedColumn{public: CondensedColumnAligned(int nRows, string color) : CondensedColumn(nRows, color) { } int GetDisplayWidth(void) const { return 1; } int GetNResidues(int row) const { return 1; } void DumpRow(CNcbiOstream& os, int row) const; void AddRowChar(int row, char ch);};void CondensedColumnAligned::DumpRow(CNcbiOstream& os, int row) const{ os << ((char) info[row]);}void CondensedColumnAligned::AddRowChar(int row, char ch){ info[row] = (int) ch;}class CondensedColumnUnaligned : public CondensedColumn{private: static const string prefix, postfix; int nDigits;public: CondensedColumnUnaligned(int nRows, string color) : CondensedColumn(nRows, color) { nDigits = 1; } int GetDisplayWidth(void) const { return prefix.size() + nDigits + postfix.size(); } int GetNResidues(int row) const { return info[row]; } void DumpRow(CNcbiOstream& os, int row) const; void AddRowChar(int row, char ch);};const string CondensedColumnUnaligned::prefix = ".[";const string CondensedColumnUnaligned::postfix = "].";void CondensedColumnUnaligned::DumpRow(CNcbiOstream& os, int row) const{ if (info[row] > 0) os << prefix << RIGHT_JUSTIFY << setw(nDigits) << info[row] << postfix; else os << setw(GetDisplayWidth()) << ' ';}void CondensedColumnUnaligned::AddRowChar(int row, char ch){ if (!IsGap(ch)) { (info[row])++; int digits = ((int) log10((double) info[row])) + 1; if (digits > nDigits) nDigits = digits; }}int AlignmentDisplay::DumpCondensed(CNcbiOstream& os, unsigned int options, int firstCol, int lastCol, int nColumns, double conservationThreshhold, const char *titleHTML, int nFeatures, const AlignmentFeature *alnFeatures) const{ bool doHTML = ((options & CAV_HTML) > 0), doHTMLHeader = ((options & CAV_HTML_HEADER) > 0); if (firstCol < 0 || lastCol >= GetWidth() || firstCol > lastCol || nColumns < 1) { ERR_POST(Error << "AlignmentDisplay::DumpText() - nonsensical display region parameters"); return CAV_ERROR_BAD_PARAMS; } // how many rows in the display, including annotations? int nDisplayRows = GetNRows(); if (!alnFeatures) nFeatures = 0; if (nFeatures > 0) nDisplayRows += nFeatures; // do make look-up location index for each feature vector < vector < bool > > annotLocsByIndex; int i, featIndex, masterIndex; if (nFeatures > 0) { annotLocsByIndex.resize(nFeatures); for (featIndex=0; featIndex<nFeatures; ++featIndex) { annotLocsByIndex[featIndex].resize(indexAlnLocToSeqLocRows[0]->sequence->Length(), false); for (i=0; i<alnFeatures[featIndex].nLocations; ++i) { masterIndex = alnFeatures[featIndex].locations[i]; if (masterIndex >= 0 && masterIndex < indexAlnLocToSeqLocRows[0]->sequence->Length()) annotLocsByIndex[featIndex][masterIndex] = true; } } } // condense the display into CondensedColumn list deque < CRef < CondensedColumn > > condensedColumns; int alnLoc, alnRow, row; bool isAlnRow; for (alnLoc=firstCol; alnLoc<=lastCol; ++alnLoc) { for (alnRow=0; alnRow<GetNRows(); ++alnRow) if (!IsAligned(textRows[alnRow]->GetCharAt(alnLoc))) break; bool alignedColumn = (alnRow == GetNRows()); if (alignedColumn) { condensedColumns.resize(condensedColumns.size() + 1); condensedColumns.back().Reset( new CondensedColumnAligned(nDisplayRows, GetColumnColor(alnLoc, conservationThreshhold))); } else { if (condensedColumns.size() == 0 || !(dynamic_cast<CondensedColumnUnaligned*>(condensedColumns.back().GetPointer()))) { condensedColumns.resize(condensedColumns.size() + 1); condensedColumns.back().Reset( new CondensedColumnUnaligned(nDisplayRows, GetColumnColor(alnLoc, conservationThreshhold))); } } for (row=0; row<nDisplayRows; ++row) { if (options & CAV_ANNOT_BOTTOM) { alnRow = row; featIndex = row - GetNRows(); } else { featIndex = row; alnRow = row - nFeatures; } isAlnRow = (alnRow >= 0 && alnRow < GetNRows()); if (isAlnRow) { condensedColumns.back()->AddRowChar(row, textRows[alnRow]->GetCharAt(alnLoc)); } else if (alignedColumn) { // display feature characters only in aligned columns masterIndex = indexAlnLocToSeqLocRows[0]->GetSeqLocAt(alnLoc); if (masterIndex >= 0 && annotLocsByIndex[featIndex][masterIndex]) condensedColumns.back()->AddRowChar(row, alnFeatures[featIndex].featChar); else condensedColumns.back()->AddRowChar(row, ' '); } } } // set up the titles and uids, figure out how much space any seqLoc string will take vector < string > titles(nDisplayRows), uids(doHTML ? GetNRows() : 0); int maxTitleLength = 0, maxSeqLocStrLength = 0, leftMargin, decimalLength; for (row=0; row<nDisplayRows; ++row) { if (options & CAV_ANNOT_BOTTOM) { alnRow = row; featIndex = row - GetNRows(); } else { featIndex = row; alnRow = row - nFeatures; } isAlnRow = (alnRow >= 0 && alnRow < GetNRows()); // title titles[row] = isAlnRow ? indexAlnLocToSeqLocRows[alnRow]->sequence->GetTitle() : string(alnFeatures[featIndex].shortName); if (titles[row].size() > maxTitleLength) maxTitleLength = titles[row].size(); if (isAlnRow) { decimalLength = ((int) log10((double) indexAlnLocToSeqLocRows[alnRow]->sequence->sequenceString.size())) + 1; if (decimalLength > maxSeqLocStrLength) maxSeqLocStrLength = decimalLength; } // uid for link to entrez if (doHTML && isAlnRow) { if (indexAlnLocToSeqLocRows[alnRow]->sequence->pdbID.size() > 0) { if (indexAlnLocToSeqLocRows[alnRow]->sequence->pdbID != "query" && indexAlnLocToSeqLocRows[alnRow]->sequence->pdbID != "consensus") { uids[alnRow] = indexAlnLocToSeqLocRows[alnRow]->sequence->pdbID; if (indexAlnLocToSeqLocRows[alnRow]->sequence->pdbChain != ' ') uids[alnRow] += (char) indexAlnLocToSeqLocRows[alnRow]->sequence->pdbChain; } } else if (indexAlnLocToSeqLocRows[alnRow]->sequence->gi != Sequence::NOT_SET) { CNcbiOstrstream uidoss; uidoss << indexAlnLocToSeqLocRows[alnRow]->sequence->gi << '\0'; uids[alnRow] = uidoss.str(); delete uidoss.str(); } else if (indexAlnLocToSeqLocRows[alnRow]->sequence->accession.size() > 0) { uids[alnRow] = indexAlnLocToSeqLocRows[alnRow]->sequence->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(GetNRows()); for (alnRow=0; alnRow<GetNRows(); ++alnRow) { lastShownSeqLocs[alnRow] = -1; for (alnLoc=0; alnLoc<firstCol; ++alnLoc) if (!IsGap(textRows[alnRow]->GetCharAt(alnLoc))) lastShownSeqLocs[alnRow]++; } // header if (doHTML && doHTMLHeader) os << "<HTML><TITLE>" << (titleHTML ? titleHTML : "CDDAlignView HTML Display") << "</TITLE><BODY BGCOLOR=" << bgColor << ">\n";; // split alignment up into "paragraphs", each with <= nColumns if (doHTML) os << "<TABLE>\n"; int paragraphStart, nParags = 0, nCondensedColumns; ERR_POST(Info << "paragraph width: " << nColumns); for (paragraphStart=0; paragraphStart<condensedColumns.size(); paragraphStart+=nCondensedColumns, ++nParags) { // figure out how many condensed columns will fit in this paragraph int displayWidth = condensedColumns[paragraphStart]->GetDisplayWidth(); nCondensedColumns = 1; while (paragraphStart+nCondensedColumns < condensedColumns.size()) { int columnWidth = condensedColumns[paragraphStart+nCondensedColumns]->GetDisplayWidth(); if (displayWidth + columnWidth <= nColumns) { displayWidth += columnWidth; ++nCondensedColumns; } else break; } // start table row if (doHTML) os << "<tr><td bgcolor=" << blockBGColors[nParags % nBlockColors] << "><pre>\n\n"; else if (paragraphStart > 0) os << '\n'; // output each alignment row for (row=0; row<nDisplayRows; ++row) { if (options & CAV_ANNOT_BOTTOM) { alnRow = row; featIndex = row - GetNRows(); } else { featIndex = row; alnRow = row - nFeatures; } isAlnRow = (alnRow >= 0 && alnRow < GetNRows()); // title if (isAlnRow && doHTML && uids[alnRow].size() > 0) { os << "<a href=\"http://www.ncbi.nlm.nih.gov/entrez/query.fcgi" << "?cmd=Search&doptcmdl=GenPept&db=Protein&term=" << uids[alnRow] << "\" onMouseOut=\"window.status=''\"\n" << "onMouseOver=\"window.status='" << ((indexAlnLocToSeqLocRows[alnRow]->sequence->description.size() > 0) ? indexAlnLocToSeqLocRows[alnRow]->sequence->description : titles[row]) << "';return true\">" << setw(0) << titles[row] << "</a>"; } else { if (doHTML && !isAlnRow) os << "<font color=" << featColor << '>'; os << setw(0) << titles[row]; } os << setw(maxTitleLength+1-titles[row].size()) << ' '; if (isAlnRow) { // count displayed residues int nDisplayedResidues = 0; for (i=0; i<nCondensedColumns; ++i) nDisplayedResidues += condensedColumns[paragraphStart+i]->GetNResidues(row); // left start pos (output 1-numbered for humans...) if (doHTML) os << "<font color=" << numColor << '>'; if (nDisplayedResidues > 0) os << RIGHT_JUSTIFY << setw(maxSeqLocStrLength) << (lastShownSeqLocs[alnRow]+2) << ' '; else os << RIGHT_JUSTIFY << setw(maxSeqLocStrLength) << ' ' << ' '; // dump sequence, applying color changes only when necessary if (doHTML) { string prevColor; for (i=0; i<nCondensedColumns; ++i) { string color = condensedColumns[paragraphStart+i]->GetColor();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?