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

Go to the SVN repository for this file.

1 /* $Id: editing_action_features.cpp 47484 2023-05-02 14:27:54Z 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 #include <ncbi_pch.hpp>
32 #include <objmgr/util/feature.hpp>
33 #include <objmgr/util/sequence.hpp>
34 #include <objmgr/seq_annot_ci.hpp>
35 #include <objmgr/bioseq_ci.hpp>
47 #include <objects/seq/Seq_data.hpp>
48 #include <objmgr/seq_vector.hpp>
49 #include <objmgr/impl/synonyms.hpp>
53 
54 
57 
58 
60  const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class, const string &name)
61  : IEditingAction(seh, name)
62 {
63  if (subtype != CSeqFeatData::eSubtype_any)
64  m_selector = SAnnotSelector(subtype);
65  else
66  m_selector = SAnnotSelector(feat_type);
67  m_ncRNAclass = ncRNA_class;
68 }
69 
71 {
73  const CSeq_annot_Handle& ah = fh.GetAnnot();
74  if (ah)
75  {
76  seh = ah.GetParentEntry();
77  if (seh.IsSet())
78  {
79  CBioseq_CI b_iter(seh, CSeq_inst::eMol_na);
80  if (b_iter)
81  seh = b_iter->GetSeq_entry_Handle();
82  }
83  }
84  return seh;
85 }
86 
88 {
89  bool match = false;
90  CBioseq_Handle bsh;
91  CScope &scope = fh.GetScope();
92  for (CSeq_loc_CI subloc(fh.GetLocation(), objects::CSeq_loc_CI::eEmpty_Skip); subloc; ++subloc)
93  {
94  bsh = scope.GetBioseqHandle(subloc.GetSeq_id());
95  if (bsh)
96  match |= m_constraint->Match(bsh);
97  }
98  return match;
99 }
100 
102 {
103  return (rna_ref.IsSetExt() && rna_ref.GetExt().IsGen() && rna_ref.GetExt().GetGen().IsSetClass());
104 }
105 const string& IEditingActionFeat::s_GetncRNAClass(const CRNA_ref& rna_ref)
106 {
107  return rna_ref.GetExt().GetGen().GetClass();
108 }
109 
111 {
112  if (!m_TopSeqEntry)
113  return;
114  size_t count = 0;
115  for (CFeat_CI feat_ci(m_TopSeqEntry, m_selector); feat_ci; ++feat_ci) {
116  CSeq_feat_Handle fh = feat_ci->GetSeq_feat_Handle();
117 
118  if (!m_ncRNAclass.empty() && m_ncRNAclass != "any" && fh.GetFeatSubtype() == CSeqFeatData::eSubtype_ncRNA) {
119  auto& rna_ref = fh.GetData().GetRna();
120  if (!s_IsSetncRNAClass(rna_ref) || !NStr::EqualCase(s_GetncRNAClass(rna_ref), m_ncRNAclass)) {
121  continue;
122  }
123  }
124  m_EditedFeat.Reset();
126 
128  {
129  m_Feat = fh;
132  else
133  {
136  }
137  Modify(action);
138  }
139  ++count;
140  if (count >= m_max_records)
141  break;
142  }
143 }
144 
146 {
147  if (!m_TopSeqEntry)
148  return;
149  IEditingActionFeat *feat_other = dynamic_cast<IEditingActionFeat*>(m_Other);
150  if (!feat_other)
151  {
152  Find(action);
153  return;
154  }
155  CSeq_feat_Handle other_fh = feat_other->GetFeatHandle();
156  CScope &scope = m_TopSeqEntry.GetScope();
158  m_Feat.Reset();
160  {
162  if( feat_fh )
163  {
164  m_Feat = feat_fh;
165  }
166  }
168  {
169  const CSeq_loc& prot_loc = other_fh.GetLocation();
170  CBioseq_Handle prot_bsh = scope.GetBioseqHandle(prot_loc);
171  if (prot_bsh)
172  {
173  const CSeq_feat* cds = sequence::GetCDSForProduct(prot_bsh);
174  if (cds)
175  {
177  {
179  }
180  else
181  {
183  if( feat_fh )
184  {
185  m_Feat = feat_fh;
186  }
187  }
188  }
189  }
190  }
192  {
193  CSeq_feat_Handle cds_fh = other_fh;
196  if(cds_fh && cds_fh.IsSetProduct())
197  {
198  const CSeq_loc& prot_loc = cds_fh.GetProduct();
199  CBioseq_Handle prot_bsh = scope.GetBioseqHandle(prot_loc);
200  if (prot_bsh)
201  {
202  CFeat_CI prot_feat_ci(prot_bsh, SAnnotSelector(CSeqFeatData::eSubtype_prot));
203  if ( prot_feat_ci )
204  {
205  CSeq_feat_Handle prot_fh = prot_feat_ci->GetSeq_feat_Handle();
206  m_Feat = prot_fh;
207  }
208  }
209  }
210  }
211  else
212  {
213  Find(action);
214  return;
215  }
216 
217  if (m_Feat)
218  {
221  else
222  {
225  }
226  Modify(action);
227  }
228 }
229 
230 
231 
232 bool IEditingActionFeat::x_TestGeneForFeature(const CSeq_loc& gene_loc, const CSeq_loc& feat_loc, CScope& scope, bool& exact, TSeqPos& diff)
233 {
234  exact = false;
235  ENa_strand feat_strand = feat_loc.GetStrand();
236  ENa_strand gene_strand = gene_loc.GetStrand();
237  if (feat_strand == eNa_strand_minus && gene_strand != eNa_strand_minus) {
238  return false;
239  } else if (feat_strand != eNa_strand_minus && gene_strand == eNa_strand_minus) {
240  return false;
241  }
242  if (gene_loc.GetStart(eExtreme_Positional) > feat_loc.GetStop(eExtreme_Positional) ||
244  return false;
245 
246  sequence::ECompare cmp = sequence::Compare(gene_loc, feat_loc, &scope);
247 
248  if (cmp == sequence::eSame) {
249  exact = true;
250  diff = 0;
251  return true;
253 
257  diff = sequence::GetCoverage(*loc3, &scope);
258  return true;
259  } else {
260  return false;
261  }
262 }
263 
265 {
266  CScope &scope = bsh.GetScope();
267  CRef<CSeq_loc> new_loc(new CSeq_loc);
268  new_loc->Assign(loc);
269  CSeq_loc_I loc_it(*new_loc); // , CSeq_loc_CI::eEmpty_Skip, CSeq_loc_CI::eOrder_Positional
270  while(loc_it)
271  {
272  if (loc_it.IsEmpty() || !sequence::IsSameBioseq(*bsh.GetSeqId(), loc_it.GetSeq_id(), &scope))
273  {
274  loc_it.Delete();
275  continue;
276  }
277  ++loc_it;
278  }
279  CRef<CSeq_loc> changed_loc = loc_it.MakeSeq_loc()->Merge(objects::CSeq_loc::fSort, NULL);;
280  if (changed_loc->IsNull() || loc_it.GetSize() == 0)
281  changed_loc.Reset();
282  return changed_loc;
283 }
284 
286 {
288  CSeq_feat_Handle exact_match;
289 
290  CSeq_feat_Handle best_non_exact;
291  TSeqPos min_diff = INT_MAX;
292 
293  set<CBioseq_Handle> seen_bsh;
294  set<CSeq_feat_Handle> feature_handles;
295  for (CSeq_loc_CI subloc(loc, objects::CSeq_loc_CI::eEmpty_Skip); subloc; ++subloc)
296  {
297  CBioseq_Handle bsh = scope.GetBioseqHandle(subloc.GetSeq_id());
298  if (!bsh)
299  continue;
300  seen_bsh.insert(bsh);
301  for (CFeat_CI gene(bsh, subtype); gene; ++gene)
302  {
303  feature_handles.insert(gene->GetSeq_feat_Handle());
304  }
305  }
306 
307  for (auto gene : feature_handles)
308  {
309  bool exact = true;
310  TSeqPos diff = 0;
311  const CSeq_loc& gene_loc = gene.GetLocation();
312  bool any_match = false;
313  for (auto bsh : seen_bsh)
314  {
315  auto subloc = x_GetSublocOnBioseq(bsh, loc);
316  auto gene_subloc = x_GetSublocOnBioseq(bsh, gene_loc);
317  if (!subloc || !gene_subloc)
318  continue;
319  bool sub_exact = false;
320  TSeqPos sub_diff = INT_MAX;
321  if (x_TestGeneForFeature(*gene_subloc, *subloc, scope, sub_exact, sub_diff))
322  {
323  exact = exact && sub_exact;
324  if (sub_diff < INT_MAX)
325  diff += sub_diff;
326  else
327  diff = INT_MAX;
328  }
329  else
330  {
331  exact = false;
332  diff = INT_MAX;
333  }
334  any_match = true;
335  }
336  if (!any_match)
337  continue;
338  if (exact)
339  {
340  exact_match = gene;
341  }
342  if (diff < min_diff)
343  {
344  best_non_exact = gene;
345  min_diff = diff;
346  }
347  }
348 
349  if (exact_match)
350  return exact_match;
351  if (best_non_exact)
352  return best_non_exact;
353  return empty;
354 }
355 
356 namespace {
357 // Types used in operations with seq-locs
358 // Ugly copy-paste
359 class CRangeWithFuzz : public CSeq_loc::TRange
360 {
361 public:
362  typedef CSeq_loc::TRange TParent;
363  typedef CConstRef<CInt_fuzz> TFuzz;
364 
365  CRangeWithFuzz(const TParent& rg)
366  : TParent(rg), m_Strand(eNa_strand_unknown)
367  {
368  }
369  CRangeWithFuzz(const CSeq_loc_CI& it)
370  : TParent(it.GetRange()),
371  m_Fuzz_from(it.GetFuzzFrom()),
372  m_Fuzz_to(it.GetFuzzTo()),
373  m_Strand(it.GetStrand())
374  {
375  }
376 
377  void ResetFuzzFrom(void) { m_Fuzz_from.Reset(); }
378  void ResetFuzzTo(void) { m_Fuzz_to.Reset(); }
379  bool IsSetFuzzFrom(void) const { return m_Fuzz_from; }
380  bool IsSetFuzzTo(void) const { return m_Fuzz_to; }
381  const CInt_fuzz& GetFuzzFrom(void) const { return *m_Fuzz_from; }
382  const CInt_fuzz& GetFuzzTo(void) const { return *m_Fuzz_to; }
383 
384  // Add fuzzes assuming that both ranges had the same 'from'
385  void AddFuzzFrom(const CRangeWithFuzz& rg)
386  {
387  x_AddFuzz(m_Fuzz_from, rg.m_Fuzz_from, rg.m_Strand);
388  }
389 
390  // Add fuzzes assuming that both ranges had the same 'to'
391  void AddFuzzTo(const CRangeWithFuzz& rg)
392  {
393  x_AddFuzz(m_Fuzz_to, rg.m_Fuzz_to, rg.m_Strand);
394  }
395 
396  void AddFuzzFrom(const CInt_fuzz& fuzz, ENa_strand strand)
397  {
398  x_AddFuzz(m_Fuzz_from, ConstRef(&fuzz), strand);
399  }
400 
401  void AddFuzzTo(const CInt_fuzz& fuzz, ENa_strand strand)
402  {
403  x_AddFuzz(m_Fuzz_to, ConstRef(&fuzz), strand);
404  }
405 
406  void CopyFrom(const CRangeWithFuzz& rg)
407  {
408  SetFrom(rg.GetFrom());
409  m_Fuzz_from = rg.m_Fuzz_from;
410  }
411 
412  void CopyTo(const CRangeWithFuzz& rg)
413  {
414  SetTo(rg.GetTo());
415  m_Fuzz_to = rg.m_Fuzz_to;
416  }
417 
418  CRangeWithFuzz& operator +=(const CRangeWithFuzz& rg)
419  {
420  TParent::position_type old_from = GetFrom();
421  TParent::position_type old_to = GetTo();
423  if (old_from != GetFrom()) {
424  m_Fuzz_from.Reset(rg.m_Fuzz_from);
425  }
426  else if (old_from == rg.GetFrom()) {
427  // Reset fuzz if it's not the same for both ranges
428  AddFuzzFrom(rg);
429  }
430  if (old_to != GetTo()) {
431  m_Fuzz_to.Reset(rg.m_Fuzz_to);
432  }
433  else if (old_to == rg.GetTo()) {
434  AddFuzzTo(rg);
435  }
436  return *this;
437  }
438 
439  CRangeWithFuzz& operator +=(const TParent& rg)
440  {
441  TParent::position_type old_from = GetFrom();
442  TParent::position_type old_to = GetTo();
444  // Reset fuzz if the corresponding extreme changes
445  if (old_from != GetFrom()) {
446  ResetFuzzFrom();
447  }
448  if (old_to != GetTo()) {
449  ResetFuzzTo();
450  }
451  return *this;
452  }
453 
454 private:
455  CRef<CInt_fuzz> x_SetFuzz(TFuzz& fuzz,
456  const CInt_fuzz* copy_from)
457  {
458  TFuzz copy_from_cref;
459  if (copy_from == fuzz) copy_from_cref.Reset(copy_from);
460  // Since TFuzz is a const-ref, setting fuzz requires creating
461  // a new object
462  CRef<CInt_fuzz> new_fuzz(new CInt_fuzz);
463  // The new value is optional
464  if ( copy_from ) {
465  new_fuzz->Assign(*copy_from);
466  }
467  fuzz.Reset(new_fuzz);
468  return new_fuzz;
469  }
470 
471  void x_AddFuzz(TFuzz& fuzz,
472  const TFuzz& other,
473  ENa_strand other_strand)
474  {
475  if ( !fuzz ) {
476  // Use fuzz from the other range if available
477  if ( other ) {
478  x_SetFuzz(fuzz, other.GetPointerOrNull());
479  }
480  return;
481  }
482  if ( !other ) {
483  // The other range has no fuzz, keep the current one
484  return;
485  }
486  if (fuzz->Which() != other->Which()) {
487  // Fuzzes have different types, reset to lim-unk.
488  CRef<CInt_fuzz> new_fuzz = x_SetFuzz(fuzz, NULL);
489  new_fuzz->SetLim(CInt_fuzz::eLim_unk);
490  return;
491  }
492 
493  const CInt_fuzz& fz = *fuzz;
494  const CInt_fuzz& ofz = *other;
495  // Both fuzzes are set and have the same type, try to merge them
496  switch ( fz.Which() ) {
497  case CInt_fuzz::e_Lim:
498  {
499  CInt_fuzz::ELim this_lim = fz.GetLim();
500  CInt_fuzz::ELim other_lim = ofz.GetLim();
501  bool this_rev = IsReverse(m_Strand);
502  bool other_rev = IsReverse(other_strand);
503  bool other_lt = other_lim == CInt_fuzz::eLim_lt ||
504  (!other_rev && other_lim == CInt_fuzz::eLim_tl) ||
505  (other_rev && other_lim == CInt_fuzz::eLim_tr);
506  bool other_gt = other_lim == CInt_fuzz::eLim_gt ||
507  (!other_rev && other_lim == CInt_fuzz::eLim_tr) ||
508  (other_rev && other_lim == CInt_fuzz::eLim_tl);
509  switch ( fz.GetLim() ) {
510  case CInt_fuzz::eLim_lt:
511  if ( other_lt ) {
512  return; // the same
513  }
514  break;
515  case CInt_fuzz::eLim_gt:
516  if ( other_gt ) {
517  return; // the same
518  }
519  break;
520  case CInt_fuzz::eLim_tl:
521  if ((!this_rev && other_lt) ||
522  (this_rev && other_gt)) {
523  return; // the same
524  }
525  break;
526  case CInt_fuzz::eLim_tr:
527  if ((!this_rev && other_gt) ||
528  (this_rev && other_lt)) {
529  return; // the same
530  }
531  break;
532  default:
533  if (other_lim == this_lim) {
534  return;
535  }
536  break;
537  }
538  // Different limits - reset to lim-unk.
539  CRef<CInt_fuzz> new_fuzz = x_SetFuzz(fuzz, NULL);
540  new_fuzz->SetLim(CInt_fuzz::eLim_unk);
541  break;
542  }
543  case CInt_fuzz::e_Alt:
544  {
545  // Use union
546  CRef<CInt_fuzz> new_fuzz = x_SetFuzz(fuzz, fuzz);
547  new_fuzz->SetAlt().insert(
548  new_fuzz->SetAlt().end(),
549  ofz.GetAlt().begin(),
550  ofz.GetAlt().end());
551  break;
552  }
553  case CInt_fuzz::e_Range:
554  {
555  // Use union
560  if (min1 > min2 || max1 < max2) {
561  CRef<CInt_fuzz> new_fuzz = x_SetFuzz(fuzz, NULL);
562  new_fuzz->SetRange().SetMin(min1 < min2 ? min1 : min2);
563  new_fuzz->SetRange().SetMax(max1 > max2 ? max1 : max2);
564  }
565  break;
566  }
567  case CInt_fuzz::e_P_m:
568  {
569  // Use max value
570  CInt_fuzz::TP_m pm = ofz.GetP_m();
571  if (fz.GetP_m() < pm) {
572  CRef<CInt_fuzz> new_fuzz = x_SetFuzz(fuzz, NULL);
573  new_fuzz->SetP_m(pm);
574  }
575  break;
576  }
577  case CInt_fuzz::e_Pct:
578  {
579  // Use max value
580  CInt_fuzz::TPct pct = ofz.GetPct();
581  if (fz.GetPct() < pct) {
582  CRef<CInt_fuzz> new_fuzz = x_SetFuzz(fuzz, NULL);
583  new_fuzz->SetPct(pct);
584  }
585  break;
586  }
587  default:
588  // Failed to merge fuzzes
589  fuzz.Reset();
590  break;
591  }
592  }
593 
594  TFuzz m_Fuzz_from;
595  TFuzz m_Fuzz_to;
597 };
598 
599 
600 class CSeq_id_Handle_Wrapper
601 {
602 public:
603  CSeq_id_Handle_Wrapper(void) {}
604 
605  CSeq_id_Handle_Wrapper(const CSeq_id_Handle& idh, const CSeq_id& id)
606  : m_Handle(idh)
607  {
608  if (id.IsLocal() && id.GetLocal().IsStr()) {
609  m_Id.Reset(&id);
610  }
611  }
612 
613  CConstRef<CSeq_id> GetSeqId(void) const { return m_Id ? m_Id : m_Handle.GetSeqId(); }
614 
615  const CSeq_id_Handle& GetHandle(void) const { return m_Handle; }
616 
617  bool operator== (const CSeq_id_Handle_Wrapper& handle) const
618  {
619  return m_Handle == handle.m_Handle;
620  }
621 
622  bool operator!= (const CSeq_id_Handle_Wrapper& handle) const
623  {
624  return m_Handle != handle.m_Handle;
625  }
626  bool operator< (const CSeq_id_Handle_Wrapper& handle) const
627  {
628  return m_Handle < handle.m_Handle;
629  }
630 
631  DECLARE_OPERATOR_BOOL(m_Handle);
632 
633 private:
636 };
637 
638 class CDefaultSynonymMapper : public ISynonymMapper
639 {
640 public:
642  virtual ~CDefaultSynonymMapper(void);
643 
644  virtual CSeq_id_Handle GetBestSynonym(const CSeq_id& id);
645 
646 private:
648 
650  TSynonymMap m_SynMap;
651  CScope* m_Scope;
652 };
653 
654 
656  : m_IdMapper(CSeq_id_Mapper::GetInstance()),
657  m_Scope(scope)
658 {
659  return;
660 }
661 
662 
664 {
665  return;
666 }
667 
668 
670 {
672  if ( !m_Scope || id.Which() == CSeq_id::e_not_set ) {
673  return idh;
674  }
675  TSynonymMap::iterator id_syn = m_SynMap.find(idh);
676  if (id_syn != m_SynMap.end()) {
677  return id_syn->second;
678  }
679  CSeq_id_Handle best;
680  int best_rank = CSeq_id::kMaxScore;
682 #ifdef _DEBUG
683  TGi gi = ZERO_GI;
684 #endif
685  ITERATE(CSynonymsSet, syn_it, *syn_set) {
686  CSeq_id_Handle synh = syn_set->GetSeq_id_Handle(syn_it);
687 #ifdef _DEBUG
688  if (synh.IsGi()) {
689  gi = synh.GetGi();
690  }
691 #endif
692  int rank = synh.GetSeqId()->BestRankScore();
693  if (rank < best_rank) {
694  best = synh;
695  best_rank = rank;
696  }
697  }
698  if ( !best ) {
699  // Synonyms set was empty
700  m_SynMap[idh] = idh;
701  return idh;
702  }
703  ITERATE(CSynonymsSet, syn_it, *syn_set) {
704  m_SynMap[syn_set->GetSeq_id_Handle(syn_it)] = best;
705  }
706 #ifdef _DEBUG
707  const CTextseq_id* txt_id = best.GetSeqId()->GetTextseq_Id();
708  if (txt_id && !txt_id->IsSetVersion() && gi != ZERO_GI) {
709  ERR_POST("Using version-less accession " << txt_id->GetAccession()
710  << " instead of GI " << gi);
711  }
712 #endif
713  return best;
714 }
715 
716 }
718 {
719  //CRef<CSeq_loc> gene_loc = sequence::Seq_loc_Merge(loc, CSeq_loc::fMerge_SingleRange, &scope);
720  CRef<CSeq_loc> gene_loc(new CSeq_loc);
721  CDefaultSynonymMapper syn_mapper(&scope);
722 
723  CRangeWithFuzz total_rg(CRangeWithFuzz::GetEmpty());
724  CSeq_id_Handle_Wrapper prev_id;
725  ENa_strand prev_strand = eNa_strand_unknown;
726  bool first = true;
727  for (CSeq_loc_CI it(loc, CSeq_loc_CI::eEmpty_Allow); it; ++it)
728  {
729  CSeq_id_Handle_Wrapper next_id(syn_mapper.GetBestSynonym(it.GetSeq_id()), it.GetSeq_id());
730  if ( !next_id )
731  {
732  // Ignore NULLs
733  continue;
734  }
735  ENa_strand next_strand = it.GetStrand();
736  if (first)
737  {
738  first = false;
739  }
740  else if (prev_id != next_id || prev_strand != next_strand)
741  {
742  CRef<CSeq_id> id(new CSeq_id);
743  id->Assign(*prev_id.GetSeqId());
744  CRef<CSeq_interval> interval(new CSeq_interval(*id, total_rg.GetFrom(), total_rg.GetTo(), prev_strand));
745  if ( total_rg.IsSetFuzzFrom() )
746  {
747  interval->SetFuzz_from().Assign(total_rg.GetFuzzFrom());
748  }
749  if ( total_rg.IsSetFuzzTo() )
750  {
751  interval->SetFuzz_to().Assign(total_rg.GetFuzzTo());
752  }
753  gene_loc->SetPacked_int().Set().push_back(interval);
754  total_rg = CRangeWithFuzz(CRangeWithFuzz::GetEmpty());
755  first = true;
756  }
757  total_rg += CRangeWithFuzz(it);
758  prev_id = next_id;
759  prev_strand = next_strand;
760  }
761 
762  if (!total_rg.Empty())
763  {
764  CRef<CSeq_id> id(new CSeq_id);
765  id->Assign(*prev_id.GetSeqId());
766  CRef<CSeq_interval> interval(new CSeq_interval(*id, total_rg.GetFrom(), total_rg.GetTo(), prev_strand));
767  if ( total_rg.IsSetFuzzFrom() )
768  {
769  interval->SetFuzz_from().Assign(total_rg.GetFuzzFrom());
770  }
771  if ( total_rg.IsSetFuzzTo() )
772  {
773  interval->SetFuzz_to().Assign(total_rg.GetFuzzTo());
774  }
775  if (gene_loc->IsPacked_int())
776  gene_loc->SetPacked_int().Set().push_back(interval);
777  else
778  gene_loc->SetInt(*interval);
779  }
780 
781  return gene_loc;
782 }
783 
785 {
786  if (!m_TopSeqEntry)
787  return;
788  size_t count = 0;
789  for (CFeat_CI feat_ci(m_TopSeqEntry, m_selector); feat_ci; ++feat_ci)
790  {
791  CSeq_feat_Handle fh = feat_ci->GetSeq_feat_Handle();
792  if (!m_ncRNAclass.empty() && m_ncRNAclass != "any" && fh.GetFeatSubtype() == CSeqFeatData::eSubtype_ncRNA) {
793  auto& rna_ref = fh.GetData().GetRna();
794  if (!s_IsSetncRNAClass(rna_ref) || !NStr::EqualCase(s_GetncRNAClass(rna_ref), m_ncRNAclass)) {
795  continue;
796  }
797  }
798 
801  CScope &scope = fh.GetScope();
803  {
804  CSeq_feat_Handle gene_fh = x_FindGeneForFeature(fh.GetLocation(), scope, other_selector.GetFeatSubtype());
805  if (gene_fh)
806  {
807  m_Feat = gene_fh;
809  {
811  }
812  else
813  {
816  }
817  Modify(action);
818  }
819  }
820  ++count;
821  if (count >= m_max_records)
822  break;
823  }
824 }
825 
826 
828 {
829  IEditingActionFeat *feat_other = dynamic_cast<IEditingActionFeat*>(m_Other);
830  if (!feat_other)
831  {
832  Find(action);
833  return;
834  }
836  CSeq_feat_Handle fh = feat_other->GetFeatHandle();
837  CScope &scope = fh.GetScope();
838  CSeq_feat_Handle gene_fh = x_FindGeneForFeature(fh.GetLocation(), scope, other_selector.GetFeatSubtype());
839 
840  if (gene_fh)
841  {
842  m_Feat = gene_fh;
845  else
846  {
849  }
850  Modify(action);
851  }
852 }
853 
855 {
856  m_saved_feat_enabled = false;
857  if (m_Feat && m_Feat.IsSetProduct())
858  {
859  const CSeq_loc& prot_loc = m_Feat.GetProduct();
860  CBioseq_Handle prot_bsh = m_Feat.GetScope().GetBioseqHandle(prot_loc);
861  if (prot_bsh)
862  {
863  CFeat_CI prot_feat_ci(prot_bsh, SAnnotSelector(CSeqFeatData::eSubtype_prot));
864  if( prot_feat_ci)
865  {
866  m_saved_feat_enabled = true;
869  CSeq_feat_Handle prot_fh = prot_feat_ci->GetSeq_feat_Handle();
870  m_Feat = prot_fh;
873  else
874  {
877  }
878  }
879  }
880  }
881 }
882 
884 {
886  {
889  m_saved_feat_enabled = false;
890  }
891 }
892 
894 {
895  if (!m_TopSeqEntry)
896  return;
897  size_t count = 0;
898  for (CFeat_CI feat_ci(m_TopSeqEntry, m_selector); feat_ci; ++feat_ci)
899  {
900  CSeq_feat_Handle fh = feat_ci->GetSeq_feat_Handle();
901  if (!m_ncRNAclass.empty() && m_ncRNAclass != "any" && fh.GetFeatSubtype() == CSeqFeatData::eSubtype_ncRNA) {
902  auto& rna_ref = fh.GetData().GetRna();
903  if (!s_IsSetncRNAClass(rna_ref) || !NStr::EqualCase(s_GetncRNAClass(rna_ref), m_ncRNAclass)) {
904  continue;
905  }
906  }
907 
910 
912  {
913  m_Feat = fh;
914  if (fh.IsSetProduct())
915  {
916  const CSeq_loc& prot_loc = fh.GetProduct();
917  CBioseq_Handle prot_bsh = m_TopSeqEntry.GetScope().GetBioseqHandle(prot_loc);
918  if (prot_bsh)
919  {
920  CFeat_CI prot_feat_ci(prot_bsh, SAnnotSelector(CSeqFeatData::eSubtype_prot));
921  if( prot_feat_ci)
922  {
923  CSeq_feat_Handle prot_fh = prot_feat_ci->GetSeq_feat_Handle();
924  m_Feat = prot_fh;
925  }
926  else if (!IsNOOP(action) && m_ChangedFeatures.find(m_Feat) == m_ChangedFeatures.end())
927  {
929  m_EditedFeat->SetData().SetProt();
930  CRef<CSeq_loc> new_prot_loc(new CSeq_loc);
931  new_prot_loc->Assign(prot_loc);
932  m_EditedFeat->SetLocation(*new_prot_loc);
934  CSeq_entry_Handle seh = prot_bsh.GetSeq_entry_Handle();
935  m_CreatedFeatures[m_Feat] = seh;
937  }
938  }
939  }
942  else
943  {
946  }
947  Modify(action);
948  }
949  ++count;
950  if (count >= m_max_records)
951  break;
952  }
953 
955  {
956  size_t count = 0;
957  for (CBioseq_CI b_iter(m_TopSeqEntry, objects::CSeq_inst::eMol_aa); b_iter; ++b_iter)
958  {
959  m_Feat.Reset();
961  CBioseq_Handle prot_bsh = *b_iter;
964  if (feat_ci)
965  continue;
966  if (prot_bsh && m_constraint->Match(prot_bsh))
967  {
968  if (!IsNOOP(action))
969  {
970  CRef<CSeq_loc> prot_loc = prot_bsh.GetRangeSeq_loc(0,0);
971  CFeat_CI prot_feat_ci(*m_scope, *prot_loc, SAnnotSelector(CSeqFeatData::eSubtype_prot));
972  if (prot_feat_ci && m_constraint->Match(prot_feat_ci->GetSeq_feat_Handle()))
973  {
974  m_Feat = prot_feat_ci->GetSeq_feat_Handle();
975  }
976  else
977  {
979  m_EditedFeat->SetData().SetProt();
980  m_EditedFeat->SetLocation(*prot_loc);
982  CSeq_entry_Handle seh = prot_bsh.GetSeq_entry_Handle();
986  for (CSeq_annot_CI annot_ci(new_seh, CSeq_annot_CI::eSearch_entry); annot_ci; ++annot_ci)
987  {
988  if ((*annot_ci).IsFtable())
989  {
990  ftable = *annot_ci;
991  break;
992  }
993  }
994  CSeq_entry_EditHandle eh = new_seh.GetEditHandle();
995  if (!ftable)
996  {
997  CRef<CSeq_annot> new_annot(new CSeq_annot());
998  ftable = eh.AttachAnnot(*new_annot);
999  }
1000 
1002  m_Feat = aeh.AddFeat(*m_EditedFeat);
1003  if (m_constraint->Match(m_Feat))
1004  {
1005  m_CreatedFeatures[m_Feat] = seh; // this seq-entry-handle should be in the original scope
1007  }
1008  else
1009  {
1010  m_Feat.Reset();
1011  }
1012  }
1013  }
1014 
1015  if (m_Feat)
1016  {
1019  else
1020  {
1023  }
1024  Modify(action);
1025  }
1026  }
1027  ++count;
1028  if (count >= m_max_records)
1029  break;
1030  }
1031  }
1032 
1033 }
1034 
1036 {
1037  if (!m_TopSeqEntry)
1038  return;
1039 
1040  IEditingActionFeat *feat_other = dynamic_cast<IEditingActionFeat*>(m_Other);
1041  if (!feat_other)
1042  {
1043  Find(action);
1044  return;
1045  }
1046  CSeq_feat_Handle other_fh = feat_other->GetFeatHandle();
1047  m_Feat.Reset();
1048 
1049  SAnnotSelector sel = m_selector;
1051  {
1053  }
1054 
1055  CScope &scope = m_TopSeqEntry.GetScope();
1056  CSeq_feat_Handle feat_fh = x_FindGeneForFeature(other_fh.GetLocation(), scope, sel.GetFeatSubtype());
1057 
1058  if(feat_fh)
1059  {
1060  m_EditedFeat.Reset();
1061  m_Feat = feat_fh;
1062  if (m_Feat.IsSetProduct())
1063  {
1064  const CSeq_loc& prot_loc = m_Feat.GetProduct();
1065  CBioseq_Handle prot_bsh = m_TopSeqEntry.GetScope().GetBioseqHandle(prot_loc);
1066  if (prot_bsh)
1067  {
1068  CFeat_CI prot_feat_ci(prot_bsh, SAnnotSelector(CSeqFeatData::eSubtype_prot));
1069  if ( prot_feat_ci )
1070  {
1071  CSeq_feat_Handle prot_fh = prot_feat_ci->GetSeq_feat_Handle();
1072  m_Feat = prot_fh;
1073  }
1074  else if (!IsNOOP(action) && m_ChangedFeatures.find(m_Feat) == m_ChangedFeatures.end())
1075  {
1077  m_EditedFeat->SetData().SetProt();
1078  CRef<CSeq_loc> new_prot_loc(new CSeq_loc);
1079  new_prot_loc->Assign(prot_loc);
1080  m_EditedFeat->SetLocation(*new_prot_loc);
1082  CSeq_entry_Handle seh = prot_bsh.GetSeq_entry_Handle();
1083  m_CreatedFeatures[m_Feat] = seh;
1085  }
1086  }
1087  }
1088  }
1089 
1090 
1091  if (m_Feat)
1092  {
1095  else
1096  {
1099  }
1100  Modify(action);
1101  }
1102 }
1103 
1105 {
1106  Action(action);
1107  if (m_modified)
1108  {
1110  }
1111 }
1112 
1114 {
1115  IEditingActionFeat *feat_source = dynamic_cast<IEditingActionFeat*>(m_Other);
1116  return (feat_source
1117  && feat_source->m_selector.GetAnnotType() == m_selector.GetAnnotType()
1118  && feat_source->m_selector.GetFeatType() == m_selector.GetFeatType()
1119  && feat_source->m_selector.GetFeatSubtype() == m_selector.GetFeatSubtype()
1120  && feat_source->m_ncRNAclass == m_ncRNAclass);
1121 }
1122 
1124 {
1125  IEditingActionFeat *feat_source = dynamic_cast<IEditingActionFeat*>(m_Other);
1126  if (feat_source && feat_source->m_Feat && feat_source->m_Feat.GetFeatSubtype() == subtype)
1127  return true;
1128  if (subtype == CSeqFeatData::eSubtype_gene)
1129  {
1131  if (locus)
1132  return true;
1134  if (desc)
1135  return true;
1137  if (maploc)
1138  return true;
1140  if (locus_tag)
1141  return true;
1143  if (synonym)
1144  return true;
1146  if (comment)
1147  return true;
1148  }
1149  return false;
1150 }
1151 
1152 
1154 {
1155  IEditingActionFeat *feat_source = dynamic_cast<IEditingActionFeat*>(source);
1156  if (feat_source)
1157  {
1158  swap(m_Feat, feat_source->m_Feat);
1159  swap(m_EditedFeat, feat_source->m_EditedFeat);
1160  }
1162 }
1163 
1165 {
1166  m_Feat = fh;
1169 }
1170 
1171 
1173 {
1174  m_Feat.Reset();
1175  if (fh.GetFeatSubtype() != subtype)
1176  {
1177  CSeq_feat_Handle gene_fh = x_FindGeneForFeature(fh.GetLocation(), fh.GetScope(), subtype);
1178  if (gene_fh)
1179  m_Feat = gene_fh;
1180  }
1181 
1182  if (!m_Feat)
1183  m_Feat = fh;
1184 
1187 }
1188 
1190 {
1191  return m_Feat;
1192 }
1193 
1195 {
1196  if (m_scope)
1197  m_scope->ResetHistory();
1199  m_scope.Reset(new CScope(*object_manager));
1200  m_scope->AddDefaults();
1201 }
1202 
1204 {
1206  {
1207  if ((*it)->IsSetData() && (*it)->GetData().IsGene())
1208  {
1210  }
1211  }
1212  if (m_EditedFeat->GetXref().empty())
1214 }
1215 
1217  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class)
1218  : IEditingActionFeat(seh, subtype, feat_type, ncRNA_class, "CEditingActionFeatComment")
1219 {
1220 }
1221 
1223 {
1224  return m_EditedFeat->IsSetComment();
1225 }
1226 
1228 {
1230 }
1231 
1233 {
1234  return m_EditedFeat->GetComment();
1235 }
1236 
1238 {
1240 }
1241 
1243  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class)
1244  : IEditingActionFeat(seh, subtype, feat_type, ncRNA_class, "CEditingActionFeatException")
1245 {
1246 }
1247 
1249 {
1251 }
1252 
1254 {
1255  m_EditedFeat->SetExcept(true);
1257 }
1258 
1260 {
1261  return m_EditedFeat->GetExcept_text();
1262 }
1263 
1265 {
1268 }
1269 
1270 
1272  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class,
1273  const string &qual, const string &name)
1274  : IEditingActionFeat(seh, subtype, feat_type, ncRNA_class, name), m_qual(qual), m_erase(false)
1275 {
1276 }
1277 
1279 {
1280  bool found = false;
1281  if (IsFrom(action) && m_EditedFeat->IsSetQual() && !m_EditedFeat->GetQual().empty() && m_EditedFeat->GetQual().capacity() < 2 * m_EditedFeat->GetQual().size())
1282  {
1283  m_EditedFeat->SetQual().reserve(2 * m_EditedFeat->GetQual().size());
1284  }
1285  if (!IsCreateNew(action))
1286  {
1288  {
1289  if ((*gbqual_it) && (*gbqual_it)->IsSetQual() && (*gbqual_it)->GetQual() == m_qual)
1290  {
1291  found = true;
1292  m_erase = false;
1293  m_GBqual = *gbqual_it;
1295  if (m_erase)
1297  }
1298  }
1299  }
1300  if (!found)
1301  {
1302  m_GBqual.Reset();
1303  m_erase = false;
1305  }
1306  if (IsFrom(action))
1307  {
1308  m_EditedFeat->SetQual().shrink_to_fit();
1309  }
1310  if (m_EditedFeat->GetQual().empty())
1312 }
1313 
1315 {
1316  return m_GBqual && m_GBqual->IsSetVal();
1317 }
1318 
1320 {
1321  if (m_GBqual)
1322  m_GBqual->SetVal(value);
1323  else if (!value.empty())
1325 }
1326 
1328 {
1329  return m_GBqual->GetVal();
1330 }
1331 
1333 {
1334  m_erase = true;
1335 }
1336 
1338  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class,
1339  const string &qual1, const string &qual2)
1340  : CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, qual1, "CEditingActionFeatGbQualTwoNames"), m_qual2(qual2)
1341 {
1342 }
1343 
1345 {
1346  bool found = false;
1347  if (IsFrom(action) && m_EditedFeat->IsSetQual() && !m_EditedFeat->GetQual().empty() && m_EditedFeat->GetQual().capacity() < 2 * m_EditedFeat->GetQual().size())
1348  {
1349  m_EditedFeat->SetQual().reserve(2 * m_EditedFeat->GetQual().size());
1350  }
1351  if (!IsCreateNew(action))
1352  {
1354  {
1355  if ((*gbqual_it) && (*gbqual_it)->IsSetQual() && ((*gbqual_it)->GetQual() == m_qual || (*gbqual_it)->GetQual() == m_qual2))
1356  {
1357  found = true;
1358  m_erase = false;
1359  m_GBqual = *gbqual_it;
1361  if (m_erase)
1363  }
1364  }
1365  }
1366  if (!found)
1367  {
1368  m_GBqual.Reset();
1369  m_erase = false;
1371  }
1372  if (IsFrom(action))
1373  {
1374  m_EditedFeat->SetQual().shrink_to_fit();
1375  }
1376  if (m_EditedFeat->GetQual().empty())
1378 }
1379 
1381  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class,
1382  const string &qual)
1383  : CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, qual, "CEditingActionFeatDualVal1")
1384 {
1385 }
1386 
1388 {
1389  if (m_GBqual && m_GBqual->IsSetVal())
1390  {
1391  string val = m_GBqual->GetVal();
1392  string element_type, element_name;
1393  NStr::SplitInTwo(val, ":", element_type, element_name);
1394  return !element_type.empty();
1395  }
1396  return false;
1397 }
1398 
1400 {
1401  if (m_GBqual)
1402  {
1403  if (m_GBqual->IsSetVal())
1404  {
1405  string val = m_GBqual->GetVal();
1406  string element_type, element_name;
1407  NStr::SplitInTwo(val, ":", element_type, element_name);
1408  element_type = value;
1409  if (!element_name.empty())
1410  element_type += ":" + element_name;
1411  m_GBqual->SetVal(element_type);
1412  }
1413  else
1414  m_GBqual->SetVal(value);
1415  }
1416  else
1418 }
1419 
1421 {
1422  string val = m_GBqual->GetVal();
1423  string element_type, element_name;
1424  NStr::SplitInTwo(val, ":", element_type, element_name);
1425  return element_type;
1426 }
1427 
1429 {
1430  if (m_GBqual->IsSetVal())
1431  {
1432  string val = m_GBqual->GetVal();
1433  string element_type, element_name;
1434  NStr::SplitInTwo(val, ":", element_type, element_name);
1435  if (!element_name.empty())
1436  m_GBqual->SetVal(":" + element_name);
1437  else
1438  m_erase = true;
1439  }
1440  m_erase = true;
1441 }
1442 
1444  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class,
1445  const string &qual)
1446  : CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, qual, "CEditingActionFeatDualVal2")
1447 {
1448 }
1449 
1451 {
1452  if (m_GBqual && m_GBqual->IsSetVal())
1453  {
1454  string val = m_GBqual->GetVal();
1455  string element_type, element_name;
1456  NStr::SplitInTwo(val, ":", element_type, element_name);
1457  return !element_name.empty();
1458  }
1459  return false;
1460 }
1461 
1463 {
1464  if (m_GBqual)
1465  {
1466  if (m_GBqual->IsSetVal())
1467  {
1468  string val = m_GBqual->GetVal();
1469  string element_type, element_name;
1470  NStr::SplitInTwo(val, ":", element_type, element_name);
1471  element_name = value;
1472  if (!element_type.empty())
1473  element_name = element_type + ":" + element_name;
1474  m_GBqual->SetVal(element_name);
1475  }
1476  else
1477  m_GBqual->SetVal(value);
1478  }
1479  else
1481 }
1482 
1484 {
1485  string val = m_GBqual->GetVal();
1486  string element_type, element_name;
1487  NStr::SplitInTwo(val, ":", element_type, element_name);
1488  return element_name;
1489 }
1490 
1492 {
1493  if (m_GBqual->IsSetVal())
1494  {
1495  string val = m_GBqual->GetVal();
1496  string element_type, element_name;
1497  NStr::SplitInTwo(val, ":", element_type, element_name);
1498  if (!element_type.empty())
1499  m_GBqual->SetVal(element_type);
1500  else
1501  m_erase = true;
1502  }
1503  m_erase = true;
1504 }
1505 
1506 
1507 
1509  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class)
1510  : IEditingActionFeat(seh, subtype, feat_type, ncRNA_class, "CEditingActionFeatDbxref"), m_erase(false)
1511 {
1512 }
1513 
1515 {
1516  bool found = false;
1517  if (IsFrom(action) && m_EditedFeat->IsSetDbxref() && !m_EditedFeat->GetDbxref().empty() && m_EditedFeat->GetDbxref().capacity() < 2 * m_EditedFeat->GetDbxref().size())
1518  {
1519  m_EditedFeat->SetDbxref().reserve(2 * m_EditedFeat->GetDbxref().size());
1520  }
1521  if (!IsCreateNew(action))
1522  {
1524  {
1525  found = true;
1526  m_erase = false;
1527  m_Dbtag = *dbxref_it;
1529  if (m_erase)
1531  }
1532  }
1533 
1534  if (!found)
1535  {
1536  m_Dbtag.Reset();
1537  m_erase = false;
1539  }
1540  if (IsFrom(action))
1541  {
1542  m_EditedFeat->SetDbxref().shrink_to_fit();
1543  }
1544  if (m_EditedFeat->IsSetDbxref() && m_EditedFeat->GetDbxref().empty())
1545  {
1547  }
1548 }
1549 
1551 {
1552  return m_Dbtag && m_Dbtag->IsSetDb() && m_Dbtag->IsSetTag();
1553 }
1554 
1556 {
1557  string db, tag;
1558  NStr::SplitInTwo(value, ":", db, tag);
1560 
1561  if (!db.empty() && !tag.empty())
1562  {
1563  if (m_Dbtag)
1564  {
1565  m_Dbtag->SetDb(db);
1566  m_Dbtag->ResetTag();
1567  if (id != 0)
1568  m_Dbtag->SetTag().SetId(id);
1569  else
1570  m_Dbtag->SetTag().SetStr(tag);
1571  }
1572  else
1573  {
1574  CRef<CDbtag> dbtag(new CDbtag);
1575  dbtag->SetDb(db);
1576  if (id != 0)
1577  dbtag->SetTag().SetId(id);
1578  else
1579  dbtag->SetTag().SetStr(tag);
1580  m_EditedFeat->SetDbxref().push_back(dbtag);
1581  }
1582  }
1583 }
1584 
1586 {
1587  string db = m_Dbtag->GetDb();
1588  string tag;
1589  if (m_Dbtag->GetTag().IsStr())
1590  tag = m_Dbtag->GetTag().GetStr();
1591  if (m_Dbtag->GetTag().IsId())
1593  return db + ":" + tag;
1594 }
1595 
1597 {
1598  m_erase = true;
1599 }
1600 
1601 
1603  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class)
1604  : IEditingActionFeat(seh, subtype, feat_type, ncRNA_class, "CEditingActionFeatEvidence")
1605 {
1606 }
1607 
1609 {
1610  return m_EditedFeat->IsSetExp_ev();
1611 }
1612 
1614 {
1615  if (CSeq_feat::ENUM_METHOD_NAME(EExp_ev)()->IsValidName(value))
1616  {
1617  m_EditedFeat->SetExp_ev(static_cast<CSeq_feat::EExp_ev>(CSeq_feat::ENUM_METHOD_NAME(EExp_ev)()->FindValue(value)));
1618  }
1619 }
1620 
1622 {
1623  return CSeq_feat::ENUM_METHOD_NAME(EExp_ev)()->FindName(m_EditedFeat->GetExp_ev(), true);
1624 }
1625 
1627 {
1629 }
1630 
1632  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class)
1633  : IEditingActionFeat(seh, subtype, feat_type, ncRNA_class, "CEditingActionFeatPseudo")
1634 {
1635 }
1636 
1638 {
1639  return m_EditedFeat->IsSetPseudo();
1640 }
1641 
1643 {
1644  m_EditedFeat->SetPseudo(true);
1645  if (!value.empty() && !NStr::EqualNocase(value,"Unqualified"))
1646  m_EditedFeat->AddOrReplaceQualifier("pseudogene", value);
1647  else
1648  m_EditedFeat->RemoveQualifier("pseudogene");
1649 }
1650 
1652 {
1653  string r = m_EditedFeat->GetNamedQual("pseudogene");
1654  if (r.empty())
1655  r = "Unqualified";
1656  return r;
1657 }
1658 
1660 {
1662  m_EditedFeat->RemoveQualifier("pseudogene");
1663 }
1664 
1666  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class)
1667  : CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "codons_recognized", "CEditingActionFeatCodonsRecognized")
1668 {
1669 }
1670 
1672 {
1676  && !m_EditedFeat->GetData().GetRna().GetExt().GetTRNA().GetCodon().empty();
1677  bool is_qual = m_GBqual && m_GBqual->IsSetVal();
1678  return is_trna || is_qual;
1679 }
1680 
1681 static bool s_IsATGC(char ch)
1682 {
1683  if (ch == 'A' || ch == 'T' || ch == 'G' || ch == 'C' || ch == 'U') {
1684  return true;
1685  } else {
1686  return false;
1687  }
1688 }
1689 
1690 
1691 static const string kAmbiguities = "MRSVWYHKDBN";
1692 static const string kReplacements[] = {
1693  "AC", "AG", "CG", "ACG", "AT", "CT", "ACT", "GT", "AGT", "CGT", "ACGT" };
1694 
1695 static const string s_GetExpansion (const string& ch)
1696 {
1697  size_t pos = NStr::Find(kAmbiguities, ch);
1698  if (pos != string::npos) {
1699  return kReplacements[pos];
1700  } else {
1701  return ch;
1702  }
1703 }
1704 
1705 
1706 static vector<string> ParseDegenerateCodons (string codon)
1707 {
1708  vector<string> replacements;
1709 
1710  if (codon.length() == 3 && s_IsATGC(codon.c_str()[0])) {
1711  string this_codon = codon.substr(0, 1);
1712  replacements.push_back(this_codon);
1713 
1714  for (int i = 1; i < 3; i++) {
1715  string ch = s_GetExpansion (codon.substr(i, 1));
1716  auto num_now = replacements.size();
1717  // add copies for each expansion letter beyond the first
1718  for (unsigned int j = 1; j < ch.length(); j++) {
1719  for (auto k = 0; k < num_now; k++) {
1720  string cpy = replacements[k];
1721  replacements.push_back(cpy);
1722  }
1723  }
1724  for (auto k = 0; k < num_now; k++) {
1725  for (unsigned int j = 0; j < ch.length(); j++) {
1726  replacements[j * num_now + k].append(ch.substr(j, 1));
1727  }
1728  }
1729  }
1730  } else {
1731  replacements.push_back(codon);
1732  }
1733  return replacements;
1734 }
1735 
1737 {
1738  if (m_GBqual)
1739  m_GBqual->SetVal(value);
1740  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsRna()
1743  {
1744  m_EditedFeat->SetData().SetRna().SetExt().SetTRNA().ResetCodon();
1745  string v = value;
1747  NStr::ToUpper(v);
1748  if (!v.empty())
1749  {
1750  vector<string> codons = ParseDegenerateCodons(v);
1751  for (unsigned int j = 0; j < codons.size(); j++)
1752  {
1754  if (val > -1)
1755  {
1756  m_EditedFeat->SetData().SetRna().SetExt().SetTRNA().SetCodon().push_back(val);
1757  }
1758  }
1759  }
1760  }
1761  else
1763 }
1764 
1766 {
1767  string r;
1768  if (m_GBqual)
1769  {
1770  r = m_GBqual->GetVal();
1771  }
1775  && !m_EditedFeat->GetData().GetRna().GetExt().GetTRNA().GetCodon().empty())
1776  {
1777  for (CTrna_ext::TCodon::const_iterator i = m_EditedFeat->GetData().GetRna().GetExt().GetTRNA().GetCodon().begin(); i != m_EditedFeat->GetData().GetRna().GetExt().GetTRNA().GetCodon().end(); ++i)
1779  }
1780  return r;
1781 }
1782 
1784 {
1785  if (m_GBqual)
1786  m_erase = true;
1788  m_EditedFeat->SetData().SetRna().SetExt().SetTRNA().ResetCodon();
1789 }
1790 
1792  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class)
1793  : CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "transl_except", "CEditingActionFeatTranslExcept")
1794 {
1795 }
1796 
1798 {
1799  bool found = false;
1800  if (!IsCreateNew(action) && m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsCdregion())
1801  {
1802  EDIT_EACH_CODEBREAK_ON_CDREGION(code_break_it, m_EditedFeat->SetData().SetCdregion())
1803  {
1804  if (*code_break_it)
1805  {
1806  found = true;
1807  m_erase = false;
1808  m_CodeBreak = *code_break_it;
1810  if (m_erase)
1811  ERASE_CODEBREAK_ON_CDREGION(code_break_it, m_EditedFeat->SetData().SetCdregion());
1812  }
1813  }
1814  }
1815  if (!found)
1816  {
1817  m_CodeBreak.Reset();
1818  m_erase = false;
1820  }
1823  m_EditedFeat->SetData().SetCdregion().ResetCode_break();
1824 }
1825 
1827 {
1828  bool is_qual = m_GBqual && m_GBqual->IsSetVal();
1829  return m_CodeBreak || is_qual;
1830 }
1831 
1833 {
1834  if (m_GBqual)
1835  m_GBqual->SetVal(value);
1836  else if (m_CodeBreak)
1837  {
1838  vector<string> v;
1839  NStr::Split(value, ":", v);
1840  if (v.size() == 2)
1841  {
1842  char aa = v[1][0];
1843  m_CodeBreak->SetAa().SetNcbieaa(aa);
1844  string loc_label = v[0];
1845  if (!NStr::IsBlank(loc_label))
1846  {
1847  int start = NStr::StringToInt(loc_label);
1848  start -= 1;
1849  const CSeq_loc &loc = m_EditedFeat->GetLocation();
1850  CRef<CSeq_loc> cb_loc (new CSeq_loc());
1851  cb_loc->SetPnt().SetPoint(start);
1852  cb_loc->SetPnt().SetId().Assign(*loc.GetId());
1853  if (loc.IsSetStrand() && loc.GetStrand() == eNa_strand_minus)
1854  cb_loc->SetPnt().SetStrand(eNa_strand_minus);
1855 
1856  m_CodeBreak->SetLoc(*cb_loc);
1857  }
1858  }
1859  }
1860  else
1862 }
1863 
1865 {
1866  string r;
1867  if (m_GBqual)
1868  {
1869  r = m_GBqual->GetVal();
1870  }
1871  else if (m_CodeBreak)
1872  {
1873  string loc_label;
1875  {
1876  // find offset from beginning of protein
1877  CScope &scope = m_Feat.GetScope();
1879  seq_pos += 1;
1880  loc_label = NStr::NumericToString(seq_pos);
1881  }
1882  char aa = 0;
1883  string str;
1884  vector<char> seqData;
1885  if (m_CodeBreak->IsSetAa())
1886  {
1887  switch (m_CodeBreak->GetAa().Which())
1888  {
1891  CSeqConvert::Convert(str, CSeqUtil::e_Ncbi8aa, 0, static_cast<TSeqPos>(str.size()), seqData, CSeqUtil::e_Ncbieaa);
1892  aa = seqData[0];
1893  break;
1896  CSeqConvert::Convert(str, CSeqUtil::e_Ncbistdaa, 0, static_cast<TSeqPos>(str.size()), seqData, CSeqUtil::e_Ncbieaa);
1897  aa = seqData[0];
1898  break;
1900  seqData.push_back(m_CodeBreak->GetAa().GetNcbieaa());
1901  aa = seqData[0];
1902  break;
1903  default:
1904  break;
1905  }
1906  }
1907  if (!loc_label.empty())
1908  r = loc_label;
1909  if (aa != 0)
1910  {
1911  if (!r.empty())
1912  r += ":";
1913  r += aa;
1914  }
1915  }
1916  return r;
1917 }
1918 
1920 {
1921  if (m_GBqual || m_CodeBreak)
1922  m_erase = true;
1923 }
1924 
1926  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class)
1927  : CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "anticodon", "CEditingActionFeatAnticodon")
1928 {
1929 }
1930 
1932 {
1936  bool is_qual = m_GBqual && m_GBqual->IsSetVal();
1937  return is_trna || is_qual;
1938 }
1939 
1941 {
1942  bool partial5 = seq_int.IsPartialStart(eExtreme_Biological);
1943  bool partial3 = seq_int.IsPartialStop(eExtreme_Biological);
1944  string rval(kEmptyStr);
1945 
1946  if (seq_int.CanGetStrand() && seq_int.GetStrand() == eNa_strand_minus) {
1947  rval = (string)"complement(" + (partial3 ? "<" : "")
1949  + ".." + (partial5 ? ">" : "")
1951  } else {
1952  rval = (partial5 ? "<" : "")
1954  + ".." + (partial3 ? ">" : "")
1956  }
1957  return rval;
1958 };
1959 
1960 
1962 {
1963  if (m_GBqual)
1964  m_GBqual->SetVal(value);
1966  {
1967  // we are not writing anticodon value in this circumstances
1968  }
1969  else
1970  {
1972  }
1973 }
1974 
1976 {
1977  string r;
1978  if (m_GBqual)
1979  {
1980  r = m_GBqual->GetVal();
1981  }
1985  {
1986  const CSeq_loc &loc = m_EditedFeat->GetData().GetRna().GetExt().GetTRNA().GetAnticodon();
1987  if (loc.IsInt())
1988  {
1989  r = GetIntervalString(loc.GetInt());
1990  }
1991  else if (loc.IsMix())
1992  {
1993  list<string> rval;
1994  ITERATE (list <CRef <CSeq_loc> >, it, loc.GetMix().Get())
1995  {
1996  if ( (*it)->IsInt())
1997  {
1998  rval.push_back(GetIntervalString( (*it)->GetInt() ));
1999  }
2000  else
2001  {
2002  r = "complex location";
2003  rval.clear();
2004  break;
2005  }
2006  }
2007  if (!rval.empty())
2008  r = NStr::Join(rval, ", ");
2009  }
2010  }
2011  return r;
2012 }
2013 
2015 {
2016  if (m_GBqual)
2017  m_erase = true;
2019  m_EditedFeat->SetData().SetRna().SetExt().SetTRNA().ResetAnticodon();
2020 }
2021 
2022 
2023 
2025  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class,
2026  const string &qual)
2027  : IEditingActionFeat(seh, subtype, feat_type, ncRNA_class, "CEditingActionFeatRnaQual"), m_qual(qual), m_erase(false)
2028 {
2029 }
2030 
2032 {
2033  bool found = false;
2034  if (!IsCreateNew(action))
2035  {
2038  {
2039  EDIT_EACH_QUAL_ON_RNAGEN(rnaqual_it, m_EditedFeat->SetData().SetRna().SetExt().SetGen())
2040  {
2041  if ((*rnaqual_it)->IsSetQual() && (*rnaqual_it)->GetQual() == m_qual)
2042  {
2043  found = true;
2044  m_erase = false;
2045  m_RnaQual = *rnaqual_it;
2047  if (m_erase)
2048  ERASE_QUAL_ON_RNAGEN(rnaqual_it, m_EditedFeat->SetData().SetRna().SetExt().SetGen());
2049  }
2050  }
2051  }
2052  }
2053 
2054  if (IsFrom(action) && m_EditedFeat->IsSetQual() && !m_EditedFeat->GetQual().empty() && m_EditedFeat->GetQual().capacity() < 2 * m_EditedFeat->GetQual().size())
2055  {
2056  m_EditedFeat->SetQual().reserve(2 * m_EditedFeat->GetQual().size());
2057  }
2058 
2059  if (!IsCreateNew(action))
2060  {
2062  {
2063  if ((*gbqual_it)->IsSetQual() && (*gbqual_it)->GetQual() == m_qual)
2064  {
2065  found = true;
2066  m_erase = false;
2067  m_GBqual = *gbqual_it;
2069  if (m_erase)
2071  }
2072  }
2073  }
2074  if (!found)
2075  {
2076  m_GBqual.Reset();
2077  m_RnaQual.Reset();
2078  m_erase = false;
2080  }
2081 
2082  if (IsFrom(action))
2083  {
2084  m_EditedFeat->SetQual().shrink_to_fit();
2085  }
2086 }
2087 
2089 {
2090  return (m_GBqual && m_GBqual->IsSetVal()) || (m_RnaQual && m_RnaQual->IsSetVal());
2091 }
2092 
2094 {
2095  if (m_GBqual)
2096  m_GBqual->SetVal(value);
2097  else if (m_RnaQual)
2101  {
2102  CRef<CRNA_qual> qual(new CRNA_qual);
2103  qual->SetQual(m_qual);
2104  qual->SetVal(value);
2105  m_EditedFeat->SetData().SetRna().SetExt().SetGen().SetQuals().Set().push_back(qual);
2106  }
2107  else
2109 }
2110 
2112 {
2113  if (m_RnaQual)
2114  return m_RnaQual->GetVal();
2115  if (m_GBqual)
2116  return m_GBqual->GetVal();
2117  return kEmptyStr;
2118 }
2119 
2121 {
2122  m_erase = true;
2123 }
2124 
2126  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class)
2127  : CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "region", "CEditingActionFeatRegion")
2128 {
2129 }
2130 
2132 {
2133  return (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsRegion()) ||
2134  (m_GBqual && m_GBqual->IsSetVal());
2135 }
2136 
2138 {
2139  if (m_GBqual)
2140  m_GBqual->SetVal(value);
2141  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsRegion())
2142  m_EditedFeat->SetData().SetRegion(value);
2143  else
2145 }
2146 
2148 {
2149  if (m_GBqual)
2150  return m_GBqual->GetVal();
2151  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsRegion())
2152  return m_EditedFeat->GetData().GetRegion();
2153 
2154  return kEmptyStr;
2155 }
2156 
2158 {
2159  if (m_GBqual)
2160  m_erase = true;
2161  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsRegion())
2163 }
2164 
2166  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class)
2167  : CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "codon_start", "CEditingActionFeatCodonStart")
2168 {
2169 }
2170 
2172 {
2174  || (m_GBqual && m_GBqual->IsSetVal());
2175 }
2176 
2178 {
2179  if (m_GBqual)
2180  m_GBqual->SetVal(value);
2182  {
2183  if (value == "1")
2184  m_EditedFeat->SetData().SetCdregion().SetFrame(CCdregion::eFrame_one);
2185  if (value == "2")
2186  m_EditedFeat->SetData().SetCdregion().SetFrame(CCdregion::eFrame_two);
2187  if (value == "3")
2188  m_EditedFeat->SetData().SetCdregion().SetFrame(CCdregion::eFrame_three);
2189  }
2190  else
2192 }
2193 
2195 {
2196  string val;
2197  if (m_GBqual)
2198  val = m_GBqual->GetVal();
2200  {
2201  switch (m_EditedFeat->GetData().GetCdregion().GetFrame())
2202  {
2203  case CCdregion::eFrame_one:
2205  val = "1";
2206  break;
2207  case CCdregion::eFrame_two:
2208  val = "2";
2209  break;
2211  val = "3";
2212  break;
2213  }
2214  }
2215 
2216  if (val.empty())
2217  val = "1";
2218  return val;
2219 }
2220 
2222 {
2223  if (m_GBqual)
2224  m_erase = true;
2226  m_EditedFeat->SetData().SetCdregion().ResetFrame();
2227 }
2228 
2230  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class)
2231  : CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "transl_table", "CEditingActionFeatTranslTable"), m_code_table(CGen_code_table::GetCodeTable())
2232 
2233 {
2234 }
2235 
2237 {
2239  || (m_GBqual && m_GBqual->IsSetVal());
2240 }
2241 
2243 {
2244  if (m_GBqual)
2245  m_GBqual->SetVal(value);
2247  {
2248  const CGenetic_code_table::Tdata& codes = m_code_table.Get();
2249  ITERATE (CGenetic_code_table::Tdata, it, codes)
2250  {
2251  string str = (*it)->GetName();
2252  int id = (*it)->GetId();
2253  if (str == value)
2254  {
2255  m_EditedFeat->SetData().SetCdregion().SetCode().SetId(id);
2256  return;
2257  }
2258  }
2260  m_EditedFeat->SetData().SetCdregion().SetCode().SetId(gc);
2261  }
2262  else
2264 }
2265 
2267 {
2268  if (m_GBqual)
2269  {
2270  return m_GBqual->GetVal();
2271  }
2273  {
2274  int gc = m_EditedFeat->GetData().GetCdregion().GetCode().GetId();
2275  const CGenetic_code_table::Tdata& codes = m_code_table.Get();
2276 
2277  ITERATE (CGenetic_code_table::Tdata, it, codes)
2278  {
2279  string str = (*it)->GetName();
2280  int id = (*it)->GetId();
2281  if (id == gc)
2282  {
2283  return str;
2284  }
2285  }
2286  return NStr::IntToString(gc);
2287  }
2288 
2289  return kEmptyStr;
2290 }
2291 
2293 {
2294  if (m_GBqual)
2295  m_erase = true;
2297  m_EditedFeat->SetData().SetCdregion().ResetCode();
2298 }
2299 
2300 
2301 
2303  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class)
2304  : CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "description", "CEditingActionFeatDesc")
2305 {
2306 }
2307 
2309 {
2312  || (m_GBqual && m_GBqual->IsSetVal());
2313 }
2314 
2316 {
2317  if (m_GBqual)
2318  m_GBqual->SetVal(value);
2319  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsGene())
2320  m_EditedFeat->SetData().SetGene().SetDesc(value);
2321  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsProt())
2322  m_EditedFeat->SetData().SetProt().SetDesc(value);
2323  else
2325 }
2326 
2328 {
2329  if (m_GBqual)
2330  {
2331  return m_GBqual->GetVal();
2332  }
2334  return m_EditedFeat->GetData().GetGene().GetDesc();
2336  return m_EditedFeat->GetData().GetProt().GetDesc();
2337 
2338  return kEmptyStr;
2339 }
2340 
2342 {
2343  if (m_GBqual)
2344  m_erase = true;
2345  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsGene())
2346  m_EditedFeat->SetData().SetGene().ResetDesc();
2347  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsProt())
2348  m_EditedFeat->SetData().SetProt().ResetDesc();
2349 }
2350 
2351 
2353  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class)
2354  : IEditingActionFeat(seh, subtype, feat_type, ncRNA_class, "CEditingActionFeatNcRnaClass")
2355 {
2356 }
2357 
2359 {
2360  return m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsRna()
2362 }
2363 
2365 {
2366  if (m_EditedFeat->IsSetData() &&
2367  m_EditedFeat->GetData().IsRna() &&
2370  m_EditedFeat->SetData().SetRna().SetExt().SetGen().SetClass(value);
2371 }
2372 
2374 {
2375  if (IsSetValue())
2377  return kEmptyStr;
2378 }
2379 
2381 {
2382  if (m_EditedFeat->IsSetData() &&
2383  m_EditedFeat->GetData().IsRna() &&
2384  m_EditedFeat->GetData().GetRna().IsSetExt() &&
2386  m_EditedFeat->SetData().SetRna().SetExt().SetGen().ResetClass();
2387 }
2388 
2389 
2391  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class)
2392  : CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "locus_tag", "CEditingActionFeatLocus_tag")
2393 {
2394 }
2395 
2397 {
2400  (m_GBqual && m_GBqual->IsSetVal());
2401 }
2402 
2404 {
2405  if (m_GBqual)
2406  {
2407  m_GBqual->SetVal(value);
2408  }
2409  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsGene())
2410  {
2411  m_EditedFeat->SetData().SetGene().SetLocus_tag(value);
2412  }
2413  else if (m_EditedFeat->GetGeneXref() != NULL)
2414  {
2415  m_EditedFeat->SetGeneXref().SetLocus_tag(value);
2416  }
2417  else
2418  {
2420  }
2421 }
2422 
2424 {
2425  if (m_GBqual)
2426  return m_GBqual->GetVal();
2428  return m_EditedFeat->GetData().GetGene().GetLocus_tag();
2430  return m_EditedFeat->GetGeneXref()->GetLocus_tag();
2431  return kEmptyStr;
2432 }
2433 
2435 {
2436  if (m_GBqual)
2437  m_erase = true;
2438  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsGene())
2439  m_EditedFeat->SetData().SetGene().ResetLocus_tag();
2440  else if (m_EditedFeat->GetGeneXref() != NULL)
2441  {
2442  bool before = m_EditedFeat->SetGeneXref().IsSuppressed();
2443  m_EditedFeat->SetGeneXref().ResetLocus_tag();
2444  bool after = m_EditedFeat->SetGeneXref().IsSuppressed();
2445  if (!before && after)
2446  RemoveGeneXref();
2447  }
2448 }
2449 
2451  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class)
2452  : CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "maploc", "CEditingActionFeatMaploc")
2453 {
2454 }
2455 
2457 {
2460  (m_GBqual && m_GBqual->IsSetVal());
2461 }
2462 
2464 {
2465  if (m_GBqual)
2466  {
2467  m_GBqual->SetVal(value);
2468  }
2469  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsGene())
2470  {
2471  m_EditedFeat->SetData().SetGene().SetMaploc(value);
2472  }
2473  else if (m_EditedFeat->GetGeneXref() != NULL)
2474  {
2475  m_EditedFeat->SetGeneXref().SetMaploc(value);
2476  }
2477  else
2478  {
2480  }
2481 }
2482 
2484 {
2485  if (m_GBqual)
2486  return m_GBqual->GetVal();
2488  return m_EditedFeat->GetData().GetGene().GetMaploc();
2490  return m_EditedFeat->GetGeneXref()->GetMaploc();
2491  return kEmptyStr;
2492 }
2493 
2495 {
2496  if (m_GBqual)
2497  m_erase = true;
2498  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsGene())
2499  m_EditedFeat->SetData().SetGene().ResetMaploc();
2500  else if (m_EditedFeat->GetGeneXref() != NULL)
2501  {
2502  bool before = m_EditedFeat->SetGeneXref().IsSuppressed();
2503  m_EditedFeat->SetGeneXref().ResetMaploc();
2504  bool after = m_EditedFeat->SetGeneXref().IsSuppressed();
2505  if (!before && after)
2506  RemoveGeneXref();
2507  }
2508 }
2509 
2511  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class)
2512  : IEditingActionFeat(seh, subtype, feat_type, ncRNA_class, "CEditingActionFeatSynonym"), m_erase(false), m_syn(NULL), m_qual("synonym")
2513 {
2514 }
2515 
2517 {
2518  bool found = false;
2519  m_GBqual.Reset();
2520  if (!IsCreateNew(action))
2521  {
2523  {
2524  EDIT_EACH_SYNONYM_ON_GENEREF(syn_it, m_EditedFeat->SetData().SetGene())
2525  {
2526  found = true;
2527  m_erase = false;
2528  m_syn = &*syn_it;
2530  if (m_erase)
2531  ERASE_SYNONYM_ON_GENEREF(syn_it, m_EditedFeat->SetData().SetGene());
2532  }
2533  }
2534  m_syn = NULL;
2535  if (!found && m_EditedFeat->GetGeneXref() != NULL)
2536  {
2537  bool before = m_EditedFeat->SetGeneXref().IsSuppressed();
2539  {
2540  found = true;
2541  m_erase = false;
2542  m_syn = &*syn_it;
2544  if (m_erase)
2546  }
2547  bool after = m_EditedFeat->SetGeneXref().IsSuppressed();
2548  if (!before && after)
2549  RemoveGeneXref();
2550  }
2551  m_syn = NULL;
2552  if (!found)
2553  {
2554  if (IsFrom(action) && m_EditedFeat->IsSetQual() && !m_EditedFeat->GetQual().empty() && m_EditedFeat->GetQual().capacity() < 2 * m_EditedFeat->GetQual().size())
2555  {
2556  m_EditedFeat->SetQual().reserve(2 * m_EditedFeat->GetQual().size());
2557  }
2559  {
2560  if ((*gbqual_it)->IsSetQual() && (*gbqual_it)->GetQual() == m_qual)
2561  {
2562  found = true;
2563  m_erase = false;
2564  m_GBqual = *gbqual_it;
2566  if (m_erase)
2568  }
2569  }
2570  if (IsFrom(action))
2571  {
2572  m_EditedFeat->SetQual().shrink_to_fit();
2573  }
2574  }
2575  }
2576 
2577  if (!found)
2578  {
2579  m_syn = NULL;
2580  m_GBqual.Reset();
2581  m_erase = false;
2583  }
2584 }
2585 
2587 {
2588  return m_syn != NULL || (m_GBqual && m_GBqual->IsSetVal());
2589 }
2590 
2592 {
2593  if (m_GBqual)
2594  {
2595  m_GBqual->SetVal(value);
2596  }
2597  else if (m_syn)
2598  {
2599  *m_syn = value;
2600  }
2601  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsGene())
2602  {
2603  m_EditedFeat->SetData().SetGene().SetSyn().push_back(value);
2604  }
2605  else if (m_EditedFeat->GetGeneXref() != NULL)
2606  {
2607  m_EditedFeat->SetGeneXref().SetSyn().push_back(value);
2608  }
2609  else
2610  {
2612  }
2613 }
2614 
2616 {
2617  if (m_GBqual)
2618  return m_GBqual->GetVal();
2619  else if (m_syn)
2620  return *m_syn;
2621 
2622  return kEmptyStr;
2623 }
2624 
2626 {
2627  m_erase = true;
2628 }
2629 
2631  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class)
2632  : CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "allele", "CEditingActionFeatAllele")
2633 {
2634 }
2635 
2637 {
2640  (m_GBqual && m_GBqual->IsSetVal());
2641 }
2642 
2644 {
2645  if (m_GBqual)
2646  {
2647  m_GBqual->SetVal(value);
2648  }
2649  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsGene())
2650  {
2651  m_EditedFeat->SetData().SetGene().SetAllele(value);
2652  }
2653  else if (m_EditedFeat->GetGeneXref() != NULL)
2654  {
2655  m_EditedFeat->SetGeneXref().SetAllele(value);
2656  }
2657  else
2658  {
2660  }
2661 }
2662 
2664 {
2665  if (m_GBqual)
2666  return m_GBqual->GetVal();
2668  return m_EditedFeat->GetData().GetGene().GetAllele();
2670  return m_EditedFeat->GetGeneXref()->GetAllele();
2671 
2672  return kEmptyStr;
2673 }
2674 
2676 {
2677  if (m_GBqual)
2678  m_erase = true;
2679  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsGene())
2680  m_EditedFeat->SetData().SetGene().ResetAllele();
2681  else if (m_EditedFeat->GetGeneXref() != NULL)
2682  {
2683  bool before = m_EditedFeat->SetGeneXref().IsSuppressed();
2684  m_EditedFeat->SetGeneXref().ResetAllele();
2685  bool after = m_EditedFeat->SetGeneXref().IsSuppressed();
2686  if (!before && after)
2687  RemoveGeneXref();
2688  }
2689 }
2690 
2692  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class)
2693  : IEditingActionFeat(seh, subtype, feat_type, ncRNA_class, "CEditingActionFeatActivity"), m_erase(false), m_activity(NULL), m_qual("activity")
2694 {
2695 }
2696 
2698 {
2699  bool found = false;
2700  GoToProtFeature();
2701  if (!IsCreateNew(action))
2702  {
2703  m_GBqual.Reset();
2705  {
2706  EDIT_EACH_ACTIVITY_ON_PROTREF(activity_it, m_EditedFeat->SetData().SetProt())
2707  {
2708  found = true;
2709  m_erase = false;
2710  m_activity = &*activity_it;
2712  if (m_erase)
2713  ERASE_ACTIVITY_ON_PROTREF(activity_it, m_EditedFeat->SetData().SetProt());
2714  }
2715  }
2716  m_activity = NULL;
2717  if (!found)
2718  {
2719  if (IsFrom(action) && m_EditedFeat->IsSetQual() && !m_EditedFeat->GetQual().empty() && m_EditedFeat->GetQual().capacity() < 2 * m_EditedFeat->GetQual().size())
2720  {
2721  m_EditedFeat->SetQual().reserve(2 * m_EditedFeat->GetQual().size());
2722  }
2724  {
2725  if ((*gbqual_it)->IsSetQual() && (*gbqual_it)->GetQual() == m_qual)
2726  {
2727  found = true;
2728  m_erase = false;
2729  m_GBqual = *gbqual_it;
2731  if (m_erase)
2733  }
2734  }
2735  if (IsFrom(action))
2736  {
2737  m_EditedFeat->SetQual().shrink_to_fit();
2738  }
2739  }
2740  }
2741 
2742  if (!found)
2743  {
2744  m_activity = NULL;
2745  m_GBqual.Reset();
2746  m_erase = false;
2748  }
2749  GoToOrigFeature();
2750 }
2751 
2753 {
2754  return m_activity != NULL || (m_GBqual && m_GBqual->IsSetVal());
2755 }
2756 
2758 {
2759  if (m_GBqual)
2760  {
2761  m_GBqual->SetVal(value);
2762  }
2763  else if (m_activity)
2764  {
2765  *m_activity = value;
2766  }
2767  else
2768  {
2770  {
2771  m_EditedFeat->SetData().SetProt().SetActivity().push_back(value);
2772  }
2773  else
2774  {
2776  }
2777  }
2778 }
2779 
2781 {
2782  if (m_GBqual)
2783  return m_GBqual->GetVal();
2784  else if (m_activity)
2785  return *m_activity;
2786  return kEmptyStr;
2787 }
2788 
2790 {
2791  m_erase = true;
2792 }
2793 
2795  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class)
2796  : IEditingActionFeat(seh, subtype, feat_type, ncRNA_class, "CEditingActionFeatPartial")
2797 {
2798 }
2799 
2801 {
2802  return m_EditedFeat->IsSetPartial();
2803 }
2804 
2806 {
2807  if (NStr::EqualNocase(value,"true"))
2808  m_EditedFeat->SetPartial(true);
2809  if (NStr::EqualNocase(value,"false"))
2810  m_EditedFeat->SetPartial(false);
2811 }
2812 
2814 {
2815  if (m_EditedFeat->GetPartial())
2816  return "true";
2817  return "false";
2818 }
2819 
2821 {
2823 }
2824 
2826  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class)
2827  : CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "translation", "CEditingActionFeatTranslation")
2828 {
2829 }
2830 
2832 {
2833  if (m_EditedFeat->IsSetProduct())
2834  {
2835  const CSeq_id *id = m_EditedFeat->GetProduct().GetId();
2836  if (id && m_Feat)
2837  {
2839  if (bsh)
2840  {
2841  return true;
2842  }
2843  }
2844  }
2845 
2846  return (m_GBqual && m_GBqual->IsSetVal());
2847 }
2848 
2850 {
2851  if (m_GBqual)
2852  {
2853  m_GBqual->SetVal(value);
2854  }
2855  else if (m_EditedFeat->IsSetProduct())
2856  {
2857  // do nothing
2858  }
2859  else
2860  {
2862  }
2863 }
2864 
2866 {
2867  if (m_GBqual)
2868  return m_GBqual->GetVal();
2869  else if (m_EditedFeat->IsSetProduct())
2870  {
2871  const CSeq_id *id = m_EditedFeat->GetProduct().GetId();
2872  if (id && m_Feat)
2873  {
2875  if (bsh)
2876  {
2877  string prot_seq;
2878  CSeqVector prot_vec(*(bsh.GetCompleteBioseq()), &m_Feat.GetScope());
2879  prot_vec.SetCoding(CSeq_data::e_Ncbieaa);
2880  prot_vec.GetSeqData(0, prot_vec.size(), prot_seq);
2881  return prot_seq;
2882  }
2883  }
2884  }
2885 
2886  return kEmptyStr;
2887 }
2888 
2890 {
2891  if (m_GBqual)
2892  m_erase = true;
2893 }
2894 
2895 
2897  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class)
2898  : IEditingActionFeat(seh, subtype, feat_type, ncRNA_class, "CEditingActionFeatEcNumber"), m_erase(false), m_ec(NULL), m_qual("EC_number")
2899 {
2900  ResetScope();
2901 }
2902 
2904 {
2905  bool found = false;
2906  GoToProtFeature();
2907  if (!IsCreateNew(action))
2908  {
2909  m_GBqual.Reset();
2911  {
2913  {
2914  found = true;
2915  m_erase = false;
2916  m_ec = &*ec_it;
2918  if (m_erase)
2919  ERASE_ECNUMBER_ON_PROTREF(ec_it, m_EditedFeat->SetData().SetProt());
2920  }
2921  }
2922  m_ec = NULL;
2923  if (!found && m_EditedFeat->GetProtXref() != NULL)
2924  {
2925  CProt_ref& prot_feat = m_EditedFeat->SetProtXref();
2926  EDIT_EACH_ECNUMBER_ON_PROTREF(ec_it, prot_feat)
2927  {
2928  found = true;
2929  m_erase = false;
2930  m_ec = &*ec_it;
2932  if (m_erase)
2933  ERASE_ECNUMBER_ON_PROTREF(ec_it, prot_feat);
2934  }
2935  }
2936  m_ec = NULL;
2937  if (!found)
2938  {
2939  if (IsFrom(action) && m_EditedFeat->IsSetQual() && !m_EditedFeat->GetQual().empty() && m_EditedFeat->GetQual().capacity() < 2 * m_EditedFeat->GetQual().size())
2940  {
2941  m_EditedFeat->SetQual().reserve(2 * m_EditedFeat->GetQual().size());
2942  }
2944  {
2945  if ((*gbqual_it)->IsSetQual() && (*gbqual_it)->GetQual() == m_qual)
2946  {
2947  found = true;
2948  m_erase = false;
2949  m_GBqual = *gbqual_it;
2951  if (m_erase)
2953  }
2954  }
2955  if (IsFrom(action))
2956  {
2957  m_EditedFeat->SetQual().shrink_to_fit();
2958  }
2959  }
2960  }
2961 
2962  if (!found)
2963  {
2964  m_ec = NULL;
2965  m_GBqual.Reset();
2966  m_erase = false;
2968  }
2969  GoToOrigFeature();
2970 }
2971 
2973 {
2974  return m_ec != NULL || (m_GBqual && m_GBqual->IsSetVal());
2975 }
2976 
2978 {
2979  if (m_GBqual)
2980  {
2981  m_GBqual->SetVal(value);
2982  }
2983  else if (m_ec)
2984  {
2985  *m_ec = value;
2986  }
2987  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsProt())
2988  {
2989  m_EditedFeat->SetData().SetProt().SetEc().push_back(value);
2990  }
2991  else if (m_EditedFeat->GetProtXref() != NULL)
2992  {
2993  m_EditedFeat->SetProtXref().SetEc().push_back(value);
2994  }
2995  else
2996  {
2998  }
2999 }
3000 
3002 {
3003  if (m_GBqual)
3004  return m_GBqual->GetVal();
3005  else if (m_ec)
3006  return *m_ec;
3007  return kEmptyStr;
3008 }
3009 
3011 {
3012  m_erase = true;
3013 }
3014 
3016 {
3017  FindOrCreateProtFeat(action);
3018 }
3019 
3021 {
3023 }
3024 
3026  const CSeqFeatData::ESubtype subtype,
3027  const CSeqFeatData::E_Choice feat_type,
3028  const string& ncRNA_class)
3029  : IEditingActionFeat(seh, subtype, feat_type, ncRNA_class, "CEditingActionFeatProduct"), m_erase(false), m_name(NULL), m_qual("product")
3030 {
3031  ResetScope();
3032 }
3033 
3035 {
3036  bool found = false;
3037  GoToProtFeature();
3038  if (!IsCreateNew(action))
3039  {
3040  m_GBqual.Reset();
3042  {
3043  EDIT_EACH_NAME_ON_PROTREF(name_it, m_EditedFeat->SetData().SetProt())
3044  {
3045  found = true;
3046  m_erase = false;
3047  m_name = &*name_it;
3049  if (m_erase)
3050  ERASE_NAME_ON_PROTREF(name_it, m_EditedFeat->SetData().SetProt());
3051  }
3052  }
3053  m_name = NULL;
3054  if (!found && m_EditedFeat->GetProtXref() != NULL)
3055  {
3056  CProt_ref& prot_feat = m_EditedFeat->SetProtXref();
3057  EDIT_EACH_NAME_ON_PROTREF(name_it, prot_feat)
3058  {
3059  found = true;
3060  m_erase = false;
3061  m_name = &*name_it;
3063  if (m_erase)
3064  ERASE_NAME_ON_PROTREF(name_it, prot_feat);
3065  }
3066  }
3067  m_name = NULL;
3068  if (!found && m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsRna())
3069  {
3070  found = true;
3072  }
3073  m_name = NULL;
3074  if (!found)
3075  {
3076  if (IsFrom(action) && m_EditedFeat->IsSetQual() && !m_EditedFeat->GetQual().empty() && m_EditedFeat->GetQual().capacity() < 2 * m_EditedFeat->GetQual().size())
3077  {
3078  m_EditedFeat->SetQual().reserve(2 * m_EditedFeat->GetQual().size());
3079  }
3081  {
3082  if ((*gbqual_it)->IsSetQual() && (*gbqual_it)->GetQual() == m_qual)
3083  {
3084  found = true;
3085  m_erase = false;
3086  m_GBqual = *gbqual_it;
3088  if (m_erase)
3090  }
3091  }
3092  if (IsFrom(action))
3093  {
3094  m_EditedFeat->SetQual().shrink_to_fit();
3095  }
3096  }
3097  }
3098 
3099  if (!found)
3100  {
3101  m_name = NULL;
3102  m_GBqual.Reset();
3103  m_erase = false;
3105  }
3106  GoToOrigFeature();
3107 }
3108 
3110 {
3111  return m_name != NULL || (m_GBqual && m_GBqual->IsSetVal()) ||
3113 }
3114 
3116 {
3117  if (m_GBqual)
3118  {
3119  m_GBqual->SetVal(value);
3120  }
3121  else if (m_name)
3122  {
3123  *m_name = value;
3124  }
3125  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsRna())
3126  {
3127  string val = value;
3128  if (val == "fM" || val == "iM")
3129  val += "et";
3130  if (val == "fMet" || val == "iMet")
3131  val = "tRNA-" + val;
3132  if ((val == "tRNA-fMet" || val == "tRNA-iMet") && m_EditedFeat->GetData().GetRna().IsSetType() && m_EditedFeat->GetData().GetRna().GetType() == CRNA_ref::eType_tRNA)
3133  {
3135  }
3136  else
3137  {
3138  string remainder;
3139  m_EditedFeat->SetData().SetRna().SetRnaProductName(value, remainder);
3140  if (!NStr::IsBlank(remainder))
3141  {
3143  {
3144  m_EditedFeat->SetComment(m_EditedFeat->GetComment() + "; " + remainder);
3145  }
3146  else
3147  {
3148  m_EditedFeat->SetComment(remainder);
3149  }
3150  }
3151  }
3152  }
3153  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsProt())
3154  {
3155  m_EditedFeat->SetData().SetProt().SetName().push_back(value);
3156  }
3157  else if (m_EditedFeat->GetProtXref() != NULL)
3158  {
3159  m_EditedFeat->SetProtXref().SetName().push_back(value);
3160  }
3161  else
3162  {
3164  }
3165 }
3166 
3168 {
3169  if (m_GBqual)
3170  return m_GBqual->GetVal();
3171  else if (m_name)
3172  return *m_name;
3174  {
3176  }
3177  return kEmptyStr;
3178 }
3179 
3181 {
3182  m_erase = true;
3184  {
3185  string remainder;
3186  m_EditedFeat->SetData().SetRna().SetRnaProductName(kEmptyStr, remainder);
3187  }
3188 }
3189 
3191 {
3192  FindOrCreateProtFeat(action);
3193 }
3194 
3196 {
3198 }
3199 
3200 
3201 // data.gene.locus OR xref.data.gene.locus OR qual.val where qual.qual = "locus"
3203  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class,
3204  const string &name)
3205  : CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "locus", name)
3206 {
3207  ResetScope();
3208 }
3209 
3211 {
3213  bool is_xref = (m_EditedFeat->GetGeneXref() != NULL) && m_EditedFeat->GetGeneXref()->IsSetLocus();
3214  bool is_qual = m_GBqual && m_GBqual->IsSetVal();
3215  return is_gene || is_xref || is_qual;
3216 }
3217 
3219 {
3220  if (m_GBqual)
3221  {
3222  m_GBqual->SetVal(value);
3223  }
3224  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsGene())
3225  {
3226  m_EditedFeat->SetData().SetGene().SetLocus(value);
3227  }
3228  else if (m_EditedFeat->GetGeneXref() != NULL)
3229  {
3230  m_EditedFeat->SetGeneXref().SetLocus(value);
3231  return;
3232  }
3233  else
3234  {
3236  }
3237 }
3238 
3240 {
3241  if (m_GBqual)
3242  return m_GBqual->GetVal();
3243  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsGene())
3244  return m_EditedFeat->GetData().GetGene().GetLocus();
3246  return m_EditedFeat->GetGeneXref()->GetLocus();
3247 
3248  return kEmptyStr;
3249 }
3250 
3252 {
3253  if (m_GBqual)
3254  m_erase = true;
3255  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsGene())
3256  m_EditedFeat->SetData().SetGene().ResetLocus();
3257  else if (m_EditedFeat->GetGeneXref() != NULL)
3258  {
3259  bool before = m_EditedFeat->SetGeneXref().IsSuppressed();
3260  m_EditedFeat->SetGeneXref().ResetLocus();
3261  bool after = m_EditedFeat->SetGeneXref().IsSuppressed();
3262  if (!before && after)
3263  RemoveGeneXref();
3264  }
3265 }
3266 
3268 {
3269  IEditingActionFeat *feat_other = dynamic_cast<IEditingActionFeat*>(m_Other);
3270  if (!feat_other)
3271  {
3272  Find(action);
3273  return;
3274  }
3275  m_EditedFeat.Reset();
3276  CSeq_feat_Handle fh = feat_other->GetFeatHandle();
3277  CScope &scope = fh.GetScope();
3278  CRef<CSeq_loc> feat_loc;
3279  if ( fh.GetFeatType() == CSeqFeatData::e_Prot )
3280  {
3281  const CSeq_loc& prot_loc = fh.GetLocation();
3282  CBioseq_Handle prot_bsh = scope.GetBioseqHandle(prot_loc);
3283  if (prot_bsh)
3284  {
3285  const CSeq_feat* cds = sequence::GetCDSForProduct(prot_bsh);
3286  if (cds)
3287  {
3288  feat_loc.Reset(new CSeq_loc);
3289  feat_loc->Assign(cds->GetLocation());
3290  }
3291  }
3292  }
3293  else
3294  {
3295  feat_loc.Reset(new CSeq_loc);
3296  feat_loc->Assign(fh.GetLocation());
3297  }
3298 
3299  if (!feat_loc)
3300  return;
3302 
3303  if (gene_fh)
3304  {
3305  m_Feat = gene_fh;
3308  else
3309  {
3312  }
3313  }
3314  else
3315  {
3317  if (gene_fh)
3318  {
3319  m_Feat = gene_fh;
3322  else
3323  {
3326  }
3327  }
3328  else
3329  {
3330  CRef<CSeq_loc> gene_loc = x_MergeFeatureLocation(*feat_loc, scope);
3332  m_EditedFeat->SetData().SetGene();
3333  m_EditedFeat->SetLocation(*gene_loc);
3336  if (seh.IsSeq() && seh.GetSeq().IsAa() && seh.HasParentEntry())
3337  {
3339  if (b_iter)
3340  seh = b_iter->GetSeq_entry_Handle();
3341  }
3345  for (CSeq_annot_CI annot_ci(new_seh, CSeq_annot_CI::eSearch_entry); annot_ci; ++annot_ci)
3346  {
3347  if ((*annot_ci).IsFtable())
3348  {
3349  ftable = *annot_ci;
3350  break;
3351  }
3352  }
3353  CSeq_entry_EditHandle eh = new_seh.GetEditHandle();
3354  if (!ftable)
3355  {
3356  CRef<CSeq_annot> new_annot(new CSeq_annot());
3357  ftable = eh.AttachAnnot(*new_annot);
3358  }
3359 
3361  m_Feat = aeh.AddFeat(*m_EditedFeat);
3362  m_CreatedFeatures[m_Feat] = seh; // this seq-entry-handle should be in the original scope
3363  }
3364  }
3365  Modify(action);
3366 }
3367 
3369 {
3370  if (!m_TopSeqEntry)
3371  return;
3372  size_t count = 0;
3373  for (CFeat_CI feat_ci(m_TopSeqEntry, m_selector); feat_ci; ++feat_ci)
3374  {
3375  CSeq_feat_Handle fh = feat_ci->GetSeq_feat_Handle();
3376  if (!m_ncRNAclass.empty() && m_ncRNAclass != "any" && fh.GetFeatSubtype() == CSeqFeatData::eSubtype_ncRNA) {
3377  auto& rna_ref = fh.GetData().GetRna();
3378  if (!s_IsSetncRNAClass(rna_ref) || !NStr::EqualCase(s_GetncRNAClass(rna_ref), m_ncRNAclass)) {
3379  continue;
3380  }
3381  }
3382  m_EditedFeat.Reset();
3384  CScope &scope = fh.GetScope();
3386  {
3387  m_Feat = fh;
3390  else
3391  {
3394  }
3395  Modify(action);
3396  if (!IsNOOP(action) && !m_EditedFeat)
3397  {
3400  else
3401  {
3404  m_EditedFeat->SetData().SetGene();
3405  m_EditedFeat->SetLocation(*gene_loc);
3408  m_CreatedFeatures[m_Feat] = seh;
3409  }
3410  if (m_EditedFeat)
3411  Modify(action);
3412  }
3413  }
3414  ++count;
3415  if (count >= m_max_records)
3416  break;
3417  }
3418 }
3419 
3421 {
3422  if (!m_TopSeqEntry)
3423  return;
3424  size_t count = 0;
3425  vector<CRef<CSeq_loc>> already_created;
3426  for (CFeat_CI feat_ci(m_TopSeqEntry, m_selector); feat_ci; ++feat_ci)
3427  {
3428  CSeq_feat_Handle fh = feat_ci->GetSeq_feat_Handle();
3429  if (!m_ncRNAclass.empty() && m_ncRNAclass != "any" && fh.GetFeatSubtype() == CSeqFeatData::eSubtype_ncRNA) {
3430  auto& rna_ref = fh.GetData().GetRna();
3431  if (!s_IsSetncRNAClass(rna_ref) || !NStr::EqualCase(s_GetncRNAClass(rna_ref), m_ncRNAclass)) {
3432  continue;
3433  }
3434  }
3435  m_EditedFeat.Reset();
3437  CScope &scope = fh.GetScope();
3439  {
3440 
3442  {
3444  if (gene_fh)
3445  m_Feat = gene_fh;
3446  }
3447  else
3448  m_Feat = fh;
3449  if (m_Feat)
3450  {
3453  else
3454  {
3457  }
3458  }
3459  else if (!IsNOOP(action))
3460  {
3461  m_Feat = fh;
3464  else
3465  {
3467  auto created = find_if(already_created.begin(), already_created.end(),[gene_loc](CRef<CSeq_loc> loc) {return loc->Equals(*gene_loc);});
3468  if (created == already_created.end())
3469  {
3470  already_created.push_back(gene_loc);
3472  m_EditedFeat->SetData().SetGene();
3473  m_EditedFeat->SetLocation(*gene_loc);
3476  m_CreatedFeatures[m_Feat] = seh;
3477  }
3478  }
3479  }
3480  if (m_EditedFeat)
3481  Modify(action);
3482 
3483  }
3484  ++count;
3485  if (count >= m_max_records)
3486  break;
3487  }
3488 }
3489 
3491 {
3493 }
3494 
3496 {
3498 }
3499 
3500 
3502 {
3503  if (!m_TopSeqEntry)
3504  return;
3505  CScope &scope = m_TopSeqEntry.GetScope();
3506  size_t count = 0;
3507  for (CFeat_CI feat_ci(m_TopSeqEntry, SAnnotSelector(CSeqFeatData::eSubtype_gene)); feat_ci; ++feat_ci)
3508  {
3509  CSeq_feat_Handle fh = feat_ci->GetSeq_feat_Handle();
3510  m_EditedFeat.Reset();
3511  m_Feat.Reset();
3514  {
3515  m_Feat = fh;
3518  else
3519  {
3522  }
3523 
3524 
3525  if (m_EditedFeat)
3526  Modify(action);
3527  }
3528  ++count;
3529  if (count >= m_max_records)
3530  break;
3531  }
3532 
3533  if (IsNOOP(action))
3534  return;
3535 
3536  vector<CSeq_feat_Handle> feat_handles;
3537 
3538  for (CFeat_CI feat_ci(m_TopSeqEntry, SAnnotSelector(CSeqFeatData::eSubtype_mRNA)); feat_ci; ++feat_ci)
3539  {
3540  CSeq_feat_Handle fh = feat_ci->GetSeq_feat_Handle();
3542  if (!gene_fh || !m_constraint->Match(gene_fh))
3543  {
3544  feat_handles.push_back(fh);
3545  }
3546  }
3547 
3548  for (CFeat_CI feat_ci(m_TopSeqEntry, SAnnotSelector(CSeqFeatData::eSubtype_cdregion)); feat_ci; ++feat_ci)
3549  {
3550  CSeq_feat_Handle fh = feat_ci->GetSeq_feat_Handle();
3553  if ((!gene_fh || !m_constraint->Match(gene_fh))
3554  && (!mrna_fh || !m_constraint->Match(mrna_fh)))
3555  {
3556  feat_handles.push_back(fh);
3557  }
3558  }
3559 
3560  vector<CRef<CSeq_loc>> already_created;
3561  for (size_t i = 0; i < feat_handles.size(); i++)
3562  {
3563  CSeq_feat_Handle fh = feat_handles[i];
3564  m_EditedFeat.Reset();
3565  m_Feat.Reset();
3568  {
3569  m_Feat = fh;
3570 
3573  else
3574  {
3576  auto created = find_if(already_created.begin(), already_created.end(),[gene_loc](CRef<CSeq_loc> loc) {return loc->Equals(*gene_loc);});
3577  if (created == already_created.end())
3578  {
3579  already_created.push_back(gene_loc);
3581  m_EditedFeat->SetData().SetGene();
3582  m_EditedFeat->SetLocation(*gene_loc);
3585  m_CreatedFeatures[m_Feat] = seh;
3586  }
3587  }
3588 
3589  if (m_EditedFeat)
3590  Modify(action);
3591  }
3592  }
3593 }
3594 
3596 {
3598 }
3599 
3601  const CSeqFeatData::ESubtype subtype, const string& ncRNA_class)
3602  : CEditingActionFeatDesc(seh, subtype, CSeqFeatData::e_Rna, ncRNA_class)
3603 {
3604  m_Name = "CEditingActionFeatRnaToGeneDesc";
3605 }
3606 
3608 {
3610 }
3611 
3612 
3614 {
3616 }
3617 
3618 
3620 {
3622 }
3623 
3625 {
3627 }
3628 
3629 
3631  const CSeqFeatData::ESubtype subtype, const string& ncRNA_class)
3632  : CEditingActionFeatMaploc(seh, subtype, CSeqFeatData::e_Rna, ncRNA_class)
3633 {
3634  m_Name = "CEditingActionFeatRnaToGeneMaploc";
3635 }
3636 
3638 {
3640 }
3641 
3643 {
3645 }
3646 
3648 {
3650 }
3651 
3653 {
3655 }
3656 
3658  const CSeqFeatData::ESubtype subtype, const string& ncRNA_class)
3659  : CEditingActionFeatLocus_tag(seh, subtype, CSeqFeatData::e_Rna, ncRNA_class)
3660 {
3661  m_Name = "CEditingActionFeatRnaToGeneLocus_tag";
3662 }
3663 
3665 {
3667 }
3668 
3670 {
3672 }
3673 
3675 {
3677 }
3678 
3680 {
3682 }
3683 
3685  const CSeqFeatData::ESubtype subtype, const string& ncRNA_class)
3686  : CEditingActionFeatSynonym(seh, subtype, CSeqFeatData::e_Rna, ncRNA_class)
3687 {
3688  m_Name = "CEditingActionFeatRnaToGeneSynonym";
3689 }
3690 
3692 {
3694 }
3695 
3697 {
3699 }
3700 
3702 {
3704 }
3705 
3707 {
3709 }
3710 
3712  const CSeqFeatData::ESubtype subtype, const string& ncRNA_class)
3713  : CEditingActionFeatComment(seh, subtype, CSeqFeatData::e_Rna, ncRNA_class)
3714 {
3715  m_Name = "CEditingActionFeatRnaToGeneComment";
3716 }
3717 
3719 {
3721 }
3722 
3724 {
3726 }
3727 
3729 {
3731 }
3732 
3734 {
3736 }
3737 
3739  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class)
3740  : IEditingActionFeat(seh, subtype, feat_type, ncRNA_class, "CEditingActionFeatFunction"), m_erase(false), m_function(NULL), m_qual("function")
3741 {
3742 }
3743 
3745 {
3746  bool found = false;
3747  GoToProtFeature();
3748  if (!IsCreateNew(action))
3749  {
3750  m_GBqual.Reset();
3752  {
3753  EDIT_EACH_ACTIVITY_ON_PROTREF(activity_it, m_EditedFeat->SetData().SetProt())
3754  {
3755  found = true;
3756  m_erase = false;
3757  m_function = &*activity_it;
3759  if (m_erase)
3760  ERASE_ACTIVITY_ON_PROTREF(activity_it, m_EditedFeat->SetData().SetProt());
3761  }
3762  }
3763  m_function = NULL;
3764  if (!found && m_EditedFeat->GetProtXref() != NULL)
3765  {
3766  CProt_ref& prot_feat = m_EditedFeat->SetProtXref();
3767  EDIT_EACH_ACTIVITY_ON_PROTREF(activity_it, prot_feat)
3768  {
3769  found = true;
3770  m_erase = false;
3771  m_function = &*activity_it;
3773  if (m_erase)
3774  ERASE_ACTIVITY_ON_PROTREF(activity_it, prot_feat);
3775  }
3776  }
3777  m_function = NULL;
3778  if (!found)
3779  {
3780  if (IsFrom(action) && m_EditedFeat->IsSetQual() && !m_EditedFeat->GetQual().empty() && m_EditedFeat->GetQual().capacity() < 2 * m_EditedFeat->GetQual().size())
3781  {
3782  m_EditedFeat->SetQual().reserve(2 * m_EditedFeat->GetQual().size());
3783  }
3785  {
3786  if ((*gbqual_it)->IsSetQual() && (*gbqual_it)->GetQual() == m_qual)
3787  {
3788  found = true;
3789  m_erase = false;
3790  m_GBqual = *gbqual_it;
3792  if (m_erase)
3794  }
3795  }
3796  if (IsFrom(action))
3797  {
3798  m_EditedFeat->SetQual().shrink_to_fit();
3799  }
3800  }
3801  }
3802  if (!found)
3803  {
3804  m_function = NULL;
3805  m_GBqual.Reset();
3806  m_erase = false;
3808  }
3809  GoToOrigFeature();
3810 }
3811 
3813 {
3814  return m_function != NULL || (m_GBqual && m_GBqual->IsSetVal());
3815 }
3816 
3818 {
3819  if (m_GBqual)
3820  {
3821  m_GBqual->SetVal(value);
3822  }
3823  else if (m_function)
3824  {
3825  *m_function = value;
3826  }
3827  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsProt())
3828  {
3829  m_EditedFeat->SetData().SetProt().SetActivity().push_back(value);
3830  }
3831  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsCdregion()) //(m_EditedFeat->GetProtXref() != NULL)
3832  {
3833  m_EditedFeat->SetProtXref().SetActivity().push_back(value);
3834  }
3835  else
3836  {
3838  }
3839 }
3840 
3842 {
3843  if (m_GBqual)
3844  return m_GBqual->GetVal();
3845  else if (m_function)
3846  return *m_function;
3847  return kEmptyStr;
3848 }
3849 
3851 {
3852  m_erase = true;
3853 }
3854 
3856  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string& ncRNA_class)
3857  : CEditingActionFeatGbQualTwoNames(seh, subtype, feat_type, ncRNA_class, "transcript_id", "orig_transcript_id")
3858 {
3859 }
3860 
3862 {
3864  (m_GBqual && m_GBqual->IsSetVal());
3865 }
3866 
3868 {
3869  if (m_GBqual)
3870  m_GBqual->SetVal(value);
3871  else if (m_EditedFeat->IsSetData() && m_EditedFeat->GetData().IsRna())
3872  {
3873  CRef<CSeq_id> new_id(new CSeq_id);
3874  new_id->SetLocal().SetStr(value);
3875  m_EditedFeat->SetProduct().SetWhole().Assign(*new_id);
3876  }
3877  else
3879 }
3880 
3882 {
3883  if (m_GBqual)
3884  return m_GBqual->GetVal();
3886  {
3887  const CSeq_id* id = m_EditedFeat->GetProduct().GetId();
3888  if (id)
3889  {
3890  string label;
3891  id->GetLabel(&label, CSeq_id::eContent);
3892  return label;
3893  }
3894  }
3895 
3896  return kEmptyStr;
3897 }
3898 
3900 {
3901  if (m_GBqual)
3902  m_erase = true;
3905 }
3906 
3908  const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type,
3909  const string& ncRNA_class)
3910 {
3911  NStr::ToLower(field);
3912  if (field == "comment" || field == "note")
3913  return new CEditingActionFeatComment(seh, subtype, feat_type, ncRNA_class);
3914  if (field == "exception")
3915  return new CEditingActionFeatException(seh, subtype, feat_type, ncRNA_class);
3916  if (field == "locus" || field == "gene locus")
3917  return new CEditingActionFeatGeneLocusPlain(seh, subtype, feat_type, ncRNA_class);
3918  if (field == "rpt_unit_seq")
3919  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "rpt_unit_seq");
3920  if (field == "inference")
3921  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "inference");
3922  if (field == "bound_moiety")
3923  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "bound_moiety");
3924  if (field == "chromosome")
3925  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "chromosome");
3926  if (field == "compare")
3927  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "compare");
3928  if (field == "cons_slice")
3929  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "cons_slice");
3930  if (field == "direction")
3931  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "direction");
3932  if (field == "environmental_sample")
3933  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "environmental_sample");
3934  if (field == "experiment")
3935  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "experiment");
3936  if (field == "focus")
3937  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "focus");
3938  if (field == "frequency")
3939  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "frequency");
3940  if (field == "function")
3941  return new CEditingActionFeatFunction(seh, subtype, feat_type, ncRNA_class);
3942  if (field == "label")
3943  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "label");
3944  if (field == "map")
3945  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "map");
3946  if (field == "mod_base")
3947  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "mod_base");
3948  if (field == "mol_type")
3949  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "mol_type");
3950  if (field == "number")
3951  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "number");
3952  if (field == "old_locus_tag")
3953  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "old_locus_tag");
3954  if (field == "operon")
3955  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "operon");
3956  if (field == "organism")
3957  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "organism");
3958  if (field == "pcr_conditions")
3959  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "pcr_conditions");
3960  if (field == "phenotype")
3961  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "phenotype");
3962  if (field == "plasmid")
3963  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "plasmid");
3964  if (field == "protein_id")
3965  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "protein_id");
3966  if (field == "rearranged")
3967  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "rearranged");
3968  if (field == "regulatory_class")
3969  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "regulatory_class");
3970  if (field == "replace")
3971  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "replace");
3972  if (field == "rpt_family")
3973  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "rpt_family");
3974  if (field == "rpt_type")
3975  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "rpt_type");
3976  if (field == "rpt_unit")
3977  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "rpt_unit");
3978  if (field == "rpt_unit_range")
3979  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "rpt_unit_range");
3980  if (field == "segment")
3981  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "segment");
3982  if (field == "sequenced_mol")
3983  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "sequenced_mol");
3984  if (field == "standard_name")
3985  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "standard_name");
3986  if (field == "tag_peptide")
3987  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "tag_peptide");
3988  if (field == "transcript_id")
3989  return new CEditingActionFeatTranscriptId(seh, subtype, feat_type, ncRNA_class);
3990  if (field == "transgenic")
3991  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "transgenic");
3992  if (field == "transl_except")
3993  return new CEditingActionFeatTranslExcept(seh, subtype, feat_type, ncRNA_class);
3994  if (field == "usedin")
3995  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "usedin");
3996  if (field == "mobile_element")
3997  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "mobile_element");
3998  if (field == "mobile_element_type")
3999  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "mobile_element_type");
4000  if (field == "mobile_element_type_type")
4001  return new CEditingActionFeatDualVal1(seh, subtype, feat_type, ncRNA_class, "mobile_element_type");
4002  if (field == "mobile_element_type_name")
4003  return new CEditingActionFeatDualVal2(seh, subtype, feat_type, ncRNA_class, "mobile_element_type");
4004  if (field == "satellite")
4005  return new CEditingActionFeatGbQual(seh, subtype, feat_type, ncRNA_class, "satellite");
4006  if (field == "satellite_type")
4007  return new CEditingActionFeatDualVal1(seh, subtype, feat_type, ncRNA_class, "satellite");
4008  if (field == "satellite_name")
4009  return new CEditingActionFeatDualVal2(seh, subtype, feat_type, ncRNA_class, "satellite");
4010  if (field == "db_xref")
4011  return new CEditingActionFeatDbxref(seh, subtype, feat_type, ncRNA_class);
4012  if (field == "evidence")
4013  return new CEditingActionFeatEvidence(seh, subtype, feat_type, ncRNA_class);
4014  if (field == "pseudogene" || field == "pseudo")
4015  return new CEditingActionFeatPseudo(seh, subtype, feat_type, ncRNA_class);
4016  if (field == "codons_recognized" || field == "codons recognized")
4017  return new CEditingActionFeatCodonsRecognized(seh, subtype, feat_type, ncRNA_class);
4018  if (field == "anticodon")
4019  return new CEditingActionFeatAnticodon(seh, subtype, feat_type, ncRNA_class);
4020  if (field == "tag_peptide" || field == "tag-peptide")
4021  return new CEditingActionFeatRnaQual(seh, subtype, feat_type, ncRNA_class, "tag_peptide");
4022  if (field == "region")
4023  return new CEditingActionFeatRegion(seh, subtype, feat_type, ncRNA_class);
4024  if (field == "codon_start")
4025  return new CEditingActionFeatCodonStart(seh, subtype, feat_type, ncRNA_class);
4026  if (field == "transl_table")
4027  return new CEditingActionFeatTranslTable(seh, subtype, feat_type, ncRNA_class);
4028  if (field == "product name" || field == "product" || field == "name")
4029  return new CEditingActionFeatProduct(seh, subtype, feat_type, ncRNA_class);
4030  if (field == "desc" || field == "description")
4031  return new CEditingActionFeatDesc(seh, subtype, feat_type, ncRNA_class);
4032  if (field == "ncrna class" || field == "ncrna_class")
4033  return new CEditingActionFeatNcRnaClass(seh, subtype, feat_type, ncRNA_class);
4034  if (field == "locus_tag")
4035  return new CEditingActionFeatLocus_tag(seh, subtype, feat_type, ncRNA_class);
4036  if (field == "maploc")
4037  return new CEditingActionFeatMaploc(seh, subtype, feat_type, ncRNA_class);
4038  if (field == "synonym" || field == "gene_synonym")
4039  return new CEditingActionFeatSynonym(seh, subtype, feat_type, ncRNA_class);
4040  if (field == "allele")
4041  return new CEditingActionFeatAllele(seh, subtype, feat_type, ncRNA_class);
4042  if (field == "activity")
4043  return new CEditingActionFeatActivity(seh, subtype, feat_type, ncRNA_class);
4044  if (field == "partial")
4045  return new CEditingActionFeatPartial(seh, subtype, feat_type, ncRNA_class);
4046  if (field == "ec_number")
4047  return new CEditingActionFeatEcNumber(seh, subtype, feat_type, ncRNA_class);
4048  if (field == "translation")
4049  return new CEditingActionFeatTranslation(seh, subtype, feat_type, ncRNA_class);
4050  return NULL;
4051 }
4052 
4054  const CSeqFeatData::ESubtype subtype, const string& ncRNA_class)
4055 {
4056  NStr::ToLower(field);
4057  if (field == "gene locus")
4058  return new CEditingActionFeatGeneLocusRna(seh, subtype, CSeqFeatData::e_Rna, ncRNA_class);
4059  if (field == "gene description")
4060  return new CEditingActionFeatRnaToGeneDesc(seh, subtype, ncRNA_class);
4061  if (field == "gene maploc")
4062  return new CEditingActionFeatRnaToGeneMaploc(seh, subtype, ncRNA_class);
4063  if (field == "gene locus tag")
4064  return new CEditingActionFeatRnaToGeneLocus_tag(seh, subtype, ncRNA_class);
4065  if (field == "gene synonym")
4066  return new CEditingActionFeatRnaToGeneSynonym(seh, subtype, ncRNA_class);
4067  if (field == "gene comment")
4068  return new CEditingActionFeatRnaToGeneComment(seh, subtype, ncRNA_class);
4069 
4070  return CreateActionFeat(seh, field, subtype, CSeqFeatData::e_Rna, ncRNA_class);
4071 
4072 }
4073 
4075  const CSeqFeatData::ESubtype subtype, const string& ncRNA_class)
4076 {
4077  NStr::ToLower(field);
4078  if (field == "gene locus")
4079  return new CEditingActionFeatGeneLocusCdsGeneProt(seh, subtype, CSeqFeatData::GetTypeFromSubtype(subtype), ncRNA_class);
4080  if (field == "gene description" || field == "protein description" || field == "mat_peptide description")
4081  return new CEditingActionFeatDesc(seh, subtype, CSeqFeatData::GetTypeFromSubtype(subtype), ncRNA_class);
4082  if (field == "gene maploc")
4083  return new CEditingActionFeatMaploc(seh, subtype, CSeqFeatData::GetTypeFromSubtype(subtype), ncRNA_class);
4084  if (field == "gene locus tag")
4085  return new CEditingActionFeatLocus_tag(seh, subtype, CSeqFeatData::GetTypeFromSubtype(subtype), ncRNA_class);
4086  if (field == "gene synonym")
4087  return new CEditingActionFeatSynonym(seh, subtype, CSeqFeatData::GetTypeFromSubtype(subtype), ncRNA_class);
4088  if (field == "gene comment" || field == "cds comment" || field == "mrna comment" || field == "mat_peptide comment" || field == "protein comment")
4089  return new CEditingActionFeatComment(seh, subtype, CSeqFeatData::GetTypeFromSubtype(subtype), ncRNA_class);
4090  if (field == "gene old_locus_tag")
4091  return new CEditingActionFeatGbQual(seh, subtype, CSeqFeatData::GetTypeFromSubtype(subtype), ncRNA_class, "old_locus_tag");
4092  if (field == "gene allele")
4093  return new CEditingActionFeatAllele(seh, subtype, CSeqFeatData::GetTypeFromSubtype(subtype), ncRNA_class);
4094  if (field == "gene inference" || field == "cds inference")
4095  return new CEditingActionFeatGbQual(seh, subtype, CSeqFeatData::GetTypeFromSubtype(subtype), ncRNA_class, "inference");
4096  if (field == "protein name" || field == "mrna product" || field == "mat_peptide name")
4097  return new CEditingActionFeatProduct(seh, subtype, CSeqFeatData::GetTypeFromSubtype(subtype), ncRNA_class);
4098  if (field == "protein ec number" || field == "mat_peptide ec number")
4099  return new CEditingActionFeatEcNumber(seh, subtype, CSeqFeatData::GetTypeFromSubtype(subtype), ncRNA_class);
4100  if (field == "protein activity" || field == "mat_peptide activity")
4101  return new CEditingActionFeatActivity(seh, subtype, CSeqFeatData::GetTypeFromSubtype(subtype), ncRNA_class);
4102  if (field == "codon-start")
4103  return new CEditingActionFeatCodonStart(seh, subtype, CSeqFeatData::GetTypeFromSubtype(subtype), ncRNA_class);
4104 
4105  return NULL;
4106 }
4107 
4109 
static CRef< CScope > m_Scope
bool IsReverse(ENa_strand s)
Definition: Na_strand.hpp:75
@ eExtreme_Positional
numerical value
Definition: Na_strand.hpp:63
@ eExtreme_Biological
5' and 3'
Definition: Na_strand.hpp:62
bool operator!=(const _Ht_iterator< _Val, _Nonconst_traits< _Val >, _Key, _HF, _ExK, _EqK, _All > &__x, const _Ht_iterator< _Val, _Const_traits< _Val >, _Key, _HF, _ExK, _EqK, _All > &__y)
Definition: _hashtable.h:173
CBioseq_CI –.
Definition: bioseq_ci.hpp:69
CBioseq_Handle –.
Definition: Dbtag.hpp:53
virtual ~CDefaultSynonymMapper(void)
CDefaultSynonymMapper(CScope *scope)
map< CSeq_id_Handle, CSeq_id_Handle > TSynonymMap
CRef< CSeq_id_Mapper > m_IdMapper
virtual CSeq_id_Handle GetBestSynonym(const CSeq_id &id)
virtual bool Match(const string &value)
CEditingActionFeatActivity(CSeq_entry_Handle seh, const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string &ncRNA_class)
virtual void SetValue(const string &value)
virtual void Modify(EActionType action)
virtual void SetValue(const string &value)
CEditingActionFeatAllele(CSeq_entry_Handle seh, const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string &ncRNA_class)
virtual void SetValue(const string &value)
CEditingActionFeatAnticodon(CSeq_entry_Handle seh, const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string &ncRNA_class)
string GetIntervalString(const CSeq_interval &seq_int)
virtual void SetValue(const string &value)
CEditingActionFeatCodonStart(CSeq_entry_Handle seh, const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string &ncRNA_class)
virtual void SetValue(const string &value)
CEditingActionFeatCodonsRecognized(CSeq_entry_Handle seh, const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string &ncRNA_class)
CEditingActionFeatComment(CSeq_entry_Handle seh, const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string &ncRNA_class)
virtual void SetValue(const string &value)
virtual void Modify(EActionType action)
CEditingActionFeatDbxref(CSeq_entry_Handle seh, const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string &ncRNA_class)
virtual void SetValue(const string &value)
virtual void SetValue(const string &value)
CEditingActionFeatDesc(CSeq_entry_Handle seh, const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string &ncRNA_class)
virtual void SetValue(const string &value)
CEditingActionFeatDualVal1(CSeq_entry_Handle seh, const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string &ncRNA_class, const string &qual)
CEditingActionFeatDualVal2(CSeq_entry_Handle seh, const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string &ncRNA_class, const string &qual)
virtual void SetValue(const string &value)
virtual void Modify(EActionType action)
virtual void FindRelated(EActionType action)
virtual void Find(EActionType action)
CEditingActionFeatEcNumber(CSeq_entry_Handle seh, const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string &ncRNA_class)
virtual void SetValue(const string &value)
virtual void SetValue(const string &value)
CEditingActionFeatEvidence(CSeq_entry_Handle seh, const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string &ncRNA_class)
CEditingActionFeatException(CSeq_entry_Handle seh, const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string &ncRNA_class)
virtual void SetValue(const string &value)
virtual void SetValue(const string &value)
CEditingActionFeatFunction(CSeq_entry_Handle seh, const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string &ncRNA_class)
virtual void Modify(EActionType action)
virtual void Modify(EActionType action)
CEditingActionFeatGbQualTwoNames(CSeq_entry_Handle seh, const CSeqFeatData::ESubtype subtype, const CSeqFeatData::E_Choice feat_type, const string &ncRNA_class, const string &qual1, const string &qual2)
virtual void SetValue(const string &value)
virtual void Modify(EActionType action)