NCBI C++ ToolKit
sequence_display.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: sequence_display.cpp 57770 2013-04-11 16:25:32Z thiessen $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Authors: Paul Thiessen
27 *
28 * File Description:
29 * Classes to hold rows in a sequence/alignment display
30 *
31 * ===========================================================================
32 */
33 
34 #include <ncbi_pch.hpp>
35 #include <corelib/ncbistd.hpp>
36 #include <corelib/ncbistl.hpp>
37 #include <corelib/ncbistre.hpp>
38 #include <corelib/ncbi_limits.h>
39 
40 #include <algorithm>
41 
43 
44 #include "sequence_display.hpp"
45 #include "viewer_window_base.hpp"
46 #include "viewer_base.hpp"
47 #include "molecule.hpp"
48 #include "messenger.hpp"
49 #include "structure_set.hpp"
50 #include "style_manager.hpp"
52 #include "sequence_viewer.hpp"
53 #include "alignment_manager.hpp"
54 #include "cn3d_colors.hpp"
55 #include "update_viewer.hpp"
56 #include "update_viewer_window.hpp"
57 #include "cn3d_tools.hpp"
58 #include "cn3d_threader.hpp"
59 #include "conservation_colorer.hpp"
60 #include "molecule_identifier.hpp"
61 #include "cn3d_blast.hpp"
62 
64 
65 
66 BEGIN_SCOPE(Cn3D)
67 
68 // block marker string stuff
69 static const char
74 static const string blockBoundaryStringTitle("(blocks)");
75 
76 // color converter
77 static inline void Vector2wxColor(const Vector& colorVec, wxColor *colorWX)
78 {
79  colorWX->Set(
80  static_cast<unsigned char>((colorVec[0] + 0.000001) * 255),
81  static_cast<unsigned char>((colorVec[1] + 0.000001) * 255),
82  static_cast<unsigned char>((colorVec[2] + 0.000001) * 255)
83  );
84 }
85 
86 
87 ////////////////////////////////////////////////////////////////////////////////
88 // The sequence view is composed of rows which can be from sequence, alignment,
89 // or any string - anything derived from DisplayRow, implemented below.
90 ////////////////////////////////////////////////////////////////////////////////
91 
93  unsigned int column, BlockMultipleAlignment::eUnalignedJustification justification,
94  char *character, Vector *color,
95  bool *drawBackground, Vector *cellBackgroundColor) const
96 {
97  bool isHighlighted,
99  column, row, justification, character, color,
100  &isHighlighted, drawBackground, cellBackgroundColor);
101 
102  // always apply highlight color, even if alignment has set its own background color
103  if (isHighlighted) {
104  *drawBackground = true;
105  *cellBackgroundColor = GlobalColors()->Get(Colors::eHighlight);
106  }
107 
108  return result;
109 }
110 
111 DisplayRowFromSequence::DisplayRowFromSequence(const Sequence *s, unsigned int from, unsigned int to) :
112  sequence(s), fromIndex(from), toIndex(to)
113 {
114  if (from >= sequence->Length() || from > to || to >= sequence->Length())
115  ERRORMSG("DisplayRowFromSequence::DisplayRowFromSequence() - from/to indexes out of range");
116 }
117 
119  unsigned int column, BlockMultipleAlignment::eUnalignedJustification justification,
120  char *character, Vector *color, bool *drawBackground, Vector *cellBackgroundColor) const
121 {
122  unsigned int index = column + fromIndex;
123  if (index > toIndex)
124  return false;
125 
126  *character = tolower((unsigned char) sequence->sequenceString[index]);
127  if (sequence->molecule)
129  else
130  color->Set(0,0,0);
131  if (GlobalMessenger()->IsHighlighted(sequence, index)) {
132  *drawBackground = true;
133  *cellBackgroundColor = GlobalColors()->Get(Colors::eHighlight);
134  } else {
135  *drawBackground = false;
136  }
137 
138  return true;
139 }
140 
142  unsigned int column, BlockMultipleAlignment::eUnalignedJustification justification,
143  const Sequence **sequenceHandle, int *seqIndex) const
144 {
145  unsigned int index = column + fromIndex;
146  if (index > toIndex)
147  return false;
148 
149  *sequenceHandle = sequence;
150  *seqIndex = index;
151  return true;
152 }
153 
154 void DisplayRowFromSequence::SelectedRange(unsigned int from, unsigned int to,
155  BlockMultipleAlignment::eUnalignedJustification justification, bool toggle) const
156 {
157  from += fromIndex;
158  to += fromIndex;
159 
160  // skip if selected outside range
161  if (from < fromIndex && to < fromIndex) return;
162  if (from > toIndex && to > toIndex) return;
163 
164  // trim to within range
165  if (from < fromIndex) from = fromIndex;
166  else if (from > toIndex) from = toIndex;
167  if (to < fromIndex) to = fromIndex;
168  else if (to > toIndex) to = toIndex;
169 
170  if (toggle)
172  else
173  GlobalMessenger()->AddHighlights(sequence, from, to);
174 }
175 
178  char *character, Vector *color, bool *drawBackground, Vector *cellBackgroundColor) const
179 {
180  if (column >= theString.size()) return false;
181 
182  *character = theString[column];
183  *color = stringColor;
184 
185  if (hasBackgroundColor) {
186  *drawBackground = true;
187  *cellBackgroundColor = backgroundColor;
188  } else {
189  *drawBackground = false;
190  }
191  return true;
192 }
193 
194 
195 ////////////////////////////////////////////////////////////////////////////////
196 // The SequenceDisplay is the structure that holds the DisplayRows of the view.
197 // It's also derived from ViewableAlignment, in order to be plugged into a
198 // SequenceDisplayWidget.
199 ////////////////////////////////////////////////////////////////////////////////
200 
201 SequenceDisplay::SequenceDisplay(bool editable, ViewerWindowBase* const *parentViewerWindow) :
202  isEditable(editable), viewerWindow(parentViewerWindow), startingColumn(0), maxRowWidth(0)
203 {
204 }
205 
207 {
208  for (unsigned int i=0; i<rows.size(); ++i) delete rows[i];
209 }
210 
212 {
213  for (unsigned int i=0; i<rows.size(); ++i) delete rows[i];
214  rows.clear();
216 }
217 
218 
220 {
222  for (unsigned int row=0; row<rows.size(); ++row)
223  copy->rows.push_back(rows[row]->Clone(newAlignments));
224  copy->startingColumn = startingColumn;
225  copy->maxRowWidth = maxRowWidth;
226  return copy;
227 }
228 
230 {
231  rows.push_back(row);
232  if (row->Width() > maxRowWidth) maxRowWidth = row->Width();
233 }
234 
236 {
237  if (row >= rows.size()) return NULL;
238  const DisplayRowFromAlignment *displayRow = dynamic_cast<const DisplayRowFromAlignment*>(rows[row]);
239  if (displayRow) return displayRow->alignment;
240  const DisplayRowFromString *stringRow = dynamic_cast<const DisplayRowFromString*>(rows[row]);
241  if (stringRow) return stringRow->alignment;
242  return NULL;
243 }
244 
246 {
247  RowVector::iterator r, re = rows.end();
248  maxRowWidth = 0;
249  for (r=rows.begin(); r!=re; ++r)
250  if ((*r)->Width() > maxRowWidth) maxRowWidth = (*r)->Width();
251 }
252 
254 {
255  if (!fromAlignment || row >= fromAlignment->NRows()) {
256  ERRORMSG("SequenceDisplay::AddRowFromAlignment() failed");
257  return;
258  }
259 
260  AddRow(new DisplayRowFromAlignment(row, fromAlignment));
261 }
262 
263 void SequenceDisplay::AddRowFromSequence(const Sequence *sequence, unsigned int from, unsigned int to)
264 {
265  if (!sequence) {
266  ERRORMSG("SequenceDisplay::AddRowFromSequence() failed");
267  return;
268  }
269 
270  AddRow(new DisplayRowFromSequence(sequence, from, to));
271 }
272 
273 void SequenceDisplay::AddRowFromString(const string& anyString)
274 {
275  AddRow(new DisplayRowFromString(anyString));
276 }
277 
278 bool SequenceDisplay::GetRowTitle(unsigned int row, wxString *title, wxColour *color) const
279 {
280  const DisplayRow *displayRow = rows[row];
281 
282  const DisplayRowFromString *strRow = dynamic_cast<const DisplayRowFromString*>(displayRow);
283  if (strRow && !strRow->title.empty()) {
284  *title = strRow->title.c_str();
285  color->Set(0,0,0); // black
286  return true;
287  }
288 
289  const Sequence *sequence = displayRow->GetSequence();
290  if (!sequence) return false;
291 
292  // set title
293  *title = sequence->identifier->ToString().c_str();
294 
295  // set color - by object if there's an associated molecule
296  const DisplayRowFromAlignment *alnRow = dynamic_cast<const DisplayRowFromAlignment*>(displayRow);
297  const Molecule *molecule;
298  if (alnRow && (molecule=alnRow->alignment->GetSequenceOfRow(alnRow->row)->molecule) != NULL)
299  Vector2wxColor(molecule->parentSet->styleManager->GetObjectColor(molecule), color);
300  else
301  color->Set(0,0,0); // ... black otherwise
302 
303  return true;
304 }
305 
306 bool SequenceDisplay::GetCharacterTraitsAt(unsigned int column, unsigned int row,
307  char *character, wxColour *color, bool *drawBackground,
308  wxColour *cellBackgroundColor) const
309 {
310  if (row >= rows.size()) {
311  WARNINGMSG("SequenceDisplay::GetCharacterTraitsAt() - row out of range");
312  return false;
313  }
314 
315  const DisplayRow *displayRow = rows[row];
316 
317  if (column >= displayRow->Width())
318  return false;
319 
320  Vector colorVec, bgColorVec;
321  if (!displayRow->GetCharacterTraitsAt(column,
322  (*viewerWindow) ? (*viewerWindow)->GetCurrentJustification() : BlockMultipleAlignment::eLeft,
323  character, &colorVec, drawBackground, &bgColorVec))
324  return false;
325 
326  Vector2wxColor(colorVec, color);
327  if (*drawBackground) Vector2wxColor(bgColorVec, cellBackgroundColor);
328  return true;
329 }
330 
332 {
333  if (*viewerWindow) {
334  wxString idLoc, status;
335 
336  if (row >= 0 && row < (int)rows.size()) {
337  const DisplayRow *displayRow = rows[row];
338  const Sequence *sequence = NULL;
339 
340  // show id if we're in sequence area
341  if (column >= 0 && column < (int)displayRow->Width()) {
342 
343  // show title and seqloc
344  int index = -1;
345  if (displayRow->GetSequenceAndIndexAt(column,
346  (*viewerWindow)->GetCurrentJustification(), &sequence, &index)) {
347  if (index >= 0) {
348  wxString title;
349  wxColour color;
350  if (GetRowTitle(row, &title, &color))
351  idLoc.Printf("%s, loc %i", title.c_str(), index + 1); // show one-based numbering
352  }
353  }
354 
355  // show PDB residue number if available (assume resID = index+1)
356  if (sequence && index >= 0 && sequence->molecule) {
357  const Residue *residue = sequence->molecule->residues.find(index + 1)->second;
358  if (residue && residue->namePDB.size() > 0) {
359  wxString n = residue->namePDB.c_str();
360  n = n.Strip(wxString::both);
361  if (n.size() > 0)
362  idLoc = idLoc + " (PDB " + n + ")";
363  }
364  }
365 
366  // show alignment block number and row-wise string
367  const DisplayRowFromAlignment *alnRow =
368  dynamic_cast<const DisplayRowFromAlignment *>(displayRow);
369  if (alnRow) {
370  int blockNum = alnRow->alignment->GetAlignedBlockNumber(column);
371  int rowNum = 0;
372  // get apparent row number (crude!)
373  for (int r=0; r<=row; ++r) {
374  const DisplayRowFromAlignment *aRow =
375  dynamic_cast<const DisplayRowFromAlignment *>(rows[r]);
376  if (aRow && aRow->alignment == alnRow->alignment) ++rowNum;
377  }
378  if (blockNum > 0)
379  status.Printf("Block %i, Row %i", blockNum, rowNum);
380  else
381  status.Printf("Row %i", rowNum);
382  if (alnRow->alignment->GetRowStatusLine(alnRow->row).size() > 0) {
383  status += " ; ";
384  status += alnRow->alignment->GetRowStatusLine(alnRow->row).c_str();
385  }
386  }
387  }
388 
389  // else show length and description if we're in the title area
390  else if (column < 0) {
391  sequence = displayRow->GetSequence();
392  if (sequence) {
393  idLoc.Printf("length %i", sequence->Length());
394  status = sequence->GetDescription().c_str();
395  }
396  }
397  }
398 
399  (*viewerWindow)->SetStatusText(idLoc, 0);
400  (*viewerWindow)->SetStatusText(status, 1);
401  }
402 }
403 
405 {
406  UpdateBlockBoundaryRow(forAlignment);
407  UpdateMaxRowWidth(); // in case alignment width has changed
408  (*viewerWindow)->viewer->Save(); // make undoable
409  (*viewerWindow)->UpdateDisplay(this);
410  if ((*viewerWindow)->AlwaysSyncStructures())
411  (*viewerWindow)->SyncStructures();
412 }
413 
414 bool SequenceDisplay::MouseDown(int column, int row, unsigned int controls)
415 {
416  TRACEMSG("got MouseDown at col:" << column << " row:" << row);
417 
418  // process events in title area (launch of browser for entrez page on a sequence)
419  if (column < 0 && row >= 0 && row < (int)NRows()) {
420  const Sequence *seq = rows[row]->GetSequence();
421  if (seq) seq->LaunchWebBrowserWithInfo();
422  return false;
423  }
424 
425  // check special keys
426  shiftDown = ((controls & ViewableAlignment::eShiftDown) > 0);
427  controlDown = ((controls &
428 #ifdef __WXMAC__
429  // on Mac, can't do ctrl-clicks, so use meta instead
431 #else
433 #endif
434  ) > 0);
435 
436  // clear highlights if ctrl-click is in whitespace below alignment
437  if (controlDown && !shiftDown && column == -1)
439 
440  // process events in sequence area
442  if (alignment && column >= 0) {
443 
444  // operations for any viewer window
445  if ((*viewerWindow)->DoSplitBlock()) {
446  if (alignment->SplitBlock(column)) {
447  if (!controlDown) (*viewerWindow)->SplitBlockOff();
448  UpdateAfterEdit(alignment);
449  }
450  return false;
451  }
452 
453  if ((*viewerWindow)->DoDeleteBlock()) {
454  if (alignment->DeleteBlock(column)) {
455  if (!controlDown) (*viewerWindow)->DeleteBlockOff();
456  UpdateAfterEdit(alignment);
457  }
458  return false;
459  }
460 
461  // operations specific to the sequence window
462  SequenceViewerWindow *sequenceWindow = dynamic_cast<SequenceViewerWindow*>(*viewerWindow);
463  if (sequenceWindow && row >= 0) {
464 
465  if (sequenceWindow->DoRestrictHighlights()) {
466  DisplayRowFromAlignment *selectedRow = dynamic_cast<DisplayRowFromAlignment*>(rows[row]);
467  if (selectedRow) {
469  sequenceWindow->RestrictHighlightsOff();
470  }
471  return false;
472  }
473 
474  if (sequenceWindow->DoMarkBlock()) {
475  if (alignment->MarkBlock(column)) {
476  if (!controlDown) sequenceWindow->MarkBlockOff();
478  }
479  return false;
480  }
481 
482  if (sequenceWindow->DoProximitySort()) {
483  if (ProximitySort(row)) {
484  sequenceWindow->ProximitySortOff();
486  }
487  return false;
488  }
489 
490  if (sequenceWindow->DoSortLoops()) {
492  sequenceWindow->SortLoopsOff();
494  }
495  return false;
496  }
497 
498  if (sequenceWindow->DoRealignRow() || sequenceWindow->DoDeleteRow()) {
499  DisplayRowFromAlignment *selectedRow = dynamic_cast<DisplayRowFromAlignment*>(rows[row]);
500  if (!selectedRow || selectedRow->row == 0 || !selectedRow->alignment) {
501  WARNINGMSG("Can't delete/realign that row...");
502  return false;
503  }
504 
505  if (sequenceWindow->DoRealignRow()) {
506  vector < unsigned int > selectedDependents(1);
507  selectedDependents[0] = selectedRow->row;
508  sequenceWindow->sequenceViewer->alignmentManager->RealignDependentSequences(alignment, selectedDependents);
509  if (!controlDown) sequenceWindow->RealignRowOff();
510  return false;
511  }
512 
513  if (sequenceWindow->DoDeleteRow()) {
514  if (alignment->NRows() <= 2) {
515  WARNINGMSG("Can't delete that row...");
516  return false;
517  }
518 
519  // in case we need to redraw molecule associated with removed row
520  const Molecule *molecule = alignment->GetSequenceOfRow(selectedRow->row)->molecule;
521 
522  // delete row based on alignment row # (not display row #); redraw molecule
523  if (alignment->DeleteRow(selectedRow->row)) {
524 
525  // delete this row from the display, and update higher row #'s
526  RowVector::iterator r, re = rows.end(), toDelete;
527  for (r=rows.begin(); r!=re; ++r) {
529  *currentARow = dynamic_cast<DisplayRowFromAlignment*>(*r);
530  if (!currentARow)
531  continue;
532  else if (currentARow->row > selectedRow->row)
533  (currentARow->row)--;
534  else if (currentARow == selectedRow)
535  toDelete = r;
536  }
537  delete *toDelete;
538  rows.erase(toDelete);
539 
540  if (!controlDown) sequenceWindow->DeleteRowOff();
541  UpdateAfterEdit(alignment);
542  if (molecule && sequenceWindow->AlwaysSyncStructures())
543  GlobalMessenger()->PostRedrawMolecule(molecule);
544  }
545  return false;
546  }
547  }
548  }
549 
550  // operations specific to the update window
551  UpdateViewerWindow *updateWindow = dynamic_cast<UpdateViewerWindow*>(*viewerWindow);
552  if (updateWindow && row >= 0) {
553 
554  // delete all blocks
555  if (updateWindow->DoDeleteAllBlocks()) {
556  if (alignment->DeleteAllBlocks()) {
557  if (!controlDown) updateWindow->DeleteAllBlocksOff();
558  UpdateAfterEdit(alignment);
559  }
560  return false;
561  }
562 
563  // thread single
564  if (updateWindow->DoThreadSingle()) {
566  ERRORMSG("Can't run threader without existing core alignment");
567  return false;
568  }
569  // get threader options
572  alignment);
573  ThreaderOptionsDialog optDialog(updateWindow, globalThreaderOptions);
574  if (optDialog.ShowModal() == wxCANCEL) return false; // user cancelled
575  if (!optDialog.GetValues(&globalThreaderOptions)) {
576  ERRORMSG("Error retrieving options values from dialog");
577  return false;
578  }
580  updateWindow->ThreadSingleOff();
581  return false;
582  }
583 
584  // BLAST single
585  if (updateWindow->DoBlastSingle()) {
586  updateWindow->updateViewer->BlastUpdate(alignment, false);
587  if (!controlDown) updateWindow->BlastSingleOff();
588  return false;
589  }
590 
591  // BLAST/PSSM single
592  if (updateWindow->DoBlastPSSMSingle()) {
593  updateWindow->updateViewer->BlastUpdate(alignment, true);
594  if (!controlDown) updateWindow->BlastPSSMSingleOff();
595  return false;
596  }
597 
598  // BLAST neighbor single
599  if (updateWindow->DoBlastNeighborSingle()) {
600  updateWindow->updateViewer->BlastNeighbor(alignment);
601  if (!controlDown) updateWindow->BlastNeighborSingleOff();
602  return false;
603  }
604 
605  // Block align single
606  if (updateWindow->DoBlockAlignSingle()) {
607  updateWindow->updateViewer->alignmentManager->BlockAlignUpdate(alignment);
608  if (!controlDown) updateWindow->BlockAlignSingleOff();
609  return false;
610  }
611 
612  // Block extend single
613  if (updateWindow->DoExtendSingle()) {
614  updateWindow->updateViewer->alignmentManager->ExtendUpdate(alignment);
615  if (!controlDown) updateWindow->ExtendSingleOff();
616  return false;
617  }
618 
619  // set region (on dependent sequence)
620  if (updateWindow->DoSetRegion()) {
621  // dialog uses 1-based sequence locations
622  RegionDialog dialog(updateWindow,
623  alignment->GetSequenceOfRow(1), alignment->alignDependentFrom + 1, alignment->alignDependentTo + 1);
624  if (dialog.ShowModal() == wxOK) {
625  int from, to;
626  if (!dialog.GetValues(&from, &to)) {
627  ERRORMSG("RegionDialog returned OK, but values invalid");
628  } else {
629  TRACEMSG("set region (dependent): " << from << " to " << to);
630  alignment->alignDependentFrom = from - 1;
631  alignment->alignDependentTo = to - 1;
632  }
633  if (!controlDown) updateWindow->SetRegionOff();
634  }
635  return false;
636  }
637 
638  // merge single
639  if (updateWindow->DoMergeSingle()) {
641  single[alignment] = true;
642  updateWindow->updateViewer->alignmentManager->MergeUpdates(single, false);
643  if (!controlDown) updateWindow->MergeSingleOff();
644  return false;
645  }
646 
647  // merge neighbor
648  if (updateWindow->DoMergeNeighbor()) {
650  single[alignment] = true;
651  updateWindow->updateViewer->alignmentManager->MergeUpdates(single, true);
652  if (!controlDown) updateWindow->MergeNeighborOff();
653  return false;
654  }
655 
656  // delete single
657  if (updateWindow->DoDeleteSingle()) {
658  updateWindow->updateViewer->DeleteAlignment(alignment);
659  if (!controlDown) updateWindow->DeleteSingleOff();
660  return false;
661  }
662  }
663  }
664 
665  return true;
666 }
667 
668 void SequenceDisplay::SelectedRectangle(int columnLeft, int rowTop,
669  int columnRight, int rowBottom)
670 {
671  TRACEMSG("got SelectedRectangle " << columnLeft << ',' << rowTop << " to "
672  << columnRight << ',' << rowBottom);
673 
675  (*viewerWindow)->GetCurrentJustification();
676 
677  BlockMultipleAlignment *alignment = GetAlignmentForRow(rowTop);
678  bool singleAlignment = (alignment && alignment == GetAlignmentForRow(rowBottom));
679  if (singleAlignment) {
680  if ((*viewerWindow)->DoMergeBlocks()) {
681  if (alignment->MergeBlocks(columnLeft, columnRight)) {
682  if (!controlDown) (*viewerWindow)->MergeBlocksOff();
683  UpdateAfterEdit(alignment);
684  }
685  return;
686  }
687  if ((*viewerWindow)->DoCreateBlock()) {
688  if (alignment->CreateBlock(columnLeft, columnRight, justification)) {
689  if (!controlDown) (*viewerWindow)->CreateBlockOff();
690  UpdateAfterEdit(alignment);
691  }
692  return;
693  }
694  }
695 
696  if (!shiftDown && !controlDown)
698 
699  if (singleAlignment && (*viewerWindow)->SelectBlocksIsOn()) {
700  alignment->SelectBlocks(columnLeft, columnRight, controlDown);
701  } else {
702  for (int i=rowTop; i<=rowBottom; ++i)
703  rows[i]->SelectedRange(columnLeft, columnRight, justification, controlDown); // toggle if control down
704  }
705 }
706 
707 void SequenceDisplay::DraggedCell(int columnFrom, int rowFrom,
708  int columnTo, int rowTo)
709 {
710  // special shift operations if shift/ctrl click w/ no drag
711  if (columnFrom == columnTo && rowFrom == rowTo) {
712  BlockMultipleAlignment *alignment = GetAlignmentForRow(rowFrom);
713  if (alignment) {
714  int alnBlockNum = alignment->GetAlignedBlockNumber(columnFrom);
715  if (alnBlockNum > 0) {
716  // operations on aligned blocks
717  if (shiftDown && !controlDown && columnTo > 0) // shift left
718  --columnTo;
719  else if (controlDown && !shiftDown && columnTo < (int)maxRowWidth-1) // shift right
720  ++columnTo;
721  else if (shiftDown && controlDown) { // optimize block
722  DisplayRowFromAlignment *alnRow = dynamic_cast<DisplayRowFromAlignment*>(rows[rowFrom]);
723  if (alnRow && alignment->OptimizeBlock(alnRow->row, columnFrom, (*viewerWindow)->GetCurrentJustification()))
724  UpdateAfterEdit(alignment);
725  return;
726  }
727  } else {
728  // operations on unaligned blocks
729  if ((shiftDown && !controlDown) || (controlDown && !shiftDown)) {
730  DisplayRowFromAlignment *alnRow = dynamic_cast<DisplayRowFromAlignment*>(rows[rowFrom]);
731  if (alnRow && alignment->ZipAlignResidue(alnRow->row, columnFrom,
732  controlDown, (*viewerWindow)->GetCurrentJustification()))
733  UpdateAfterEdit(alignment);
734  return;
735  }
736  }
737  }
738  }
739 
740  TRACEMSG("got DraggedCell " << columnFrom << ',' << rowFrom << " to "
741  << columnTo << ',' << rowTo);
742  if (rowFrom == rowTo && columnFrom == columnTo) return;
743  if (rowFrom != rowTo && columnFrom != columnTo) return; // ignore diagonal drag
744 
745  if (columnFrom != columnTo) {
746  BlockMultipleAlignment *alignment = GetAlignmentForRow(rowFrom);
747  if (alignment) {
748  // process horizontal drag on special block boundary row
749  DisplayRowFromString *strRow = dynamic_cast<DisplayRowFromString*>(rows[rowFrom]);
750  if (strRow) {
751  wxString title;
752  wxColour ignored;
753  if (GetRowTitle(rowFrom, &title, &ignored) && title == blockBoundaryStringTitle.c_str()) {
754  char ch = strRow->theString[columnFrom];
755  if (ch == blockRightEdgeChar || ch == blockLeftEdgeChar || ch == blockOneColumnChar) {
756  if (alignment->MoveBlockBoundary(columnFrom, columnTo))
757  UpdateAfterEdit(alignment);
758  }
759  }
760  return;
761  }
762 
763  // process drag on regular row - block row shift
764  DisplayRowFromAlignment *alnRow = dynamic_cast<DisplayRowFromAlignment*>(rows[rowFrom]);
765  if (alnRow) {
766  if (alignment->ShiftRow(alnRow->row, columnFrom, columnTo,
767  (*viewerWindow)->GetCurrentJustification()))
768  UpdateAfterEdit(alignment);
769  return;
770  }
771  }
772  return;
773  }
774 
775  // use vertical drag to reorder row; move rowFrom so that it ends up just before the
776  // initial rowTo row
777  if (rowFrom == rowTo - 1) return;
778  if (rowTo > rowFrom) --rowTo;
779  RowVector newRows(rows);
780  DisplayRow *row = newRows[rowFrom];
781  RowVector::iterator r = newRows.begin();
782  int i;
783  for (i=0; i<rowFrom; ++i) ++r; // get iterator for position rowFrom
784  newRows.erase(r);
785  for (r=newRows.begin(), i=0; i<rowTo; ++i) ++r; // get iterator for position rowTo
786  newRows.insert(r, row);
787 
788  // make sure that the master row of an alignment is still first
789  bool masterOK = true;
790  for (i=0; i<(int)newRows.size(); ++i) {
791  DisplayRowFromAlignment *alnRow = dynamic_cast<DisplayRowFromAlignment*>(newRows[i]);
792  if (alnRow) {
793  if (alnRow->row != 0) {
794  WARNINGMSG("The first alignment row must always be the master sequence");
795  masterOK = false;
796  }
797  break;
798  }
799  }
800  if (masterOK) {
801  rows = newRows;
802  (*viewerWindow)->UpdateDisplay(this);
803  (*viewerWindow)->viewer->Save(); // make this an undoable operation
805  }
806 }
807 
809 {
810  for (unsigned int i=0; i<rows.size(); ++i) {
811  const Sequence *sequence = rows[i]->GetSequence();
812  if (sequence && sequence->molecule)
814  }
815 }
816 
818 {
819  DisplayRowFromString *blockBoundaryRow = NULL;
820  for (unsigned int row=0; row<rows.size(); ++row) {
821  if ((blockBoundaryRow = dynamic_cast<DisplayRowFromString*>(rows[row])) != NULL) {
822  if (blockBoundaryRow->alignment == forAlignment &&
823  blockBoundaryRow->title == blockBoundaryStringTitle)
824  break;
825  else
826  blockBoundaryRow = NULL;
827  }
828  }
829  return blockBoundaryRow;
830 }
831 
833 {
834  return new DisplayRowFromString("", Vector(0,0,0),
835  blockBoundaryStringTitle, true, Vector(0.8,0.8,1), forAlignment);
836 }
837 
839 {
840  if (!IsEditable()) return;
841 
842  // find alignment master rows
843  unsigned int i = 0;
845  do {
846  RowVector::iterator r;
847  for (r=rows.begin(), i=0; i<rows.size(); ++r, ++i) {
848  DisplayRowFromAlignment *alnRow = dynamic_cast<DisplayRowFromAlignment*>(*r);
849  if (!alnRow || alnRow->row != 0 || !alnRow->alignment ||
850  doneForAlignment.find(alnRow->alignment) != doneForAlignment.end()) continue;
851 
852  // insert block row before each master row
853  DisplayRowFromString *blockBoundaryRow = CreateBlockBoundaryRow(alnRow->alignment);
854  UpdateBlockBoundaryRow(blockBoundaryRow);
855  rows.insert(r, blockBoundaryRow);
856  doneForAlignment[alnRow->alignment] = true;
857  break; // insert on vector can cause invalidation of iterators, so start over
858  }
859  } while (i < rows.size());
860 
861  if (*viewerWindow) (*viewerWindow)->UpdateDisplay(this);
862 }
863 
865 {
866  DisplayRowFromString *blockBoundaryRow = CreateBlockBoundaryRow(forAlignment);
867  AddRow(blockBoundaryRow);
868  UpdateBlockBoundaryRow(blockBoundaryRow);
869 }
870 
872 {
873  DisplayRowFromString *blockBoundaryRow;
874  if (!IsEditable() || (blockBoundaryRow = FindBlockBoundaryRow(forAlignment)) == NULL ||
875  !blockBoundaryRow->alignment) return;
876  UpdateBlockBoundaryRow(blockBoundaryRow);
877 }
878 
880 {
881  if (!IsEditable() || !blockBoundaryRow || !blockBoundaryRow->alignment) return;
882 
883  unsigned int alignmentWidth = blockBoundaryRow->alignment->AlignmentWidth();
884  blockBoundaryRow->theString.resize(alignmentWidth);
885 
886  // fill out block boundary marker string
887  int blockColumn, blockWidth;
888  for (unsigned int i=0; i<alignmentWidth; ++i) {
889  blockBoundaryRow->alignment->GetAlignedBlockPosition(i, &blockColumn, &blockWidth);
890  if (blockColumn >= 0 && blockWidth > 0) {
891  if (blockWidth == 1)
892  blockBoundaryRow->theString[i] = blockOneColumnChar;
893  else if (blockColumn == 0)
894  blockBoundaryRow->theString[i] = blockLeftEdgeChar;
895  else if (blockColumn == blockWidth - 1)
896  blockBoundaryRow->theString[i] = blockRightEdgeChar;
897  else
898  blockBoundaryRow->theString[i] = blockInsideChar;
899  } else
900  blockBoundaryRow->theString[i] = ' ';
901  }
902  if (*viewerWindow) GlobalMessenger()->PostRedrawSequenceViewer((*viewerWindow)->viewer);
903 }
904 
906 {
907  vector < bool > toRemove(rows.size(), false);
908  unsigned int nToRemove = 0;
909  for (unsigned int row=0; row<rows.size(); ++row) {
910  DisplayRowFromString *blockBoundaryRow = dynamic_cast<DisplayRowFromString*>(rows[row]);
911  if (blockBoundaryRow && blockBoundaryRow->title == blockBoundaryStringTitle) {
912  delete blockBoundaryRow;
913  toRemove[row] = true;
914  ++nToRemove;
915  }
916  }
917  VectorRemoveElements(rows, toRemove, nToRemove);
919  if (*viewerWindow) (*viewerWindow)->UpdateDisplay(this);
920 }
921 
923 {
924  seqs->clear();
925  for (unsigned int row=0; row<rows.size(); ++row) {
926  const Sequence *seq = rows[row]->GetSequence();
927  if (seq && seq->isProtein)
928  seqs->push_back(seq);
929  }
930 }
931 
933 {
934  seqs->clear();
935  for (unsigned int row=0; row<rows.size(); ++row) {
936  DisplayRowFromAlignment *alnRow = dynamic_cast<DisplayRowFromAlignment*>(rows[row]);
937  if (alnRow && alnRow->alignment == forAlignment)
938  seqs->push_back(alnRow->alignment->GetSequenceOfRow(alnRow->row));
939  }
940 }
941 
943  const BlockMultipleAlignment *forAlignment, vector < unsigned int > *dependentRowOrder) const
944 {
945  dependentRowOrder->clear();
946  for (unsigned int row=0; row<rows.size(); ++row) {
947  DisplayRowFromAlignment *alnRow = dynamic_cast<DisplayRowFromAlignment*>(rows[row]);
948  if (alnRow && alnRow->alignment == forAlignment)
949  dependentRowOrder->push_back(alnRow->row);
950  }
951  if (dependentRowOrder->size() != forAlignment->NRows() || dependentRowOrder->front() != 0)
952  ERRORMSG("SequenceDisplay::GetRowOrder() - row order vector problem");
953 }
954 
955 // comparison function: if CompareRows(a, b) == true, then row a moves up
957 
959 {
961  a->alignment->GetSequenceOfRow(a->row)->identifier,
962  b->alignment->GetSequenceOfRow(b->row)->identifier);
963 }
964 
966 {
967  return (a->alignment->GetRowDouble(a->row) > b->alignment->GetRowDouble(b->row));
968 }
969 
971 {
972  return ((a->alignment->GetRowDouble(a->row) >= 0.0 &&
973  a->alignment->GetRowDouble(a->row) < b->alignment->GetRowDouble(b->row)) ||
974  b->alignment->GetRowDouble(b->row) < 0.0);
975 }
976 
978 {
979  return (a->alignment->GetSequenceOfRow(a->row)->identifier->pdbID.size() > 0 &&
980  b->alignment->GetSequenceOfRow(b->row)->identifier->pdbID.size() == 0);
981 }
982 
984 {
985  return (GlobalMessenger()->IsHighlightedAnywhere(a->alignment->GetSequenceOfRow(a->row)->identifier) &&
986  !GlobalMessenger()->IsHighlightedAnywhere(b->alignment->GetSequenceOfRow(b->row)->identifier));
987 }
988 
991 {
992  return (violations[a->row].size() > 0 && violations[b->row].size() == 0);
993 }
994 
996 
998 {
1000  SortRows();
1001 }
1002 
1004 {
1005  if (!CalculateRowScoresWithThreader(weightPSSM)) return;
1007  SortRows();
1008 }
1009 
1011 {
1013  SortRows();
1014 }
1015 
1017 {
1019  SortRows();
1020 }
1021 
1023 {
1024  DisplayRowFromAlignment *alnRow = NULL;
1025  for (unsigned int row=0; row<rows.size(); ++row) {
1026  alnRow = dynamic_cast<DisplayRowFromAlignment*>(rows[row]);
1027  if (alnRow)
1028  break;
1029  }
1030  if (!alnRow) {
1031  ERRORMSG("SequenceDisplay::FloatGVToTop() - can't get alignment");
1032  return;
1033  }
1034 
1035  if ((*viewerWindow)->viewer->alignmentManager->threader->
1036  GetGeometryViolations(alnRow->alignment, &violations) == 0)
1037  return;
1038  if (!(*viewerWindow)->menuBar->IsChecked(ViewerWindowBase::MID_SHOW_GEOM_VLTNS))
1039  (*viewerWindow)->ProcessCommand(ViewerWindowBase::MID_SHOW_GEOM_VLTNS);
1040 
1042  SortRows();
1043 }
1044 
1046 {
1047  // get alignment
1048  for (unsigned int row=0; row<rows.size(); ++row) {
1049  DisplayRowFromAlignment *alnRow = dynamic_cast<DisplayRowFromAlignment*>(rows[row]);
1050  if (alnRow) {
1051  // do self-hit calculation
1052  (*viewerWindow)->viewer->CalculateSelfHitScores(alnRow->alignment);
1053 
1054  // then sort by score
1056  SortRows();
1057  return;
1058  }
1059  }
1060 }
1061 
1062 bool SequenceDisplay::SortRowsByLoopLength(unsigned int row, unsigned int alnIndex)
1063 {
1064  DisplayRowFromAlignment *alnRow = dynamic_cast<DisplayRowFromAlignment*>(rows[row]);
1065  if (!alnRow)
1066  return false;
1067 
1068  for (unsigned int r=0; r<alnRow->alignment->NRows(); ++r) {
1069  int loop = alnRow->alignment->GetLoopLength(r, alnIndex);
1070  if (loop < 0) // means this column is aligned
1071  return false;
1072  alnRow->alignment->SetRowDouble(r, loop);
1073  }
1074 
1076  SortRows();
1077  return true;
1078 }
1079 
1081 {
1082  if (!rowComparisonFunction) {
1083  ERRORMSG("SequenceDisplay::SortRows() - must first set comparison function");
1084  return;
1085  }
1086 
1087  // to simplify sorting, construct list of dependent rows only
1088  vector < DisplayRowFromAlignment * > dependents;
1089  unsigned int row;
1090  for (row=0; row<rows.size(); ++row) {
1091  DisplayRowFromAlignment *alnRow = dynamic_cast<DisplayRowFromAlignment*>(rows[row]);
1092  if (alnRow && alnRow->row > 0)
1093  dependents.push_back(alnRow);
1094  }
1095 
1096  // do the sort
1097  stable_sort(dependents.begin(), dependents.end(), rowComparisonFunction);
1099 
1100  // recreate the row list with new order
1101  RowVector newRows(rows.size());
1102  unsigned int nDependents = 0;
1103  for (row=0; row<rows.size(); ++row) {
1104  DisplayRowFromAlignment *alnRow = dynamic_cast<DisplayRowFromAlignment*>(rows[row]);
1105  if (alnRow && alnRow->row > 0)
1106  newRows[row] = dependents[nDependents++]; // put sorted dependents in place
1107  else
1108  newRows[row] = rows[row]; // leave other rows in original order
1109  }
1110  if (nDependents == dependents.size()) // sanity check
1111  rows = newRows;
1112  else
1113  ERRORMSG("SequenceDisplay::SortRows() - internal inconsistency");
1114 
1115  (*viewerWindow)->viewer->Save(); // make this an undoable operation
1116  (*viewerWindow)->UpdateDisplay(this);
1117 }
1118 
1119 bool SequenceDisplay::ProximitySort(unsigned int displayRow)
1120 {
1121  DisplayRowFromAlignment *keyRow = dynamic_cast<DisplayRowFromAlignment*>(rows[displayRow]);
1122  if (!keyRow || keyRow->row == 0) return false;
1123  if (keyRow->alignment->NRows() < 3) return true;
1124 
1125  TRACEMSG("doing Proximity Sort on alignment row " << keyRow->row);
1126  unsigned int row;
1129  BlockMultipleAlignment::UngappedAlignedBlockList::const_iterator b, be = blocks.end();
1130  const Sequence *seq1 = keyRow->alignment->GetSequenceOfRow(keyRow->row);
1131  vector < DisplayRowFromAlignment * > sortedByScore;
1132 
1133  // calculate scores for each row based on simple Blosum62 sum of all aligned pairs
1134  for (row=0; row<rows.size(); ++row) {
1135  DisplayRowFromAlignment *alnRow = dynamic_cast<DisplayRowFromAlignment*>(rows[row]);
1136  if (!alnRow) continue;
1137  sortedByScore.push_back(alnRow);
1138 
1139  if (alnRow == keyRow) {
1140  keyRow->alignment->SetRowDouble(keyRow->row, kMax_Double);
1141  keyRow->alignment->SetRowStatusLine(keyRow->row, "(key row)");
1142  } else {
1143  const Sequence *seq2 = alnRow->alignment->GetSequenceOfRow(alnRow->row);
1144  double score = 0.0;
1145  for (b=blocks.begin(); b!=be; ++b) {
1146  const Block::Range
1147  *r1 = (*b)->GetRangeOfRow(keyRow->row),
1148  *r2 = (*b)->GetRangeOfRow(alnRow->row);
1149  for (unsigned int i=0; i<(*b)->width; ++i)
1150  score += GetBLOSUM62Score(
1151  seq1->sequenceString[r1->from + i], seq2->sequenceString[r2->from + i]);
1152  }
1153  alnRow->alignment->SetRowDouble(alnRow->row, score);
1154  alnRow->alignment->SetRowStatusLine(alnRow->row, ("Score vs. key row: " + NStr::IntToString((int) score)));
1155  }
1156  }
1157  if (sortedByScore.size() != keyRow->alignment->NRows()) {
1158  ERRORMSG("SequenceDisplay::ProximitySort() - wrong # rows in sort list");
1159  return false;
1160  }
1161 
1162  // sort by these scores
1163  stable_sort(sortedByScore.begin(), sortedByScore.end(), CompareRowsByScore);
1164 
1165  // find where the master row is in sorted list
1166  unsigned int M;
1167  for (M=0; M<sortedByScore.size(); ++M) if (sortedByScore[M]->row == 0) break;
1168 
1169  // arrange by proximity to key row
1170  vector < DisplayRowFromAlignment * > arrangedByProximity(sortedByScore.size(), NULL);
1171 
1172  // add master and key row
1173  arrangedByProximity[0] = sortedByScore[M]; // move master back to top
1174  arrangedByProximity[M] = sortedByScore[0]; // move key row to M
1175  // remove these from sorted list
1176  vector < bool > toRemove(sortedByScore.size(), false);
1177  toRemove[M] = toRemove[0] = true;
1178  VectorRemoveElements(sortedByScore, toRemove, 2);
1179 
1180  // add the rest of the sequences in the sorted list to the arranged list
1181  int i = 1, j = 1, N;
1182  unsigned int R = 0;
1183  while (R < sortedByScore.size()) {
1184  N = M + i*j; // iterate N = M+1, M-1, M+2, M-2, ...
1185  j = -j;
1186  if (j > 0) ++i;
1187  if (N > 0 && N < (int)arrangedByProximity.size())
1188  arrangedByProximity[N] = sortedByScore[R++];
1189  }
1190 
1191  // recreate the row list with new order
1192  RowVector newRows(rows.size());
1193  unsigned int nNewRows = 0;
1194  for (row=0; row<rows.size(); ++row) {
1195  DisplayRowFromAlignment *alnRow = dynamic_cast<DisplayRowFromAlignment*>(rows[row]);
1196  if (alnRow)
1197  newRows[row] = arrangedByProximity[nNewRows++]; // put arranged rows in place
1198  else
1199  newRows[row] = rows[row]; // leave other rows in original order
1200  }
1201  if (nNewRows == arrangedByProximity.size()) // sanity check
1202  rows = newRows;
1203  else
1204  ERRORMSG("SequenceDisplay::ProximitySort() - internal inconsistency");
1205 
1206  // finally, highlight the key row and scroll approximately there
1208  GlobalMessenger()->AddHighlights(seq1, 0, seq1->Length() - 1);
1209  (*viewerWindow)->ScrollToRow((M - 3) > 0 ? (M - 3) : 0);
1210  (*viewerWindow)->viewer->Save(); // make this an undoable operation
1211  (*viewerWindow)->UpdateDisplay(this);
1212  return true;
1213 }
1214 
1216 {
1217  if (isEditable) {
1218  SequenceViewer *seqViewer = dynamic_cast<SequenceViewer*>((*viewerWindow)->viewer);
1219  if (seqViewer) {
1220  seqViewer->alignmentManager->CalculateRowScoresWithThreader(weightPSSM);
1221  TRACEMSG("calculated row scores");
1222  return true;
1223  }
1224  }
1225  return false;
1226 }
1227 
1228 void SequenceDisplay::RowsAdded(unsigned int nRowsAddedToMultiple, BlockMultipleAlignment *multiple, int alnWhere)
1229 {
1230  if (nRowsAddedToMultiple == 0) return;
1231 
1232  // find the last row that's from this multiple
1233  unsigned int r, nRows = 0, lastAlnRowIndex = 0;
1234  int displayWhere = -1;
1235  DisplayRowFromAlignment *lastAlnRow = NULL;
1236  for (r=0; r<rows.size(); ++r) {
1237  DisplayRowFromAlignment *alnRow = dynamic_cast<DisplayRowFromAlignment*>(rows[r]);
1238  if (alnRow && alnRow->alignment == multiple) {
1239  lastAlnRow = alnRow;
1240  lastAlnRowIndex = r;
1241  ++nRows;
1242  if (alnWhere >= 0 && (int)alnRow->row == alnWhere)
1243  displayWhere = r; // convert 'where' from alignment row to display row
1244  }
1245  }
1246  if (!lastAlnRow || multiple->NRows() != nRows + nRowsAddedToMultiple) {
1247  ERRORMSG("SequenceDisplay::RowsAdded() - inconsistent parameters");
1248  return;
1249  }
1250  int rowToMergeAfter = (displayWhere >= 0) ? displayWhere : lastAlnRowIndex;
1251  INFOMSG("adding new row after display row #" << (rowToMergeAfter+1));
1252 
1253  // move higher rows up to leave space for new rows
1254  unsigned int nRowsToMove = rows.size() - 1 - rowToMergeAfter;
1255  rows.resize(rows.size() + nRowsAddedToMultiple);
1256  for (r=0; r<nRowsToMove; ++r)
1257  rows[rows.size() - 1 - r] = rows[rows.size() - 1 - r - nRowsAddedToMultiple];
1258 
1259  // add new rows, assuming new rows to add to the display are from the last rows of the multiple
1260  for (r=0; r<nRowsAddedToMultiple; ++r)
1261  rows[rowToMergeAfter + 1 + r] = new DisplayRowFromAlignment(
1262  multiple->NRows() + r - nRowsAddedToMultiple, multiple);
1263 
1264  UpdateAfterEdit(multiple);
1265 }
1266 
1267 void SequenceDisplay::RowsRemoved(const vector < unsigned int >& rowsRemoved,
1268  const BlockMultipleAlignment *multiple)
1269 {
1270  if (rowsRemoved.size() == 0) return;
1271 
1272  // first, construct a map of old alignment row numbers -> new row numbers; also do sanity checks
1273  unsigned int i;
1274  vector < unsigned int > alnRowNumbers(multiple->NRows() + rowsRemoved.size());
1275  vector < bool > removedAlnRows(alnRowNumbers.size(), false);
1276  for (i=0; i<alnRowNumbers.size(); ++i) alnRowNumbers[i] = i;
1277  for (i=0; i<rowsRemoved.size(); ++i) {
1278  if (rowsRemoved[i] < 1 || rowsRemoved[i] >= alnRowNumbers.size()) {
1279  ERRORMSG("SequenceDisplay::RowsRemoved() - can't remove row " << removedAlnRows[i]);
1280  return;
1281  } else
1282  removedAlnRows[rowsRemoved[i]] = true;
1283  }
1284  VectorRemoveElements(alnRowNumbers, removedAlnRows, rowsRemoved.size());
1285  map < unsigned int, unsigned int > oldRowToNewRow;
1286  for (i=0; i<alnRowNumbers.size(); ++i) oldRowToNewRow[alnRowNumbers[i]] = i;
1287 
1288  // then tag rows to remove from display, and update row numbers for rows not removed
1289  vector < bool > removeDisplayRows(rows.size(), false);
1290  for (i=0; i<rows.size(); ++i) {
1291  DisplayRowFromAlignment *alnRow = dynamic_cast<DisplayRowFromAlignment*>(rows[i]);
1292  if (alnRow && alnRow->alignment == multiple) {
1293  if (removedAlnRows[alnRow->row]) {
1294  delete rows[i];
1295  removeDisplayRows[i] = true;
1296  } else
1297  alnRow->row = oldRowToNewRow[alnRow->row];
1298  }
1299  }
1300  VectorRemoveElements(rows, removeDisplayRows, rowsRemoved.size());
1301 
1302  UpdateAfterEdit(multiple);
1303 }
1304 
1305 bool SequenceDisplay::GetDisplayCoordinates(const Molecule *molecule, unsigned int seqIndex,
1306  BlockMultipleAlignment::eUnalignedJustification justification, unsigned int *column, unsigned int *row)
1307 {
1308  if (!molecule) return false;
1309 
1310  unsigned int displayRow;
1311  const Sequence *seq;
1312 
1313  // search by Molecule*
1314  for (displayRow=0; displayRow<NRows(); ++displayRow) {
1315  seq = rows[displayRow]->GetSequence();
1316  if (seq && seq->molecule == molecule) {
1317  *row = displayRow;
1318 
1319  const DisplayRowFromAlignment *alnRow = dynamic_cast<DisplayRowFromAlignment*>(rows[displayRow]);
1320  if (alnRow) {
1321  int c = alnRow->alignment->GetAlignmentIndex(alnRow->row, seqIndex, justification);
1322  *column = c;
1323  return (c >= 0);
1324  }
1325 
1326  const DisplayRowFromSequence *seqRow = dynamic_cast<DisplayRowFromSequence*>(rows[displayRow]);
1327  if (seqRow && seqIndex >= seqRow->fromIndex && seqIndex <= seqRow->toIndex) {
1328  *column = seqIndex - seqRow->fromIndex;
1329  return true;
1330  }
1331  }
1332  }
1333  return false;
1334 }
1335 
1336 END_SCOPE(Cn3D)
void BlockAlignUpdate(BlockMultipleAlignment *single)
void CalculateRowScoresWithThreader(double weightPSSM)
void RealignDependentSequences(BlockMultipleAlignment *multiple, const std::vector< unsigned int > &dependentsToRealign)
void ExtendUpdate(BlockMultipleAlignment *single)
std::map< BlockMultipleAlignment *, bool > UpdateMap
void ThreadUpdate(const ThreaderOptions &options, BlockMultipleAlignment *single)
const BlockMultipleAlignment * GetCurrentMultipleAlignment(void) const
void MergeUpdates(const UpdateMap &updates, bool mergeToNeighbor)
bool CreateBlock(unsigned int fromAlignmentIndex, unsigned int toAlignmentIndex, eUnalignedJustification justification)
void SelectBlocks(unsigned int alnIndexFrom, unsigned int alnIndexTo, bool toggle) const
bool ZipAlignResidue(unsigned int row, unsigned int alignmentIndex, bool moveRight, eUnalignedJustification justification)
unsigned int AlignmentWidth(void) const
bool MoveBlockBoundary(unsigned int columnFrom, unsigned int columnTo)
bool MarkBlock(unsigned int column)
bool OptimizeBlock(unsigned int row, unsigned int alignmentIndex, eUnalignedJustification justification)
bool ShiftRow(unsigned int row, unsigned int fromAlignmentIndex, unsigned int toAlignmentIndex, eUnalignedJustification justification)
bool GetCharacterTraitsAt(unsigned int alignmentColumn, unsigned int row, eUnalignedJustification justification, char *character, Vector *color, bool *isHighlighted, bool *drawBackground, Vector *cellBackgroundColor) const
void SetRowDouble(unsigned int row, double value) const
void SetRowStatusLine(unsigned int row, const std::string &value) const
std::vector< const UngappedAlignedBlock * > UngappedAlignedBlockList
const Sequence * GetSequenceOfRow(unsigned int row) const
unsigned int GetAlignedBlockNumber(unsigned int alignmentIndex) const
void GetUngappedAlignedBlocks(UngappedAlignedBlockList *blocks) const
unsigned int GetAlignmentIndex(unsigned int row, unsigned int seqIndex, eUnalignedJustification justification)
const std::string & GetRowStatusLine(unsigned int row) const
void GetAlignedBlockPosition(unsigned int alignmentIndex, unsigned int *blockColumn, unsigned int *blockWidth) const
bool DeleteBlock(unsigned int alignmentIndex)
bool MergeBlocks(unsigned int fromAlignmentIndex, unsigned int toAlignmentIndex)
bool SplitBlock(unsigned int alignmentIndex)
int GetLoopLength(unsigned int row, unsigned int alignmentIndex)
@ eHighlight
Definition: cn3d_colors.hpp:60
const Vector & Get(eColor which) const
bool GetCharacterTraitsAt(unsigned int column, BlockMultipleAlignment::eUnalignedJustification justification, char *character, Vector *color, bool *drawBackground, Vector *cellBackgroundColor) const
BlockMultipleAlignment *const alignment
const Sequence *const sequence
DisplayRowFromSequence(const Sequence *s, unsigned int from, unsigned int to)
bool GetCharacterTraitsAt(unsigned int column, BlockMultipleAlignment::eUnalignedJustification justification, char *character, Vector *color, bool *drawBackground, Vector *cellBackgroundColor) const
const unsigned int toIndex
bool GetSequenceAndIndexAt(unsigned int column, BlockMultipleAlignment::eUnalignedJustification justification, const Sequence **sequenceHandle, int *index) const
void SelectedRange(unsigned int from, unsigned int to, BlockMultipleAlignment::eUnalignedJustification justification, bool toggle) const
const unsigned int fromIndex
BlockMultipleAlignment *const alignment
const std::string title
bool GetCharacterTraitsAt(unsigned int column, BlockMultipleAlignment::eUnalignedJustification justification, char *character, Vector *color, bool *drawBackground, Vector *cellBackgroundColor) const
virtual bool GetSequenceAndIndexAt(unsigned int column, BlockMultipleAlignment::eUnalignedJustification justification, const Sequence **sequence, int *index) const =0
virtual const Sequence * GetSequence(void) const =0
virtual unsigned int Width(void) const =0
virtual bool GetCharacterTraitsAt(unsigned int column, BlockMultipleAlignment::eUnalignedJustification justification, char *character, Vector *color, bool *drawBackground, Vector *cellBackgroundColor) const =0
void ToggleHighlights(const Sequence *sequence, unsigned int seqIndexFrom, unsigned int seqIndexTo)
Definition: messenger.cpp:350
void PostRedrawMolecule(const Molecule *molecule)
Definition: messenger.cpp:85
void PostRedrawSequenceViewer(ViewerBase *viewer)
Definition: messenger.cpp:95
void KeepHighlightsOnlyOnSequence(const Sequence *sequence)
Definition: messenger.cpp:277
bool RemoveAllHighlights(bool postRedraws)
Definition: messenger.cpp:393
void PostRedrawAllSequenceViewers(void)
Definition: messenger.cpp:90
void AddHighlights(const Sequence *sequence, unsigned int seqIndexFrom, unsigned int seqIndexTo)
Definition: messenger.cpp:248
static bool CompareIdentifiers(const MoleculeIdentifier *a, const MoleculeIdentifier *b)
std::string ToString(void) const
Vector GetResidueColor(int sequenceIndex) const
Definition: molecule.cpp:218
ResidueMap residues
Definition: molecule.hpp:89
bool GetValues(int *from, int *to)
std::string namePDB
Definition: residue.hpp:74
bool GetRowTitle(unsigned int row, wxString *title, wxColour *color) const
bool GetCharacterTraitsAt(unsigned int column, unsigned int row, char *character, wxColour *color, bool *drawBackground, wxColour *cellBackgroundColor) const
bool ProximitySort(unsigned int displayRow)
bool CalculateRowScoresWithThreader(double weightPSSM)
void AddBlockBoundaryRows(void)
void FloatPDBRowsToTop(void)
BlockMultipleAlignment * GetAlignmentForRow(unsigned int row) const
DisplayRowFromString * FindBlockBoundaryRow(const BlockMultipleAlignment *forAlignment) const
void SortRowsByThreadingScore(double weightPSSM)
void AddRowFromAlignment(unsigned int row, BlockMultipleAlignment *fromAlignment)
void UpdateMaxRowWidth(void)
bool SortRowsByLoopLength(unsigned int row, unsigned int alnIndex)
unsigned int NRows(void) const
void AddRowFromString(const std::string &anyString)
void RedrawAlignedMolecules(void) const
void SortRowsBySelfHit(void)
void UpdateAfterEdit(const BlockMultipleAlignment *forAlignment)
void FloatHighlightsToTop(void)
SequenceDisplay * Clone(const Old2NewAlignmentMap &newAlignments) const
void GetProteinSequences(SequenceList *seqs) const
bool GetDisplayCoordinates(const Molecule *molecule, unsigned int seqIndex, BlockMultipleAlignment::eUnalignedJustification justification, unsigned int *column, unsigned int *row)
void RowsAdded(unsigned int nRowsAddedToMultiple, BlockMultipleAlignment *multiple, int where=-1)
SequenceDisplay(bool editable, ViewerWindowBase *const *parentViewerWindow)
unsigned int maxRowWidth
virtual ~SequenceDisplay(void)
void AddRow(DisplayRow *row)
bool MouseDown(int column, int row, unsigned int controls)
void GetSequences(const BlockMultipleAlignment *forAlignment, SequenceList *seqs) const
void RemoveBlockBoundaryRows(void)
void RowsRemoved(const std::vector< unsigned int > &rowsRemoved, const BlockMultipleAlignment *multiple)
bool IsEditable(void) const
unsigned int startingColumn
void AddRowFromSequence(const Sequence *sequence, unsigned int from, unsigned int to)
ViewerWindowBase *const * viewerWindow
void GetRowOrder(const BlockMultipleAlignment *forAlignment, std::vector< unsigned int > *dependentRowOrder) const
void MouseOver(int column, int row) const
void DraggedCell(int columnFrom, int rowFrom, int columnTo, int rowTo)
std::vector< DisplayRow * > RowVector
void SortRowsByIdentifier(void)
void AddBlockBoundaryRow(BlockMultipleAlignment *forAlignment)
void UpdateBlockBoundaryRow(const BlockMultipleAlignment *forAlignment) const
std::vector< const Sequence * > SequenceList
void SelectedRectangle(int columnLeft, int rowTop, int columnRight, int rowBottom)
bool DoRestrictHighlights(void) const
bool isProtein
const Molecule * molecule
std::string GetDescription(void) const
const MoleculeIdentifier * identifier
unsigned int Length(void) const
string sequenceString
Definition: cav_seqset.hpp:93
void LaunchWebBrowserWithInfo(void) const
StructureSet * parentSet
StyleManager * styleManager
const Vector & GetObjectColor(const Molecule *molecule) const
bool GetValues(ThreaderOptions *options)
std::vector< IntervalList > GeometryViolationsForRow
static unsigned int EstimateNRandomStarts(const BlockMultipleAlignment *coreAlignment, const BlockMultipleAlignment *toBeThreaded)
bool DoThreadSingle(void) const
bool DoBlastSingle(void) const
bool DoBlastPSSMSingle(void) const
bool DoMergeSingle(void) const
bool DoDeleteSingle(void) const
bool DoExtendSingle(void) const
bool DoBlockAlignSingle(void) const
bool DoSetRegion(void) const
bool DoBlastNeighborSingle(void) const
bool DoDeleteAllBlocks(void) const
bool DoMergeNeighbor(void) const
void BlastUpdate(BlockMultipleAlignment *alignment, bool usePSSMFromMultiple)
void DeleteAlignment(BlockMultipleAlignment *toDelete)
void BlastNeighbor(BlockMultipleAlignment *update)
AlignmentManager * alignmentManager
Definition: viewer_base.hpp:96
bool AlwaysSyncStructures(void) const
const_iterator end() const
Definition: map.hpp:152
const_iterator find(const key_type &key) const
Definition: map.hpp:153
Definition: map.hpp:338
const Colors * GlobalColors(void)
Definition: cn3d_colors.cpp:52
static int nRows
Definition: cn3d_png.cpp:115
ThreaderOptions globalThreaderOptions
#define TRACEMSG(stream)
Definition: cn3d_tools.hpp:83
#define INFOMSG(stream)
Definition: cn3d_tools.hpp:84
#define WARNINGMSG(stream)
Definition: cn3d_tools.hpp:85
#define ERRORMSG(stream)
Definition: cn3d_tools.hpp:86
Include a standard set of the NCBI C++ Toolkit most basic headers.
#define bool
Definition: bool.h:34
static const char * column
Definition: stats.c:23
#define NULL
Definition: ncbistd.hpp:225
#define kMax_Double
Definition: ncbi_limits.h:208
#define END_SCOPE(ns)
End the previously defined scope.
Definition: ncbistl.hpp:75
#define BEGIN_SCOPE(ns)
Define a new scope.
Definition: ncbistl.hpp:72
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5078
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
n background color
int i
yy_size_t n
Messenger * GlobalMessenger(void)
Definition: messenger.cpp:73
unsigned int a
Definition: ncbi_localip.c:102
int tolower(Uchar c)
Definition: ncbictype.hpp:72
The NCBI C++/STL use hints.
NCBI C++ stream class wrappers for triggering between "new" and "old" C++ stream libraries.
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
void copy(Njn::Matrix< S > *matrix_, const Njn::Matrix< T > &matrix0_)
Definition: njn_matrix.hpp:613
#define M
static bool CompareRowsFloatGV(const DisplayRowFromAlignment *a, const DisplayRowFromAlignment *b)
static DisplayRowFromString * CreateBlockBoundaryRow(BlockMultipleAlignment *forAlignment)
static const char blockRightEdgeChar
bool(* CompareRows)(const DisplayRowFromAlignment *a, const DisplayRowFromAlignment *b)
static bool CompareRowsByScore(const DisplayRowFromAlignment *a, const DisplayRowFromAlignment *b)
static bool CompareRowsByIdentifier(const DisplayRowFromAlignment *a, const DisplayRowFromAlignment *b)
static void Vector2wxColor(const Vector &colorVec, wxColor *colorWX)
static const char blockLeftEdgeChar
static const char blockOneColumnChar
static bool CompareRowsFloatHighlights(const DisplayRowFromAlignment *a, const DisplayRowFromAlignment *b)
static const string blockBoundaryStringTitle("(blocks)")
static bool CompareRowsFloatPDB(const DisplayRowFromAlignment *a, const DisplayRowFromAlignment *b)
static Threader::GeometryViolationsForRow violations
USING_NCBI_SCOPE
static const char blockInsideChar
static CompareRows rowComparisonFunction
static bool CompareRowsByEValue(const DisplayRowFromAlignment *a, const DisplayRowFromAlignment *b)
std::map< BlockMultipleAlignment *, BlockMultipleAlignment * > Old2NewAlignmentMap
static const sljit_gpr r1
static const sljit_gpr r2
#define row(bind, expected)
Definition: string_bind.c:73
static DP_BlockInfo * blocks
static int GetBLOSUM62Score(char a, char b)
void VectorRemoveElements(std::vector< T > &v, const std::vector< bool > &remove, unsigned int nToRemove)
Definition: su_private.hpp:53
else result
Definition: token2.c:20
#define N
Definition: crc32.c:57
Modified on Fri Sep 20 14:57:30 2024 by modify_doxy.py rev. 669887