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

Go to the SVN repository for this file.

1 /* $Id: adjust_features_for_gaps.cpp 47485 2023-05-02 14:46:59Z ucko $
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: Igor Filippov
27  */
28 
29 
30 #include <ncbi_pch.hpp>
31 
32 
33 // For compilers that support precompilation, includes "wx/wx.h".
34 #include "wx/wxprec.h"
35 
36 #ifdef __BORLANDC__
37 #pragma hdrstop
38 #endif
39 
40 #ifndef WX_PRECOMP
41 #include "wx/wx.h"
42 #endif
43 
44 ////@begin includes
45 #include <wx/textfile.h>
46 #include <wx/hyperlink.h>
47 ////@end includes
48 
55 #include <objmgr/seq_map.hpp>
56 #include <objmgr/seq_map_ci.hpp>
57 #include <objmgr/feat_ci.hpp>
59 #include <objmgr/util/sequence.hpp>
61 #include <gui/objutils/utils.hpp>
75 #include <objmgr/util/feature.hpp>
76 
80 
81 ////@begin XPM images
82 ////@end XPM images
83 
84 
87 
88 /*
89  * CAdjustFeaturesForGaps type definition
90  */
91 
92 IMPLEMENT_DYNAMIC_CLASS( CAdjustFeaturesForGaps, wxDialog )
93 
94 
95 /*
96  * CAdjustFeaturesForGaps event table definition
97  */
98 
99 BEGIN_EVENT_TABLE( CAdjustFeaturesForGaps, wxDialog )
100 
101 ////@begin CAdjustFeaturesForGaps event table entries
103  EVT_CHECKBOX(ID_CADJUSTFEATURES_CHECKBOX1, CAdjustFeaturesForGaps::OnKnownUnknownSelected) // unknown
108  EVT_LIST_ITEM_SELECTED(ID_CADJUSTFEATURES_LISTBOX, CAdjustFeaturesForGaps::OnFeatTypeChanged)
109  EVT_LIST_ITEM_DESELECTED(ID_CADJUSTFEATURES_LISTBOX, CAdjustFeaturesForGaps::OnFeatTypeChanged)
110  EVT_BUTTON(ID_CADJUSTFEATURES_BUTTON2, CAdjustFeaturesForGaps::OnMakeReport)
111 ////@end CAdjustFeaturesForGaps event table entries
112 
114 
115 
116 /*
117  * CAdjustFeaturesForGaps constructors
118  */
119 
121 {
122  Init();
123 }
124 
125 CAdjustFeaturesForGaps::CAdjustFeaturesForGaps( wxWindow* parent, objects::CSeq_entry_Handle tse, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
126  : m_TopSeqEntry(tse)
127 {
128  Init();
129  Create(parent, id, caption, pos, size, style);
130 }
131 
132 
133 /*
134  * CAdjustFeaturesForGaps creator
135  */
136 
137 bool CAdjustFeaturesForGaps::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
138 {
139 ////@begin CAdjustFeaturesForGaps creation
140  SetExtraStyle(wxWS_EX_BLOCK_EVENTS);
141  wxDialog::Create( parent, id, caption, pos, size, style );
142 
143  CreateControls();
144  if (GetSizer())
145  {
146  GetSizer()->SetSizeHints(this);
147  }
148  Centre();
149 ////@end CAdjustFeaturesForGaps creation
150  return true;
151 }
152 
153 
154 /*
155  * CAdjustFeaturesForGaps destructor
156  */
157 
159 {
160 ////@begin CAdjustFeaturesForGaps destruction
161 ////@end CAdjustFeaturesForGaps destruction
162 }
163 
164 
165 /*
166  * Member initialisation
167  */
168 
170 {
171 ////@begin CAdjustFeaturesForGaps member initialisation
172  m_Features = NULL;
174  m_UnknownGap = NULL;
175  m_KnownGap = NULL;
177  m_TrimEnds = NULL;
181 ////@end CAdjustFeaturesForGaps member initialisation
184 }
185 
186 
187 /*
188  * Control creation for CAdjustFeaturesForGaps
189  */
190 
192 {
193 ////@begin CAdjustFeaturesForGaps content construction
194  // Generated by DialogBlocks, 25/02/2016 16:13:18 (unregistered)
195 
196  CAdjustFeaturesForGaps* itemDialog1 = this;
197 
198  wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
199  itemDialog1->SetSizer(itemBoxSizer2);
200 
201  wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxHORIZONTAL);
202  itemBoxSizer2->Add(itemBoxSizer3, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
203 
204  m_Features = new wxListCtrl( itemDialog1, ID_CADJUSTFEATURES_LISTCTRL, wxDefaultPosition, wxDefaultSize, wxLC_REPORT );
205  itemBoxSizer3->Add(m_Features, 1, wxGROW|wxALL, 5);
206 
207  wxListItem col0;
208  col0.SetId(0);
209  col0.SetText( _("Feature") );
210  col0.SetWidth(80);
211  m_Features->InsertColumn(0, col0);
212 
213  wxListItem col1;
214  col1.SetId(1);
215  col1.SetText( wxEmptyString );
216  col1.SetWidth(250);
217  m_Features->InsertColumn(1, col1);
218 
219  wxListItem col2;
220  col2.SetId(2);
221  col2.SetText(_("Action"));
222  col2.SetWidth(60);
223  m_Features->InsertColumn(2, col2);
224 
225  wxListItem col3;
226  col3.SetId(3);
227  col3.SetText( _("Location") );
228  col3.SetWidth(250);
229  m_Features->InsertColumn(3, col3);
230 
231  m_FeatureCountText = new wxStaticText( itemDialog1, wxID_STATIC, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
232  itemBoxSizer2->Add(m_FeatureCountText, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
233 
234  m_FeatureType = new wxListCtrl(itemDialog1, ID_CADJUSTFEATURES_LISTBOX, wxDefaultPosition, wxSize(250, 200), wxLC_REPORT);
235  itemBoxSizer2->Add(m_FeatureType, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
236 
237  wxBoxSizer* itemBoxSizer7 = new wxBoxSizer(wxHORIZONTAL);
238  itemBoxSizer2->Add(itemBoxSizer7, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
239 
240  m_UnknownGap = new wxCheckBox( itemDialog1, ID_CADJUSTFEATURES_CHECKBOX, _("Unknown length gaps"), wxDefaultPosition, wxDefaultSize, 0 );
241  m_UnknownGap->SetValue(false);
242  itemBoxSizer7->Add(m_UnknownGap, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
243 
244  m_KnownGap = new wxCheckBox( itemDialog1, ID_CADJUSTFEATURES_CHECKBOX1, _("Known length gaps"), wxDefaultPosition, wxDefaultSize, 0 );
245  m_KnownGap->SetValue(false);
246  itemBoxSizer7->Add(m_KnownGap, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
247 
248  m_Ns = new wxCheckBox(itemDialog1, ID_CADJUSTFEATURES_CHECKBOX_NS, _("Ns"), wxDefaultPosition, wxDefaultSize, 0);
249  m_Ns->SetValue(false);
250  itemBoxSizer7->Add(m_Ns, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
251 
252  wxArrayString m_MakeTruncatedPartialStrings;
253  m_MakeTruncatedPartialStrings.Add(_("Always"));
254  m_MakeTruncatedPartialStrings.Add(_("Unless pseudo"));
255  m_MakeTruncatedPartialStrings.Add(_("Never"));
256  m_MakeTruncatedPartial = new wxRadioBox( itemDialog1, ID_CADJUSTFEATURES_RADIOBOX, _("Make truncated ends partial"), wxDefaultPosition, wxDefaultSize, m_MakeTruncatedPartialStrings, 1, wxRA_SPECIFY_ROWS );
257  m_MakeTruncatedPartial->SetSelection(0);
258  itemBoxSizer2->Add(m_MakeTruncatedPartial, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
259 
260  wxBoxSizer* itemBoxSizer11 = new wxBoxSizer(wxHORIZONTAL);
261  itemBoxSizer2->Add(itemBoxSizer11, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
262 
263  m_TrimEnds = new wxCheckBox( itemDialog1, ID_CADJUSTFEATURES_CHECKBOX2, _("Trim ends in gaps"), wxDefaultPosition, wxDefaultSize, 0 );
264  m_TrimEnds->SetValue(false);
265  itemBoxSizer11->Add(m_TrimEnds, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
266 
267  m_RemoveFeats = new wxCheckBox(itemDialog1, ID_CADJUSTFEATURES_CHECKBOX5, _("Remove features entirely in gaps"), wxDefaultPosition, wxDefaultSize, 0);
268  m_RemoveFeats->SetValue(false);
269  itemBoxSizer11->Add(m_RemoveFeats, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
270 
271  m_SplitForInternal = new wxCheckBox( itemDialog1, ID_CADJUSTFEATURES_CHECKBOX3, _("Split for internal gaps"), wxDefaultPosition, wxDefaultSize, 0 );
272  m_SplitForInternal->SetValue(false);
273  itemBoxSizer11->Add(m_SplitForInternal, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
274 
275  m_EvenIfIntrons = new wxCheckBox( itemDialog1, ID_CADJUSTFEATURES_CHECKBOX4, _("[Even when gaps are in introns]"), wxDefaultPosition, wxDefaultSize, 0 );
276  m_EvenIfIntrons->SetValue(false);
277  m_EvenIfIntrons->Enable(false);
278  itemBoxSizer11->Add(m_EvenIfIntrons, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
279 
280  wxBoxSizer* itemBoxSizer15 = new wxBoxSizer(wxHORIZONTAL);
281  itemBoxSizer2->Add(itemBoxSizer15, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
282 
283  m_AcceptButton = new wxButton( itemDialog1, wxID_OK, _("Accept"), wxDefaultPosition, wxDefaultSize, 0 );
284  itemBoxSizer15->Add(m_AcceptButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
285  m_AcceptButton->Disable();
286 
287  wxButton* itemButton17 = new wxButton( itemDialog1, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
288  itemBoxSizer15->Add(itemButton17, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
289 
290  wxButton* itemButton18 = new wxButton( itemDialog1, ID_CADJUSTFEATURES_BUTTON2, _("Make Report"), wxDefaultPosition, wxDefaultSize, 0 );
291  itemBoxSizer15->Add(itemButton18, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
292 
293  wxHyperlinkCtrl* itemHyperlinkCtrl = new wxHyperlinkCtrl( itemDialog1, wxID_HELP, _("Help"), wxT("https://www.ncbi.nlm.nih.gov/tools/gbench/manual15/#adjust-features"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE );
294  itemHyperlinkCtrl->SetForegroundColour(wxColour(192, 192, 192));
295  itemBoxSizer15->Add(itemHyperlinkCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
296 
297  m_LeaveUp = new wxCheckBox(itemDialog1, wxID_ANY, _("Leave dialog up"));
298  itemBoxSizer15->Add(m_LeaveUp, 0, wxALIGN_LEFT | wxALL, 5);
299 
300 ////@end CAdjustFeaturesForGaps content construction
302 
303  m_FeatureType->InsertColumn(0, " Feature", wxLIST_FORMAT_LEFT, 237);
304  for (unsigned int i = 0; i < m_FeatureTypeStrings.size(); i++) {
305  m_FeatureType->InsertItem(i, m_FeatureTypeStrings[i]);
306  }
307 }
308 
310 {
311  m_FeatureTypeStrings.Clear();
312  if (!m_TopSeqEntry)
313  return;
314  set<wxString> existing;
315  vector<const objects::CFeatListItem *> feat_list = GetSortedFeatList(m_TopSeqEntry);
316  ITERATE(vector<const objects::CFeatListItem *>, ft_it, feat_list)
317  {
318  const objects::CFeatListItem& item = **ft_it;
319  wxString desc = wxString(item.GetDescription());
320  int feat_type = item.GetType();
321  int feat_subtype = item.GetSubtype();
322  if (existing.find(desc) == existing.end())
323  {
324  existing.insert(desc);
325  m_FeatureTypeStrings.Add(desc);
326  m_feat_types.push_back(feat_type);
327  m_feat_subtypes.push_back(feat_subtype);
328  }
329  }
330 }
331 
333 {
334  if (!m_TopSeqEntry)
335  return;
336 
338  m_FeatTree = new feature::CFeatTree(f);
339 
343 }
344 
345 
347 {
348  long item = -1;
349  for (;;)
350  {
351  item = m_FeatureType->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
352  if (item == -1) break;
353  string name = ToStdString(m_FeatureType->GetItemText(item));
354  if (NStr::EqualNocase(name, "All")) {
355  return true;
356  } else {
358  if (match == subtype) {
359  return true;
360  }
361  }
362  }
363  return false;
364 }
365 
366 string CAdjustFeaturesForGaps::x_Action(edit::CFeatGapInfo& fgap)
367 {
368  if ((fgap.HasKnown() && m_KnownGap->GetValue()) ||
369  (fgap.HasUnknown() && m_UnknownGap->GetValue()) ||
370  (fgap.HasNs() && m_Ns->GetValue())) {
371  if (fgap.ShouldRemove() && m_RemoveFeats->GetValue()) {
372  return "remove";
373  } else {
374  string rval = kEmptyStr;
375  if (fgap.Trimmable() && m_TrimEnds->GetValue()) {
376  rval = "trim";
377  }
378  if (fgap.Splittable() && m_SplitForInternal->GetValue()) {
379  if (!rval.empty()) {
380  rval += ";";
381  }
382  rval += "split";
383  }
384  return rval;
385  }
386  } else {
387  return kEmptyStr;
388  }
389 }
390 
391 
392 bool CAdjustFeaturesForGaps::x_Adjustable(edit::CFeatGapInfo& fgap)
393 {
394  if (((fgap.HasKnown() && m_KnownGap->GetValue()) ||
395  (fgap.HasUnknown() && m_UnknownGap->GetValue()) ||
396  (fgap.HasNs() && m_Ns->GetValue())) &&
397  ((fgap.Trimmable() && m_TrimEnds->GetValue()) ||
398  (fgap.Splittable() && m_SplitForInternal->GetValue())))
399  {
400 
401  if (x_IsFeatureTypeSelected(fgap.GetFeature().GetData().GetSubtype())) {
402  return true;
403  } else {
404  return false;
405  }
406  } else if (fgap.ShouldRemove() && m_RemoveFeats->GetValue()) {
407  if (x_IsFeatureTypeSelected(fgap.GetFeature().GetData().GetSubtype())) {
408  return true;
409  } else {
410  return false;
411  }
412  } else {
413  return false;
414  }
415 }
416 
417 
419 {
421  return;
422  m_FeatureCountText->SetLabelText(wxEmptyString);
423  m_Features->DeleteAllItems();
424  size_t internal_gap = 0;
425  for (size_t i = 0; i < m_GappedFeatureList.size(); i++)
426  {
427  if (m_GappedFeatureList[i]->Splittable()) {
428  internal_gap++;
429  }
431  objects::CSeq_feat_Handle fh = m_GappedFeatureList[i]->GetFeature();
432 
433  string name, desc, location;
434  GetTextForFeature(fh, name, desc, location);
435  string action = x_Action(*(m_GappedFeatureList[i]));
436 
437  long itemIndex = m_Features->InsertItem(0, wxString(name));
438  m_Features->SetItem(itemIndex, 1, wxString(desc));
439  m_Features->SetItem(itemIndex, 2, wxString(action));
440  m_Features->SetItem(itemIndex, 3, wxString(location));
441  }
442  }
443  size_t num_items = m_Features->GetItemCount();
444  if (num_items > 0 || internal_gap > 0)
445  {
446  wxString feat_count;
447  if (num_items > 0) {
448  feat_count << num_items;
449  if (num_items > 1)
450  feat_count << " features will be adjusted";
451  else
452  feat_count << " feature will be adjusted";
453  }
454  m_FeatureCountText->SetLabelText(feat_count);
455  Layout();
456  }
457 }
458 
459 void CAdjustFeaturesForGaps::GetTextForFeature(objects::CSeq_feat_Handle fh, string &name, string &desc, string &location)
460 {
461  string locus_tag;
462  edit::GetTextObjectDescription(*fh.GetOriginalSeq_feat(), fh.GetScope(), name, desc, location, locus_tag);
463 }
464 
465 /*
466  * Should we show tooltips?
467  */
468 
470 {
471  return true;
472 }
473 
474 /*
475  * Get bitmap resources
476  */
477 
478 wxBitmap CAdjustFeaturesForGaps::GetBitmapResource( const wxString& name )
479 {
480  // Bitmap retrieval
481 ////@begin CAdjustFeaturesForGaps bitmap retrieval
482  wxUnusedVar(name);
483  return wxNullBitmap;
484 ////@end CAdjustFeaturesForGaps bitmap retrieval
485 }
486 
487 /*
488  * Get icon resources
489  */
490 
491 wxIcon CAdjustFeaturesForGaps::GetIconResource( const wxString& name )
492 {
493  // Icon retrieval
494 ////@begin CAdjustFeaturesForGaps icon retrieval
495  wxUnusedVar(name);
496  return wxNullIcon;
497 ////@end CAdjustFeaturesForGaps icon retrieval
498 }
499 
501 {
504 }
505 
506 
508 {
509  if (!m_KnownGap || !m_UnknownGap || !m_Ns) {
510  return;
511  }
512  bool show_known = m_KnownGap->GetValue();
513  bool show_unknown = m_UnknownGap->GetValue();
514  bool show_ns = m_Ns->GetValue();
515 
517  (*it)->CalculateRelevantIntervals(show_unknown, show_known, show_ns);
518  }
519 }
520 
521 
523 {
527 }
528 
529 void CAdjustFeaturesForGaps::OnTrimSelected(wxCommandEvent& event)
530 {
533 }
534 
535 
536 void CAdjustFeaturesForGaps::OnRemoveSelected(wxCommandEvent& event)
537 {
540 }
541 
542 
543 void CAdjustFeaturesForGaps::OnSplitSelected(wxCommandEvent& event)
544 {
545  if (m_SplitForInternal->GetValue())
546  {
547  m_EvenIfIntrons->Enable();
548  }
549  else
550  {
551  m_EvenIfIntrons->Disable();
552  }
555 }
556 
558 {
559  if ((m_SplitForInternal->GetValue() || m_TrimEnds->GetValue() || m_RemoveFeats->GetValue()) &&
560  m_Features->GetItemCount() > 0)
561  {
562  m_AcceptButton->Enable();
563  }
564  else
565  {
566  m_AcceptButton->Disable();
567  }
568 }
569 
570 void CAdjustFeaturesForGaps::OnMakeReport( wxCommandEvent& event)
571 {
572  size_t num_adjustable = 0, num_internal = 0;
573  for (size_t i = 0; i < m_GappedFeatureList.size(); i++)
574  {
576  num_adjustable++;
577  }
578  if (m_GappedFeatureList[i]->Splittable()) {
579  num_internal++;
580  }
581  }
582  if (num_adjustable == 0 && num_internal == 0) {
583  wxMessageBox(_("No features found"), wxT("Error"), wxOK|wxICON_ERROR);
584  return;
585  }
586 
587  wxFileDialog save_file(this, wxT("Make report"), wxEmptyString, wxEmptyString,
589  wxFD_SAVE|wxFD_OVERWRITE_PROMPT);
590 
591  if (save_file.ShowModal() == wxID_OK)
592  {
593  wxString path = save_file.GetPath();
594  if( !path.IsEmpty())
595  {
596  string lb(wxString(wxTextFile::GetEOL()).ToStdString());
597  ios::openmode mode = ios::out;
598  CNcbiOfstream os(path.fn_str(), mode);
599  if (num_adjustable > 0)
600  {
601  os << num_adjustable;
602  if (num_adjustable > 1)
603  os << " features will be adjusted" << lb;
604  else
605  os <<" feature will be adjusted" << lb;
606 
607  for (size_t i = 0; i < m_GappedFeatureList.size(); i++)
608  {
610  string name, desc, location;
611  GetTextForFeature(m_GappedFeatureList[i]->GetFeature(), name, desc, location);
612  os << name << "\t" << desc << "\t" << location << lb;
613  }
614  }
615  if (num_internal > 0)
616  os << lb;
617  }
618  if (num_internal > 0)
619  {
620  os << num_internal;
621  if (num_internal > 1)
622  os << " features contain internal gaps" << lb;
623  else
624  os << " feature contains internal gaps" << lb;
625  for (size_t i = 0; i < m_GappedFeatureList.size(); i++)
626  {
627  if (m_GappedFeatureList[i]->Splittable()) {
628  string name, desc, location;
629  GetTextForFeature(m_GappedFeatureList[i]->GetFeature(), name, desc, location);
630  os << name << "\t" << desc << "\t" << location << lb;
631  }
632  }
633  }
634  }
635  }
636 }
637 
638 
639 CAdjustFeaturesForGaps::TFeatUpdatePairVector CAdjustFeaturesForGaps::x_PullRelatedGroup(edit::TGappedFeatList &to_edit, bool always, bool unless_pseudo, bool do_trim, bool do_split, bool split_intron, bool create_general_only)
640 {
641  CRef<edit::CFeatGapInfo> top = to_edit[0];
643  bool make_partial = (always || (unless_pseudo && !(top->GetFeature().IsSetPseudo() && top->GetFeature().GetPseudo())));
644  grp.push_back(TFeatUpdatePair(top, top->AdjustForRelevantGapIntervals(make_partial, do_trim, do_split, split_intron, create_general_only)));
645  to_edit.erase(to_edit.begin());
646  size_t check_index = 0;
647  while (check_index < grp.size()) {
648  CRef<edit::CFeatGapInfo> top = grp[check_index].first;
649  edit::TGappedFeatList::iterator cand = to_edit.begin();
650  while (cand != to_edit.end()) {
651  if (top->IsRelatedByCrossRef(**cand)) {
652  bool make_partial = (always || (unless_pseudo && !((*cand)->GetFeature().IsSetPseudo() && (*cand)->GetFeature().GetPseudo())));
653  grp.push_back(TFeatUpdatePair(*cand, (*cand)->AdjustForRelevantGapIntervals(make_partial, do_trim, do_split, split_intron, create_general_only)));
654  cand = to_edit.erase(cand);
655  } else {
656  ++cand;
657  }
658  }
659  check_index++;
660  }
661 
662  return grp;
663 }
664 
665 
667  map<CObject_id::TId, CObject_id::TId> &old_to_new, bool create_xref_map)
668 {
670  if (it->second.size() > 1) {
671  edit::FixFeatureIdsForUpdates(it->second, next_id);
672  }
673  }
675  TFeatUpdatePairVector::iterator it2 = it1;
676  ++it2;
677  while (it2 != grp.end()) {
678  edit::FixFeatureIdsForUpdatePair(it1->second, it2->second);
679  ++it2;
680  }
681  x_DoOne(*it1, next_id, cmd, old_to_new, create_xref_map);
682  }
683 
684 }
685 
687 {
688  CSeq_feat_Handle fh = p.first->GetFeature();
689  CScope& scope = fh.GetScope();
690  vector<CRef<CSeq_feat> > updates = p.second;
691  if (updates.empty() || (p.first->ShouldRemove() && m_RemoveFeats->GetValue())) {
692  CRef<CCmdDelSeq_feat> cmd_del(new CCmdDelSeq_feat(fh));
693  if (cmd_del)
694  {
695  cmd.AddCommand(*cmd_del);
696  }
697  } else if (fh.GetData().IsCdregion()) {
698  // safer just to add all new coding regions
699  const objects::CSeq_annot_Handle& feat_annot_handle = fh.GetAnnot();
700  objects::CSeq_entry_Handle feat_seh = feat_annot_handle.GetParentEntry();
701  if (!feat_seh.IsSet()) {
702  CBioseq_set_Handle bssh = feat_seh.GetParentBioseq_set();
703  if (bssh && bssh.IsSetClass() && bssh.GetClass() == CBioseq_set::eClass_nuc_prot) {
704  feat_seh = bssh.GetParentEntry();
705  }
706  }
707 
708  CRef< CCmdChangeSeq_feat > change_feat(new CCmdChangeSeq_feat(fh, *(updates.front())));
709  if (change_feat)
710  {
711  cmd.AddCommand(*change_feat);
712  }
713  if (fh.IsSetProduct())
714  {
715  const CSeq_id *id = fh.GetProduct().GetId();
716  if (id)
717  {
718  CBioseq_Handle prot_bsh = scope.GetBioseqHandle(*id);
719  if (prot_bsh)
720  {
721  string prot;
722  try
723  {
724  CSeqTranslator::Translate(*(updates.front()), scope, prot);
725  }
726  catch (const CSeqVectorException&) {}
727 
728  if (!prot.empty())
729  {
730  if (NStr::EndsWith(prot, "*"))
731  {
732  prot = prot.substr(0, prot.length() - 1);
733  }
734  CRef<CBioseq> prot_seq(new CBioseq);
735  prot_seq->Assign(*(prot_bsh.GetCompleteBioseq()));
736  prot_seq->SetInst().ResetExt();
737  prot_seq->SetInst().SetRepr(objects::CSeq_inst::eRepr_raw);
738  prot_seq->SetInst().SetSeq_data().SetIupacaa().Set(prot);
739  prot_seq->SetInst().SetLength(TSeqPos(prot.length()));
740  prot_seq->SetInst().SetMol(CSeq_inst::eMol_aa);
741  CRef<CCmdChangeBioseqInst> chgInst(new CCmdChangeBioseqInst(prot_bsh, prot_seq->SetInst()));
742  cmd.AddCommand(*chgInst);
743  objects::CFeat_CI prot_feat_ci(prot_bsh, objects::SAnnotSelector(objects::CSeqFeatData::eSubtype_prot));
744  if (prot_feat_ci)
745  {
746  CRef<objects::CSeq_feat> prot_feat(new objects::CSeq_feat());
747  prot_feat->Assign(*(prot_feat_ci->GetSeq_feat()));
748  prot_feat->ResetLocation();
749  prot_feat->SetLocation().SetInt().SetId().Assign(*(prot_seq->GetId().front()));
750  prot_feat->SetLocation().SetInt().SetFrom(0);
751  prot_feat->SetLocation().SetInt().SetTo(prot_seq->GetLength() - 1);
752  edit::AdjustProteinFeaturePartialsToMatchCDS(*prot_feat, *(updates.front()));
753  CIRef<IEditCommand> chgFeat(new CCmdChangeSeq_feat(prot_feat_ci->GetSeq_feat_Handle(), *prot_feat));
754  cmd.AddCommand(*chgFeat);
755  }
756  bool modified;
757  CRef<CCmdComposite> composite(&cmd);
758  NRawToDeltaSeq::RemapOtherProtFeats(*fh.GetOriginalSeq_feat(), *(updates.front()), prot_bsh, composite, modified);
759  }
760  else
761  {
762  CRef<CCmdDelBioseqInst> delInst(new CCmdDelBioseqInst(prot_bsh));
763  cmd.AddCommand(*delInst);
764  }
765  }
766  }
767  }
768 
769  for (size_t offset = 1; offset < updates.size(); offset++) {
770  CRef<CSeq_feat> new_feat = updates[offset];
771  CRef<objects::CSeq_feat> prot_feat;
772  objects::CBioseq_Handle product = scope.GetBioseqHandle(fh.GetProduct());
773  vector<CRef<CSeq_feat> > other_prot_feats;
774  vector<CRef<objects::CSeq_id> > new_prot_id;
775  CRef<objects::CSeq_id> new_id(new objects::CSeq_id);
776  new_id->Assign(new_feat->GetProduct().GetWhole());
777  new_prot_id.push_back(new_id);
778 
779  if (product)
780  {
781  for (objects::CFeat_CI prot_feat_ci(product); prot_feat_ci; ++prot_feat_ci)
782  {
783  if (prot_feat_ci->GetSeq_feat_Handle().GetFeatSubtype() == objects::CSeqFeatData::eSubtype_prot)
784  {
785  prot_feat.Reset(new objects::CSeq_feat());
786  prot_feat->Assign(*(prot_feat_ci->GetSeq_feat()));
787  if (offset > 0)
788  {
789  edit::FixFeatureIdsForUpdates(*prot_feat, next_id);
790  }
791  }
792  else
793  {
794  --next_id;
795  NRawToDeltaSeq::RemapOtherProtFeats(*fh.GetOriginalSeq_feat(), *new_feat, prot_feat_ci->GetSeq_feat_Handle(), other_prot_feats, next_id, old_to_new, create_xref_map);
796  ++next_id;
797  }
798  }
799  }
800  cmd.AddCommand(*CRef<CCmdCreateCDS>(new CCmdCreateCDS(feat_seh, *new_feat, prot_feat, new_prot_id, other_prot_feats)));
801  }
802  } else {
803  CRef< CCmdChangeSeq_feat > change_feat(new CCmdChangeSeq_feat(fh, *(updates.front())));
804  if (change_feat)
805  {
806  cmd.AddCommand(*change_feat);
807  }
808  const objects::CSeq_annot_Handle& feat_annot_handle = fh.GetAnnot();
809  objects::CSeq_entry_Handle feat_seh = feat_annot_handle.GetParentEntry();
810  for (size_t offset = 1; offset < updates.size(); offset++) {
811  CRef<CSeq_feat> new_feat = updates[offset];
812  CRef<CCmdCreateFeat> cmd_add_feat(new CCmdCreateFeat(feat_seh, *new_feat));
813  cmd.AddCommand(*cmd_add_feat);
814  }
815  }
816 }
817 
818 
820 {
821  ITERATE(edit::TGappedFeatList, it, to_do) {
822  if ((*it)->GetFeature() == feat) {
823  return *it;
824  }
825  }
827 }
828 
829 
830 // if trimming, need to adjust genes even if not selected
832 {
833  edit::TGappedFeatList genes_to_trim;
834  ITERATE(edit::TGappedFeatList, it, to_do) {
835  CSeq_feat_Handle fh = (*it)->GetFeature();
836  if (!fh.GetData().IsGene()) {
837  CSeq_feat_Handle gene = m_FeatTree->GetBestGene(fh);
838  if (gene && !s_ListHasFeature(gene, to_do)) {
840  if (add) {
841  genes_to_trim.push_back(add);
842  }
843  }
844  }
845  }
846  return genes_to_trim;
847 }
848 
849 
851 {
853 
854  edit::TGappedFeatList::reverse_iterator rit = m_GappedFeatureList.rbegin();
855  while (rit != m_GappedFeatureList.rend() &&
856  !x_Adjustable(**rit)) {
857  rit++;
858  }
859  size_t shown_feat_offset = 0;
860  long item = -1;
861  for (;;)
862  {
863  item = m_Features->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
864  if (item == -1) break;
865  while (shown_feat_offset < item) {
866  rit++;
867  while (rit != m_GappedFeatureList.rend() && !x_Adjustable(**rit)) {
868  rit++;
869  }
870  if (rit == m_GappedFeatureList.rend()) {
871  break;
872  }
873  shown_feat_offset++;
874  }
875  if (item == shown_feat_offset) {
876  rval.push_back(*rit);
877  }
878  }
879  return rval;
880 }
881 
883 {
885  bool create_xref_map = true;
886  GetCommand_impl(old_to_new, create_xref_map);
887  create_xref_map = false;
888  return GetCommand_impl(old_to_new, create_xref_map);
889 }
890 
892 {
893  CRef<CCmdComposite> cmd(new CCmdComposite("Adjust Features for Gaps"));
894  objects::CScope &scope = m_TopSeqEntry.GetScope();
895  bool create_general_only = objects::edit::IsGeneralIdProtPresent(m_TopSeqEntry);
896  int partial_sel = m_MakeTruncatedPartial->GetSelection();
897  if (partial_sel == wxNOT_FOUND)
898  return cmd;
899  string partial_sel_str = m_MakeTruncatedPartial->GetString(partial_sel).ToStdString();
900  bool always = false;
901  bool unless_pseudo = false;
902  if (partial_sel_str == "Always")
903  always = true;
904  else if (partial_sel_str == "Unless pseudo")
905  unless_pseudo = true;
906 
907  bool do_trim = m_TrimEnds->GetValue();
908  bool do_remove = m_RemoveFeats->GetValue();
909  bool do_split = m_SplitForInternal->GetValue();
910  bool split_intron = false;
911  if (do_split) {
912  split_intron = m_EvenIfIntrons->GetValue();
913  }
914 
915  edit::TGappedFeatList to_do;
916  if (m_Features->GetSelectedItemCount() == 0) {
918  if (x_Adjustable(**it)) {
919  to_do.push_back(*it);
920  }
921  }
922  } else {
923  to_do = x_GetSelectedFeatures();
924  }
925 
926  CObject_id::TId next_id = m_TopFeatureId + 1;
927 
928  if (do_trim) {
929  edit::TGappedFeatList genes_to_trim = x_GetGenesForFeatures(to_do);
930  NON_CONST_ITERATE(edit::TGappedFeatList, it, genes_to_trim) {
932  bool make_partial = (always || (unless_pseudo && !((*it)->GetFeature().IsSetPseudo() && (*it)->GetFeature().GetPseudo())));
933  grp.push_back(TFeatUpdatePair(*it, (*it)->AdjustForRelevantGapIntervals(make_partial, do_trim, false, false, create_general_only)));
934  x_DoGroup(grp, next_id, *cmd, old_to_new, create_xref_map);
935  }
936  }
937 
938  while (!to_do.empty()) {
939  TFeatUpdatePairVector grp = x_PullRelatedGroup(to_do, always, unless_pseudo, do_trim, do_split, split_intron, create_general_only);
940  x_DoGroup(grp, next_id, *cmd, old_to_new, create_xref_map);
941  }
942 
943  return cmd;
944 }
945 
946 
948 {
952 }
953 
954 
User-defined methods of the data storage class.
User-defined methods of the data storage class.
USING_SCOPE(objects)
CRef< edit::CFeatGapInfo > s_ListHasFeature(CSeq_feat_Handle feat, const edit::TGappedFeatList &to_do)
EVT_CHECKBOX(ID_CADJUSTFEATURES_CHECKBOX, CAdjustFeaturesForGaps::OnKnownUnknownSelected) EVT_CHECKBOX(ID_CADJUSTFEATURES_CHECKBOX1
#define ID_CADJUSTFEATURES_BUTTON2
#define ID_CADJUSTFEATURES_CHECKBOX5
#define ID_CADJUSTFEATURES_CHECKBOX1
#define ID_CADJUSTFEATURES_CHECKBOX3
#define ID_CADJUSTFEATURES_CHECKBOX
#define ID_CADJUSTFEATURES_LISTCTRL
#define ID_CADJUSTFEATURES_CHECKBOX_NS
#define ID_CADJUSTFEATURES_LISTBOX
#define ID_CADJUSTFEATURES_CHECKBOX4
#define ID_CADJUSTFEATURES_RADIOBOX
#define ID_CADJUSTFEATURES_CHECKBOX2
bool AdjustProteinFeaturePartialsToMatchCDS(CSeq_feat &new_prot, const CSeq_feat &cds)
AdjustProteinFeaturePartialsToMatchCDS A function to change an existing MolInfo to match a coding reg...
Definition: cds_fix.cpp:398
bool IsGeneralIdProtPresent(objects::CSeq_entry_Handle tse)
void OnSplitSelected(wxCommandEvent &event)
CRef< objects::feature::CFeatTree > m_FeatTree
bool x_Adjustable(objects::edit::CFeatGapInfo &fgap)
objects::CSeq_entry_Handle m_TopSeqEntry
objects::edit::TGappedFeatList x_GetGenesForFeatures(const objects::edit::TGappedFeatList &to_do)
void OnRemoveSelected(wxCommandEvent &event)
bool Create(wxWindow *parent, wxWindowID id=10000, const wxString &caption=_("Adjust Features For Gaps"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(400, 300), long style=wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU|wxCLOSE_BOX|wxTAB_TRAVERSAL)
Creation.
static bool ShowToolTips()
Should we show tooltips?
void OnTrimSelected(wxCommandEvent &event)
objects::edit::TGappedFeatList m_GappedFeatureList
void OnKnownUnknownSelected(wxCommandEvent &event)
TFeatUpdatePairVector x_PullRelatedGroup(objects::edit::TGappedFeatList &to_edit, bool always, bool unless_pseudo, bool do_trim, bool do_split, bool split_intron, bool create_general_only)
void OnMakeReport(wxCommandEvent &event)
void x_DoGroup(TFeatUpdatePairVector grp, objects::CObject_id::TId &next_id, CCmdComposite &cmd, map< objects::CObject_id::TId, objects::CObject_id::TId > &old_to_new, bool create_xref_map)
void GetTextForFeature(objects::CSeq_feat_Handle fh, string &name, string &desc, string &location)
void x_DoOne(TFeatUpdatePair &p, objects::CObject_id::TId &next_id, CCmdComposite &cmd, map< objects::CObject_id::TId, objects::CObject_id::TId > &old_to_new, bool create_xref_map)
string x_Action(objects::edit::CFeatGapInfo &fgap)
bool x_IsFeatureTypeSelected(objects::CSeqFeatData::ESubtype subtype)
void CreateControls()
Creates the controls and sizers.
CRef< CCmdComposite > GetCommand()
CRef< CCmdComposite > GetCommand_impl(map< objects::CObject_id::TId, objects::CObject_id::TId > &old_to_new, bool create_xref_map)
pair< CRef< objects::edit::CFeatGapInfo >, vector< CRef< objects::CSeq_feat > > > TFeatUpdatePair
wxIcon GetIconResource(const wxString &name)
Retrieves icon resources.
objects::CObject_id::TId m_TopFeatureId
void OnFeatTypeChanged(wxListEvent &event)
void Init()
Initialises member variables.
objects::edit::TGappedFeatList x_GetSelectedFeatures()
wxBitmap GetBitmapResource(const wxString &name)
Retrieves bitmap resources.
vector< TFeatUpdatePair > TFeatUpdatePairVector
CBioseq_Handle –.
CBioseq_set_Handle –.
TSeqPos GetLength(void) const
Definition: Bioseq.cpp:360
CFeat_CI –.
Definition: feat_ci.hpp:64
static wxString GetDialogFilter(EFileType fileType)
static TId s_FindHighestFeatureId(const objects::CSeq_entry_Handle &entry)
CRef –.
Definition: ncbiobj.hpp:618
CScope –.
Definition: scope.hpp:92
static ESubtype SubtypeNameToValue(CTempString sName)
Turn a string into its ESubtype which is NOT necessarily related to the identifier of the enum.
SeqVector related exceptions.
CSeq_feat_Handle –.
Definition: set.hpp:45
iterator_bool insert(const value_type &val)
Definition: set.hpp:149
const_iterator find(const key_type &key) const
Definition: set.hpp:137
const_iterator end() const
Definition: set.hpp:136
void RemapOtherProtFeats(const objects::CSeq_feat &old_cds, objects::CSeq_feat &cds, objects::CBioseq_Handle bh, CRef< CCmdComposite > composite, bool &any_actions)
#define _(proto)
Definition: ct_nlmzip_i.h:78
std::ofstream out("events_result.xml")
main entry point for tests
static CS_COMMAND * cmd
Definition: ct_dynamic.c:26
static char col1[256]
Definition: compute.c:13
static char col2[256]
Definition: compute.c:13
static void Init(void)
Definition: cursor6.c:76
int offset
Definition: replacements.h:160
static const char location[]
Definition: config.c:97
TGappedFeatList ListGappedFeatures(CFeat_CI &feat_it, CScope &scope)
Definition: gap_trim.cpp:625
void FixFeatureIdsForUpdatePair(vector< CRef< CSeq_feat > > &updates1, vector< CRef< CSeq_feat > > &updates2)
Definition: gap_trim.cpp:743
void FixFeatureIdsForUpdates(vector< CRef< CSeq_feat > > updates, objects::CObject_id::TId &next_id)
vector< CRef< CFeatGapInfo > > TGappedFeatList
Definition: gap_trim.hpp:124
unsigned int TSeqPos
Type for sequence locations and lengths.
Definition: ncbimisc.hpp:875
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
#define NON_CONST_ITERATE(Type, Var, Cont)
Non constant version of ITERATE macro.
Definition: ncbimisc.hpp:822
#define NULL
Definition: ncbistd.hpp:225
vector< const objects::CFeatListItem * > GetSortedFeatList(objects::CSeq_entry_Handle seh, size_t max=numeric_limits< size_t >::max())
virtual void Assign(const CSerialObject &source, ESerialRecursionMode how=eRecursive)
Set object to copy of another one.
const CSeq_id * GetId(void) const
Get the id of the location return NULL if has multiple ids or no id at all.
Definition: Seq_loc.hpp:941
static void Translate(const string &seq, string &prot, const CGenetic_code *code, bool include_stop=true, bool remove_trailing_X=false, bool *alt_start=NULL, bool is_5prime_complete=true, bool is_3prime_complete=true)
Translate a string using a specified genetic code.
Definition: sequence.cpp:4095
CBioseq_Handle GetBioseqHandle(const CSeq_id &id)
Get bioseq handle by seq-id.
Definition: scope.cpp:95
CConstRef< CBioseq > GetCompleteBioseq(void) const
Get the complete bioseq.
TClass GetClass(void) const
const CSeq_annot_Handle & GetAnnot(void) const
Get handle to seq-annot for this feature.
const CSeqFeatData & GetData(void) const
virtual const CSeq_loc & GetProduct(void) const
CBioseq_set_Handle GetParentBioseq_set(void) const
Return a handle for the parent Bioseq-set, or null handle.
bool IsSetProduct(void) const
CSeq_entry_Handle GetParentEntry(void) const
Get parent Seq-entry handle.
CSeq_entry_Handle GetParentEntry(void) const
Return a handle for the parent seq-entry of the bioseq.
bool IsSetClass(void) const
CScope & GetScope(void) const
Get scope this handle belongs to.
CConstRef< CSeq_feat > GetOriginalSeq_feat(void) const
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:773
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
IO_PREFIX::ofstream CNcbiOfstream
Portable alias for ofstream.
Definition: ncbistre.hpp:500
#define kEmptyStr
Definition: ncbistr.hpp:123
static bool EndsWith(const CTempString str, const CTempString end, ECase use_case=eCase)
Check if a string ends with a specified suffix value.
Definition: ncbistr.hpp:5430
static bool EqualNocase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-insensitive equality of a substring with another string.
Definition: ncbistr.hpp:5353
bool IsCdregion(void) const
Check if variant Cdregion is selected.
bool IsGene(void) const
Check if variant Gene is selected.
const TProduct & GetProduct(void) const
Get the Product member data.
Definition: Seq_feat_.hpp:1096
const TWhole & GetWhole(void) const
Get the variant data.
Definition: Seq_loc_.cpp:172
@ eClass_nuc_prot
nuc acid and coded proteins
Definition: Bioseq_set_.hpp:99
const TId & GetId(void) const
Get the Id member data.
Definition: Bioseq_.hpp:290
void SetInst(TInst &value)
Assign a value to Inst data member.
Definition: Bioseq_.cpp:86
END_EVENT_TABLE()
int i
#define wxT(x)
Definition: muParser.cpp:41
mdb_mode_t mode
Definition: lmdb++.h:38
const struct ncbi::grid::netcache::search::fields::SIZE size
double f(double x_, const double &y_)
Definition: njn_root.hpp:188
static int match(register const pcre_uchar *eptr, register const pcre_uchar *ecode, const pcre_uchar *mstart, int offset_top, match_data *md, eptrblock *eptrb, unsigned int rdepth)
Definition: pcre_exec.c:513
static static static wxID_ANY
string GetTextObjectDescription(const CSeq_feat &sf, CScope &scope)
string ToStdString(const wxString &s)
Definition: wx_utils.hpp:161
Modified on Mon May 13 04:34:29 2024 by modify_doxy.py rev. 669887