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

Go to the SVN repository for this file.

1 /* $Id: fuse_features.cpp 42192 2019-01-10 16:52:15Z filippov $
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 ////@begin includes
33 ////@end includes
34 #include <sstream>
35 #include <objmgr/scope.hpp>
37 #include <objmgr/feat_ci.hpp>
38 #include <objmgr/seq_annot_ci.hpp>
39 #include <objmgr/bioseq_ci.hpp>
41 #include <objmgr/util/feature.hpp>
47 #include <gui/objutils/utils.hpp>
52 
53 #include <util/xregexp/regexp.hpp>
54 
55 #include <wx/button.h>
56 #include <wx/statbox.h>
57 #include <wx/msgdlg.h>
58 
59 ////@begin XPM images
60 ////@end XPM images
61 
63 
64 
65 
66 IMPLEMENT_DYNAMIC_CLASS( CFuseFeaturesDlg, CBulkCmdDlg )
67 
68 
69 BEGIN_EVENT_TABLE( CFuseFeaturesDlg, CBulkCmdDlg )
72 
74 {
75  Init();
76 }
77 
79  wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
80  : CBulkCmdDlg(wb)
81 {
82  Init();
83  Create(parent, id, caption, pos, size, style);
84 }
85 
86 
87 bool CFuseFeaturesDlg::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
88 {
89  SetExtraStyle(wxWS_EX_BLOCK_EVENTS);
90  CBulkCmdDlg::Create( parent, id, caption, pos, size, style );
91 
93  if (GetSizer())
94  {
95  GetSizer()->SetSizeHints(this);
96  }
97  Centre();
98 
99 
100  return true;
101 }
102 
103 
105 {
106 }
107 
108 
109 /*!
110  * Member initialisation
111  */
112 
114 {
115 
116 }
117 
118 
119 
120 
122 {
123  CFuseFeaturesDlg* itemDialog1 = this;
124 
125  wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
126  itemDialog1->SetSizer(itemBoxSizer2);
127 
128  m_FeatureType = new CFeatureTypePanel(itemDialog1, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0);
129  itemBoxSizer2->Add(m_FeatureType, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 0);
131 
132  m_FeatureConstraint = new CFeatureFieldNamePanel(itemDialog1, NULL, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0);
133  itemBoxSizer2->Add(m_FeatureConstraint, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 0);
135 
136  m_StringConstraintPanel = new CStringConstraintPanel( itemDialog1, false, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
137  itemBoxSizer2->Add(m_StringConstraintPanel, 0, wxALIGN_LEFT|wxALL, 0);
138 
139  COkCancelPanel *OkCancel = new COkCancelPanel( itemDialog1, ID_FUSE_FEATURES_OKCANCEL, wxDefaultPosition, wxSize(100, 100), 0 );
140  itemBoxSizer2->Add(OkCancel, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
141 }
142 
143 
144 /*!
145  * Should we show tooltips?
146  */
147 
149 {
150  return true;
151 }
152 
153 /*!
154  * Get bitmap resources
155  */
156 
157 wxBitmap CFuseFeaturesDlg::GetBitmapResource( const wxString& name )
158 {
159  // Bitmap retrieval
160  wxUnusedVar(name);
161  return wxNullBitmap;
162 }
163 
164 /*!
165  * Get icon resources
166  */
167 
168 wxIcon CFuseFeaturesDlg::GetIconResource( const wxString& name )
169 {
170  // Icon retrieval
171  wxUnusedVar(name);
172  return wxNullIcon;
173 }
174 
176 {
177  CRef<CCmdComposite> cmd( new CCmdComposite("Fuse Features") );
178  bool modified = false;
180  CScope &scope = m_TopSeqEntry.GetScope();
181 
182  string field_name = m_FeatureType->GetFieldName(true);
183  if (field_name.empty())
184  return empty;
185  int itype, isubtype;
186  if (!CSeqFeatData::GetFeatList()->GetTypeSubType(field_name, itype, isubtype))
187  return empty;
188  CSeqFeatData::ESubtype subtype = static_cast<CSeqFeatData::ESubtype>(isubtype);
189 
190  if (NStr::IsBlank(field_name)) {
191  field_name = kPartialStart;
192  } else {
193  field_name += " " + kPartialStart;
194  }
195 
196  vector<CSeq_feat_Handle> entry_handles;
198  string constraint_field = m_FeatureConstraint->GetFieldName(false);
199  if (constraint && !constraint_field.empty())
200  {
201  CRef<CMiscSeqTableColumn> col(new CMiscSeqTableColumn(field_name));
202  vector<CRef<edit::CApplyObject> > objects = col->GetApplyObjects(m_TopSeqEntry, constraint_field, constraint);
203  ITERATE(vector<CRef<edit::CApplyObject> >, obj_it, objects)
204  {
205  const CSeq_feat *feat = dynamic_cast<const CSeq_feat*> ( (*obj_it)->GetOriginalObject() );
206 
207  if (feat)
208  {
209  if (feat->IsSetData() && feat->GetData().IsCdregion() &&
210  feat->IsSetExcept_text() && NStr::Find(feat->GetExcept_text(), "RNA editing") != string::npos)
211  {
212  continue;
213  }
215  if (fh)
216  {
217  entry_handles.push_back(fh);
218  }
219  }
220  }
221  }
222  else
223  {
224  for (CFeat_CI feat(m_TopSeqEntry, SAnnotSelector(subtype)); feat; ++feat)
225  {
226  const CSeq_feat& cds = feat->GetOriginalFeature();
227  if (cds.IsSetData() && cds.GetData().IsCdregion() &&
228  cds.IsSetExcept_text() && NStr::Find(cds.GetExcept_text(), "RNA editing") != string::npos)
229  {
230  continue;
231  }
232  entry_handles.push_back(feat->GetSeq_feat_Handle());
233  }
234  }
235 
236 
237  set< CSeq_feat_Handle > deleted_feats;
238  int offset = 1;
239  bool create_general_only = objects::edit::IsGeneralIdProtPresent(m_TopSeqEntry);
240  for (size_t i = 0; i < entry_handles.size(); i++)
241  {
242  CSeq_feat_Handle feat1 = entry_handles[i];
243  if (deleted_feats.find(feat1) == deleted_feats.end())
244  {
245  CRef<CSeq_loc> new_loc(new CSeq_loc);
246  new_loc->Assign(feat1.GetLocation());
247  bool partial_start = new_loc->IsPartialStart(eExtreme_Positional);
248  bool partial_stop = new_loc->IsPartialStop(eExtreme_Positional);
249  new_loc->SetPartialStart(false,eExtreme_Positional);
250  new_loc->SetPartialStop(false,eExtreme_Positional);
251  bool changed = false;
252  CRef<CSeq_id> new_product_id(NULL);
253  if (feat1.IsSetProduct()) {
254  new_product_id.Reset(new CSeq_id());
255  new_product_id->Assign(*(feat1.GetProduct().GetId()));
256  }
257  for (size_t j = i + 1; j < entry_handles.size(); j++)
258  {
259  CSeq_feat_Handle feat2 = entry_handles[j];
260  if ( deleted_feats.find(feat2) == deleted_feats.end() &&
261  sequence::IsSameBioseq(*feat1.GetLocation().GetId(),*feat2.GetLocation().GetId(),&scope))
262  {
263  CRef<CSeq_loc> add_loc(new CSeq_loc);
264  add_loc->Assign(feat2.GetLocation());
265  partial_stop = add_loc->IsPartialStop(eExtreme_Positional);
266  add_loc->SetPartialStart(false,eExtreme_Positional);
267  add_loc->SetPartialStop(false,eExtreme_Positional);
268  new_loc->Assign(*(sequence::Seq_loc_Add(*new_loc, *add_loc, CSeq_loc::fMerge_All|CSeq_loc::fSort, &scope)));
269  cmd->AddCommand(*CRef<CCmdDelSeq_feat>(new CCmdDelSeq_feat(feat2)));
270  if (feat2.IsSetProduct()) {
271  if (!new_product_id) {
272  new_product_id.Reset(new CSeq_id());
273  new_product_id->Assign(*(feat2.GetProduct().GetId()));
274  } else {
275  CBioseq_Handle product = scope.GetBioseqHandle(feat2.GetProduct());
276  if (product) {
277  cmd->AddCommand(*CRef<CCmdDelBioseqInst>(new CCmdDelBioseqInst(product)));
278  }
279  }
280  }
281  deleted_feats.insert(feat2);
282  changed = true;
283  }
284  }
285  if (changed)
286  {
287  CRef<CSeq_feat> new_feat(new CSeq_feat);
288  new_feat->Assign(*feat1.GetOriginalSeq_feat());
289  new_loc->SetPartialStart(partial_start,eExtreme_Positional);
290  new_loc->SetPartialStop(partial_stop,eExtreme_Positional);
291  new_feat->SetLocation(*new_loc);
292  new_feat->SetPartial(partial_start || partial_stop);
293  if (!new_feat->IsSetProduct() && new_product_id) {
294  new_feat->SetProduct().SetWhole().Assign(*new_product_id);
295  }
296  cmd->AddCommand(*CRef< CCmdChangeSeq_feat > (new CCmdChangeSeq_feat(feat1,*new_feat)));
297  if (subtype == CSeqFeatData::eSubtype_cdregion && new_feat->IsSetProduct())
298  {
299  CRef<CCmdComposite> retranslate_cmd = GetRetranslateCDSCommand(scope, *new_feat, offset, create_general_only);
300  cmd->AddCommand(*retranslate_cmd);
301  }
302  modified = true;
303  }
304  }
305  }
306 
307  if (modified)
308  return cmd;
309  return empty;
310 }
311 
312 
313 void CFuseFeaturesDlg::ProcessUpdateFeatEvent( wxCommandEvent& event )
314 {
315  UpdateChildrenFeaturePanels(this->GetSizer());
316 }
317 
319 {
320  wxSizerItemList& slist = sizer->GetChildren();
321  int n =0;
322  for (wxSizerItemList::iterator iter = slist.begin(); iter != slist.end(); ++iter, ++n) {
323  if ((*iter)->IsSizer()) {
324  UpdateChildrenFeaturePanels((*iter)->GetSizer());
325  } else if ((*iter)->IsWindow()) {
326  wxWindow* child = (*iter)->GetWindow();
327  if (child) {
328  CFeatureTypePanel* panel = dynamic_cast<CFeatureTypePanel*>(child);
329  if (panel) {
331  } else {
332  wxSizer* subsizer = child->GetSizer();
333  if (subsizer) {
334  UpdateChildrenFeaturePanels(subsizer);
335  }
336  }
337  }
338  }
339  }
340 }
341 
342 
344 {
345  CRef<CCmdComposite> composite(new CCmdComposite("Fuse Joins in Feature Locations"));
346  bool modified = false;
347  for (CFeat_CI feat_it(seh); feat_it; ++feat_it)
348  {
349  if (feat_it->GetOriginalFeature().IsSetData())
350  {
351  CRef<CSeq_feat> new_feat(new CSeq_feat);
352  new_feat->Assign(feat_it->GetOriginalFeature());
353  const CSeq_loc& feat_loc = feat_it->GetLocation();
354  CRef<CSeq_loc> new_loc(new CSeq_loc);
355  new_loc->Assign(feat_loc);
356  vector<pair<int,int> > ranges;
357  for (CSeq_loc_CI loc_ci(feat_loc, CSeq_loc_CI::eEmpty_Skip, CSeq_loc_CI::eOrder_Positional); loc_ci; ++loc_ci)
358  {
359  CSeq_loc_CI::TRange feat_range = loc_ci.GetRange();
360  TSeqPos feat_start = feat_range.GetFrom();
361  TSeqPos feat_stop = feat_range.GetTo();
362  ranges.push_back(pair<int, int>(feat_start, feat_stop));
363  }
364  size_t i = 0;
365  for (size_t j = 1; j < ranges.size(); j++)
366  {
367  if (ranges[j].first == ranges[i].second + 1)
368  {
369  ranges[i].second = ranges[j].second;
370  ranges[j].first = -1;
371  ranges[j].second = -1;
372  continue;
373  }
374  i = j;
375  }
376 
377  CSeq_loc_I loc_it(*new_loc); // , CSeq_loc_CI::eEmpty_Skip, CSeq_loc_CI::eOrder_Positional
378  i = 0;
379  while(loc_it)
380  {
381  if (loc_it.IsEmpty())
382  {
383  ++loc_it;
384  continue;
385  }
386  CSeq_loc_CI::TRange feat_range = loc_it.GetRange();
387  TSeqPos feat_start = feat_range.GetFrom();
388  TSeqPos feat_stop = feat_range.GetTo();
389  int new_start = ranges[i].first;
390  int new_stop = ranges[i].second;
391  if (new_start < 0 || new_stop < 0)
392  {
393  loc_it.Delete();
394  ++i;
395  continue;
396  }
397  if (feat_start != new_start)
398  {
399  loc_it.SetFrom(new_start);
400  }
401  if (feat_stop != new_stop)
402  {
403  loc_it.SetTo(new_stop);
404  }
405  ++loc_it;
406  ++i;
407  }
408  CRef<CSeq_loc> loc = loc_it.MakeSeq_loc();
409  if (loc_it.HasChanges())
410  {
411  new_feat->SetLocation(*loc);
412  CRef< CCmdChangeSeq_feat > cmd(new CCmdChangeSeq_feat(feat_it->GetSeq_feat_Handle(),*new_feat));
413  if (cmd)
414  {
415  composite->AddCommand(*cmd);
416  modified = true;
417  }
418 
419  }
420  }
421  }
422  if (!modified)
423  composite.Reset();
424  return composite;
425 }
426 
427 
@ eExtreme_Positional
numerical value
Definition: Na_strand.hpp:63
bool IsGeneralIdProtPresent(objects::CSeq_entry_Handle tse)
CBioseq_Handle –.
objects::CSeq_entry_Handle m_TopSeqEntry
bool Create(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxDEFAULT_FRAME_STYLE, const wxString &name=wxFrameNameStr)
void AddCommand(IEditCommand &command)
CFeat_CI –.
Definition: feat_ci.hpp:64
virtual string GetFieldName(const bool subfield=false)
Returns the name of the field as selected in the panel.
virtual string GetFieldName(const bool subfield=false)
Returns the name of the field as selected in the panel.
void ListPresentFeaturesFirst(const objects::CSeq_entry_Handle &entry, vector< const objects::CFeatListItem * > *featlist=nullptr)
void UpdateChildrenFeaturePanels(wxSizer *sizer)
void CreateControls()
Creates the controls and sizers.
~CFuseFeaturesDlg()
Destructor.
CFeatureTypePanel * m_FeatureType
wxIcon GetIconResource(const wxString &name)
Retrieves icon resources.
wxBitmap GetBitmapResource(const wxString &name)
Retrieves bitmap resources.
virtual CRef< CCmdComposite > GetCommand()
CFeatureFieldNamePanel * m_FeatureConstraint
CStringConstraintPanel * m_StringConstraintPanel
void Init()
Initialises member variables.
void ProcessUpdateFeatEvent(wxCommandEvent &event)
static bool ShowToolTips()
Should we show tooltips?
bool Create(wxWindow *parent, wxWindowID id=11000, const wxString &caption=_("Fuse Features"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU|wxCLOSE_BOX|wxTAB_TRAVERSAL)
Creation.
CFuseFeaturesDlg()
Constructors.
static CRef< CCmdComposite > apply(CSeq_entry_Handle seh)
vector< CRef< objects::edit::CApplyObject > > GetApplyObjects(objects::CBioseq_Handle bsh)
CScope –.
Definition: scope.hpp:92
static const CFeatList * GetFeatList()
CSeq_entry_Handle –.
CSeq_feat_Handle –.
namespace ncbi::objects::
Definition: Seq_feat.hpp:58
Seq-loc iterator class – iterates all intervals from a seq-loc in the correct order.
Definition: Seq_loc.hpp:593
CRef< edit::CStringConstraint > GetStringConstraint()
IWorkbench is the central interface in the application framework.
Definition: workbench.hpp:113
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
const string kPartialStart
#define EVT_UPDATE_FEATURE_LIST(id, fn)
static CS_COMMAND * cmd
Definition: ct_dynamic.c:26
static DLIST_TYPE *DLIST_NAME() first(DLIST_LIST_TYPE *list)
Definition: dlist.tmpl.h:46
static void Init(void)
Definition: cursor6.c:76
int offset
Definition: replacements.h:160
#define ID_FUSE_FEATURES_OKCANCEL
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 NULL
Definition: ncbistd.hpp:225
virtual void Assign(const CSerialObject &source, ESerialRecursionMode how=eRecursive)
Set object to copy of another one.
virtual void Assign(const CSerialObject &source, ESerialRecursionMode how=eRecursive)
Optimized implementation of CSerialObject::Assign, which is not so efficient.
Definition: Seq_id.cpp:318
CRef< CSeq_loc > MakeSeq_loc(EMakeType make_type=eMake_CompactType) const
return constructed CSeq_loc with all changes
Definition: Seq_loc.cpp:2946
void SetFrom(TSeqPos from)
Set the range from position.
Definition: Seq_loc.cpp:2818
void SetTo(TSeqPos to)
Set the range to position.
Definition: Seq_loc.cpp:2829
bool IsPartialStart(ESeqLocExtremes ext) const
check start or stop of location for e_Lim fuzz
Definition: Seq_loc.cpp:3222
void Delete(void)
Delete current element, and make iterator to point to the next element.
Definition: Seq_loc.cpp:2724
virtual void Assign(const CSerialObject &source, ESerialRecursionMode how=eRecursive)
Override Assign() to incorporate cache invalidation.
Definition: Seq_loc.cpp:337
bool HasChanges(void) const
return true of any part was changed since initialization
Definition: Seq_loc.cpp:2706
bool IsEmpty(void) const
True if the current location is empty.
Definition: Seq_loc.hpp:1084
TRange GetRange(void) const
Get the range.
Definition: Seq_loc.hpp:1042
void SetPartialStart(bool val, ESeqLocExtremes ext)
set / remove e_Lim fuzz on start or stop (lt/gt - indicating partial interval)
Definition: Seq_loc.cpp:3280
void SetPartialStop(bool val, ESeqLocExtremes ext)
Definition: Seq_loc.cpp:3313
bool IsPartialStop(ESeqLocExtremes ext) const
Definition: Seq_loc.cpp:3251
@ eOrder_Positional
Definition: Seq_loc.hpp:461
@ fMerge_All
Definition: Seq_loc.hpp:331
CRef< CSeq_loc > Seq_loc_Add(const CSeq_loc &loc1, const CSeq_loc &loc2, CSeq_loc::TOpFlags flags, CScope *scope)
Add two seq-locs.
bool IsSameBioseq(const CSeq_id &id1, const CSeq_id &id2, CScope *scope, CScope::EGetBioseqFlag get_flag=CScope::eGetBioseq_All)
Determines if two CSeq_ids represent the same CBioseq.
CBioseq_Handle GetBioseqHandle(const CSeq_id &id)
Get bioseq handle by seq-id.
Definition: scope.cpp:95
CSeq_feat_Handle GetSeq_featHandle(const CSeq_feat &feat, EMissing action=eMissing_Default)
Definition: scope.cpp:200
@ eMissing_Null
Definition: scope.hpp:157
virtual const CSeq_loc & GetProduct(void) const
bool IsSetProduct(void) const
virtual const CSeq_loc & GetLocation(void) const
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
static bool IsBlank(const CTempString str, SIZE_TYPE pos=0)
Check if a string is blank (has no text).
Definition: ncbistr.cpp:106
static SIZE_TYPE Find(const CTempString str, const CTempString pattern, ECase use_case=eCase, EDirection direction=eForwardSearch, SIZE_TYPE occurrence=0)
Find the pattern in the string.
Definition: ncbistr.cpp:2891
TTo GetTo(void) const
Get the To member data.
Definition: Range_.hpp:269
TFrom GetFrom(void) const
Get the From member data.
Definition: Range_.hpp:222
bool IsSetData(void) const
the specific data Check if a value has been assigned to Data data member.
Definition: Seq_feat_.hpp:913
void SetLocation(TLocation &value)
Assign a value to Location data member.
Definition: Seq_feat_.cpp:131
bool IsCdregion(void) const
Check if variant Cdregion is selected.
void SetPartial(TPartial value)
Assign a value to Partial data member.
Definition: Seq_feat_.hpp:971
void SetProduct(TProduct &value)
Assign a value to Product data member.
Definition: Seq_feat_.cpp:110
const TData & GetData(void) const
Get the Data member data.
Definition: Seq_feat_.hpp:925
const TExcept_text & GetExcept_text(void) const
Get the Except_text member data.
Definition: Seq_feat_.hpp:1405
bool IsSetExcept_text(void) const
explain if except=TRUE Check if a value has been assigned to Except_text data member.
Definition: Seq_feat_.hpp:1393
bool IsSetProduct(void) const
product of process Check if a value has been assigned to Product data member.
Definition: Seq_feat_.hpp:1084
END_EVENT_TABLE()
int i
yy_size_t n
constexpr bool empty(list< Ts... >) noexcept
const struct ncbi::grid::netcache::search::fields::SIZE size
static static static wxID_ANY
SAnnotSelector –.
C++ wrappers for the Perl-compatible regular expression (PCRE) library.
CRef< CCmdComposite > GetRetranslateCDSCommand(objects::CScope &scope, const objects::CSeq_feat &cds, bool create_general_only)
Modified on Wed Apr 17 13:10:19 2024 by modify_doxy.py rev. 669887