📄 update_viewer.cpp
字号:
/* * =========================================================================== * PRODUCTION $Log: update_viewer.cpp,v $ * PRODUCTION Revision 1000.3 2004/06/01 18:29:49 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.73 * PRODUCTION * =========================================================================== *//* $Id: update_viewer.cpp,v 1000.3 2004/06/01 18:29:49 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 update 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 <corelib/ncbistl.hpp>#include <objects/cdd/Cdd.hpp>#include <objects/cdd/Update_align.hpp>#include <objects/cdd/Update_comment.hpp>#include <objects/seq/Seq_annot.hpp>#include <objects/seq/Bioseq.hpp>#include <objects/seqset/Seq_entry.hpp>#include <objects/seqset/Bioseq_set.hpp>#include <objects/ncbimime/Ncbi_mime_asn1.hpp>#include <objects/ncbimime/Biostruc_seq.hpp>#include <objects/mmdb2/Model_type.hpp>#include <objects/mmdb2/Biostruc_model.hpp>#include <objects/mmdb1/Biostruc_graph.hpp>#include <objects/mmdb1/Biostruc_descr.hpp>#include <objects/general/Dbtag.hpp>#include <objects/general/Object_id.hpp>#include <objects/mmdb1/Biostruc_id.hpp>#include <objects/mmdb1/Mmdb_id.hpp>#include <objects/mmdb1/Biostruc_annot_set.hpp>#include <objects/mmdb3/Biostruc_feature_set.hpp>#include <objects/mmdb3/Chem_graph_alignment.hpp>#include <objects/mmdb3/Chem_graph_pntrs.hpp>#include <objects/mmdb3/Residue_pntrs.hpp>#include <objects/mmdb3/Residue_interval_pntr.hpp>#include <objects/mmdb1/Molecule_id.hpp>#include <objects/mmdb1/Residue_id.hpp>#include <objects/mmdb3/Biostruc_feature_set_id.hpp>#include <objects/mmdb3/Biostruc_feature_id.hpp>#include <memory>#include <algorithm>#include "update_viewer.hpp"#include "asn_reader.hpp"#include "update_viewer_window.hpp"#include "messenger.hpp"#include "sequence_display.hpp"#include "cn3d_colors.hpp"#include "alignment_manager.hpp"#include "cn3d_threader.hpp"#include "structure_set.hpp"#include "molecule.hpp"#include "cn3d_tools.hpp"#include "asn_converter.hpp"#include "cn3d_blast.hpp"#include "molecule_identifier.hpp"#include "cn3d_cache.hpp"#include "cn3d_ba_interface.hpp"#include <wx/tokenzr.h>// C stuff#include <stdio.h>#include <tofasta.h>#include <objseq.h>#include <objsset.h>USING_NCBI_SCOPE;USING_SCOPE(objects);BEGIN_SCOPE(Cn3D)UpdateViewer::UpdateViewer(AlignmentManager *alnMgr) : // not sure why this cast is necessary, but MSVC requires it... ViewerBase(reinterpret_cast<ViewerWindowBase**>(&updateWindow), alnMgr), updateWindow(NULL){ // when first created, start with blank display AlignmentList emptyAlignmentList; SequenceDisplay *blankDisplay = new SequenceDisplay(true, viewerWindow); InitData(&emptyAlignmentList, blankDisplay); EnableStacks();}UpdateViewer::~UpdateViewer(void){}void UpdateViewer::SetInitialState(void){ KeepCurrent(); EnableStacks();}void UpdateViewer::SaveDialog(bool prompt){ if (updateWindow) updateWindow->SaveDialog(prompt, false);}void UpdateViewer::CreateUpdateWindow(void){ if (updateWindow) { updateWindow->Show(true); GlobalMessenger()->PostRedrawSequenceViewer(this); } else { SequenceDisplay *display = GetCurrentDisplay(); if (display) { updateWindow = new UpdateViewerWindow(this); updateWindow->NewDisplay(display, false); updateWindow->ScrollToColumn(display->GetStartingColumn()); updateWindow->Show(true); // ScrollTo causes immediate redraw, so don't need a second one GlobalMessenger()->UnPostRedrawSequenceViewer(this); } }}void UpdateViewer::AddAlignments(const AlignmentList& newAlignments){ AlignmentList& alignments = GetCurrentAlignments(); SequenceDisplay *display = GetCurrentDisplay(); // populate successive lines of the display with each alignment, with blank lines inbetween AlignmentList::const_iterator a, ae = newAlignments.end(); int nViolations = 0; for (a=newAlignments.begin(); a!=ae; ++a) { if ((*a)->NRows() != 2) { ERRORMSG("UpdateViewer::AddAlignments() - got alignment with " << (*a)->NRows() << " rows"); continue; } // add alignment to stack list alignments.push_back(*a); // add alignment to the display, including block row since editor is always on if (display->NRows() != 0) display->AddRowFromString(""); display->AddBlockBoundaryRow(*a); for (int row=0; row<2; ++row) display->AddRowFromAlignment(row, *a); } if (alignments.size() > 0) display->SetStartingColumn(alignments.front()->GetFirstAlignedBlockPosition() - 5); Save(); // make this an undoable operation if (updateWindow) updateWindow->UpdateDisplay(display);}void UpdateViewer::ReplaceAlignments(const AlignmentList& alignmentList){ // empty out the current alignment list and display (but not the undo stacks!) DELETE_ALL_AND_CLEAR(GetCurrentAlignments(), AlignmentList); GetCurrentDisplay()->Empty(); AddAlignments(alignmentList);}void UpdateViewer::DeleteAlignment(BlockMultipleAlignment *toDelete){ AlignmentList keepAlignments; AlignmentList::const_iterator a, ae = GetCurrentAlignments().end(); for (a=GetCurrentAlignments().begin(); a!=ae; ++a) if (*a != toDelete) keepAlignments.push_back((*a)->Clone()); ReplaceAlignments(keepAlignments);}void UpdateViewer::SaveAlignments(void){ SetInitialState(); // construct a new list of ASN Update-aligns CCdd::TPending updates; map < CUpdate_align * , bool > usedUpdateAligns; AlignmentList::const_iterator a, ae = GetCurrentAlignments().end(); for (a=GetCurrentAlignments().begin(); a!=ae; ++a) { // create a Seq-align (with Dense-diags) out of this update if ((*a)->NRows() != 2) { ERRORMSG("CreateSeqAlignFromUpdate() - can only save pairwise updates"); continue; } BlockMultipleAlignment::UngappedAlignedBlockList blocks; (*a)->GetUngappedAlignedBlocks(&blocks); CSeq_align *newSeqAlign = CreatePairwiseSeqAlignFromMultipleRow(*a, blocks, 1); if (!newSeqAlign) continue; // the Update-align and Seq-annot's list of Seq-aligns where this new Seq-align will go CUpdate_align *updateAlign = (*a)->updateOrigin.GetPointer(); CSeq_annot::C_Data::TAlign *seqAlignList = NULL; // if this alignment came from an existing Update-align, then replace just the Seq-align // so that the rest of the Update-align's comments/annotations are preserved if (updateAlign) { if (!updateAlign->IsSetSeqannot() || !updateAlign->GetSeqannot().GetData().IsAlign()) { ERRORMSG("UpdateViewer::SaveAlignments() - confused by Update-align format"); continue; } } // if this is a new update, create a new Update-align and tag it else { updateAlign = new CUpdate_align(); // set type field depending on whether demoted sequence has structure updateAlign->SetType((*a)->GetSequenceOfRow(1)->molecule ? CUpdate_align::eType_demoted_3d : CUpdate_align::eType_demoted); // add a text comment CUpdate_comment *comment = new CUpdate_comment(); comment->SetComment("Created by demotion or import in Cn3D 4.0"); updateAlign->SetDescription().resize(updateAlign->GetDescription().size() + 1); updateAlign->SetDescription().back().Reset(comment); // create a new Seq-annot CRef < CSeq_annot > seqAnnotRef(new CSeq_annot()); seqAnnotRef->SetData().SetAlign(); updateAlign->SetSeqannot(*seqAnnotRef); } // get Seq-align list if (!updateAlign || !(seqAlignList = &(updateAlign->SetSeqannot().SetData().SetAlign()))) { ERRORMSG("UpdateViewer::SaveAlignments() - can't find Update-align and/or Seq-align list"); continue; } // if this is the first re-use of this Update-align, then empty out all existing // Seq-aligns and push it onto the new update list if (usedUpdateAligns.find(updateAlign) == usedUpdateAligns.end()) { seqAlignList->clear(); updates.resize(updates.size() + 1); updates.back().Reset(updateAlign); usedUpdateAligns[updateAlign] = true; } // finally, add the new Seq-align to the list seqAlignList->resize(seqAlignList->size() + 1); seqAlignList->back().Reset(newSeqAlign); } // save these changes to the ASN data alignmentManager->ReplaceUpdatesInASN(updates);}const Sequence * UpdateViewer::GetMasterSequence(void) const{ const Sequence *master = NULL; // if there's a multiple alignment in the sequence viewer, use same master as that if (alignmentManager->GetCurrentMultipleAlignment()) { master = alignmentManager->GetCurrentMultipleAlignment()->GetMaster(); } // if there's already an update present, use same master as that else if (GetCurrentAlignments().size() > 0) { master = GetCurrentAlignments().front()->GetMaster(); } // otherwise, this must be a single structure with no updates, so we need to pick one of its // chains as the new master else { vector < const Sequence * > chains; if (alignmentManager->GetStructureProteins(&chains)) { if (chains.size() == 1) { master = chains[0]; } else { wxString *titles = new wxString[chains.size()]; int choice; for (choice=0; choice<chains.size(); ++choice) titles[choice] = chains[choice]->identifier->ToString().c_str(); choice = wxGetSingleChoiceIndex("Align to which protein chain?", "Select Chain", chains.size(), titles); if (choice >= 0) master = chains[choice]; else // cancelled return NULL; } } } if (!master) ERRORMSG("UpdateViewer::GetMasterSequence() - no master sequence defined"); return master;}void UpdateViewer::FetchSequencesViaHTTP(SequenceList *newSequences, StructureSet *sSet) const{ wxString ids = wxGetTextFromUser("Enter a list of protein GIs or Accessions:", "Input Identifier", "", *viewerWindow); if (ids.size() == 0) return; wxStringTokenizer tkz(ids, " ,;\t\r\n", wxTOKEN_STRTOK); while (tkz.HasMoreTokens()) { wxString id = tkz.GetNextToken(); CRef < CBioseq > bioseq = FetchSequenceViaHTTP(id.c_str()); const Sequence *sequence = sSet->CreateNewSequence(*bioseq); if (sequence) { if (sequence->isProtein) newSequences->push_back(sequence); else ERRORMSG("The sequence must be a protein"); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -