1 /* $Id: apply_object.cpp 632623 2021-06-03 17:38:11Z ivanov $
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 * Author: Colleen Bollin, NCBI
27 *
28 * File Description:
29 * CApplyObject class
30 */
31 #include <ncbi_pch.hpp>
32 #include <corelib/ncbistd.hpp>
33 #include <corelib/ncbiobj.hpp>
34 #include <objects/seqfeat/Seq_feat.hpp>
35 #include <objects/seq/Seq_descr.hpp>
36 #include <objects/general/User_object.hpp>
37 #include <objects/general/Object_id.hpp>
38 #include <objmgr/seq_entry_ci.hpp>
39 #include <objmgr/seq_feat_handle.hpp>
40 #include <objmgr/feat_ci.hpp>
41 #include <objmgr/seq_annot_ci.hpp>
42 #include <objmgr/seq_annot_handle.hpp>
43 #include <objtools/edit/apply_object.hpp>
44
45 BEGIN_NCBI_SCOPE
BEGIN_SCOPE(objects)46 BEGIN_SCOPE(objects)
47 BEGIN_SCOPE(edit)
48
49 CApplyObject::CApplyObject(CBioseq_Handle bsh, const CSeqdesc& desc) : m_Delete(false)
50 {
51 m_SEH = bsh.GetParentEntry();
52 if (!desc.IsMolinfo() && !desc.IsTitle()) {
53 CBioseq_set_Handle bssh = bsh.GetParentBioseq_set();
54 if (bssh && bssh.IsSetClass() && bssh.GetClass() == objects::CBioseq_set::eClass_nuc_prot) {
55 m_SEH = bssh.GetParentEntry();
56 }
57 }
58
59 m_Original.Reset(&desc);
60 CRef<CSeqdesc> new_desc(new CSeqdesc());
61 new_desc->Assign(desc);
62 m_Editable = new_desc.GetPointer();
63 }
64
65
CApplyObject(CBioseq_Handle bsh,CSeqdesc::E_Choice subtype)66 CApplyObject::CApplyObject(CBioseq_Handle bsh, CSeqdesc::E_Choice subtype): m_Delete(false)
67 {
68 m_SEH = bsh.GetParentEntry();
69 if (subtype != CSeqdesc::e_Molinfo && subtype != CSeqdesc::e_Title) {
70 CBioseq_set_Handle bssh = bsh.GetParentBioseq_set();
71 if (bssh && bssh.IsSetClass() && bssh.GetClass() == objects::CBioseq_set::eClass_nuc_prot) {
72 m_SEH = bssh.GetParentEntry();
73 }
74 }
75
76 m_Original.Reset(NULL);
77 CRef<CSeqdesc> new_desc(new CSeqdesc());
78 new_desc->Select(subtype);
79 m_Editable = new_desc.GetPointer();
80 }
81
82
CApplyObject(CBioseq_Handle bsh,const string & user_label)83 CApplyObject::CApplyObject(CBioseq_Handle bsh, const string& user_label) : m_Delete(false)
84 {
85 m_SEH = bsh.GetParentEntry();
86 CBioseq_set_Handle bssh = bsh.GetParentBioseq_set();
87 if (bssh && bssh.IsSetClass() && bssh.GetClass() == objects::CBioseq_set::eClass_nuc_prot) {
88 m_SEH = bssh.GetParentEntry();
89 }
90
91 m_Original.Reset(NULL);
92 CRef<CSeqdesc> new_desc(new CSeqdesc());
93 new_desc->SetUser().SetType().SetStr(user_label);
94 m_Editable = new_desc.GetPointer();
95 }
96
97
CApplyObject(CBioseq_Handle bsh,const CSeq_feat & feat)98 CApplyObject::CApplyObject(CBioseq_Handle bsh, const CSeq_feat& feat) : m_Delete(false)
99 {
100 m_SEH = bsh.GetParentEntry();
101 m_Original.Reset(&feat);
102 CRef<CSeq_feat> new_feat(new CSeq_feat());
103 new_feat->Assign(feat);
104 m_Editable = new_feat.GetPointer();
105 }
106
107
CApplyObject(CBioseq_Handle bsh)108 CApplyObject::CApplyObject(CBioseq_Handle bsh) : m_Delete(false)
109 {
110 m_SEH = bsh.GetParentEntry();
111 m_Original.Reset(bsh.GetCompleteBioseq().GetPointer());
112 CRef<CBioseq> new_seq(new CBioseq());
113 new_seq->Assign(*(bsh.GetCompleteBioseq()));
114 m_Editable = new_seq.GetPointer();
115 }
116
117
ApplyChange()118 void CApplyObject::ApplyChange()
119 {
120 if (m_Delete) {
121 // deletion
122 if (m_Original) {
123 const CSeqdesc* orig_desc = dynamic_cast<const CSeqdesc * >(m_Original.GetPointer());
124 const CSeq_feat* orig_feat = dynamic_cast<const CSeq_feat * >(m_Original.GetPointer());
125 const CSeq_inst* orig_inst = dynamic_cast<const CSeq_inst * >(m_Original.GetPointer());
126 if (orig_desc) {
127 CSeq_entry_Handle seh = GetSeqEntryForSeqdesc (CRef<CScope>(&(m_SEH.GetScope())), *orig_desc);
128 if (!seh) {
129 seh = m_SEH;
130 }
131 CSeq_entry_EditHandle eseh = seh.GetEditHandle();
132 eseh.RemoveSeqdesc(*orig_desc);
133 } else if (orig_feat) {
134 CSeq_feat_Handle oh = m_SEH.GetScope().GetSeq_featHandle(*orig_feat);
135 CSeq_feat_EditHandle(oh).Remove();
136 } else if (orig_inst) {
137 // not going to handle this for now
138 }
139 }
140 return;
141 }
142
143 CSeqdesc* desc = dynamic_cast<CSeqdesc * >(m_Editable.GetPointer());
144 CSeq_feat* feat = dynamic_cast<CSeq_feat * >(m_Editable.GetPointer());
145 CSeq_inst* inst = dynamic_cast<CSeq_inst * >(m_Editable.GetPointer());
146
147 if (desc) {
148 if (m_Original) {
149 const CSeqdesc* orig_desc = dynamic_cast<const CSeqdesc* >(m_Original.GetPointer());
150 CSeqdesc* change_desc = const_cast<CSeqdesc* >(orig_desc);
151 change_desc->Assign(*desc);
152 } else {
153 CSeq_entry_EditHandle eseh = m_SEH.GetEditHandle();
154 eseh.AddSeqdesc(const_cast<CSeqdesc&>(*desc));
155 }
156 } else if (feat) {
157 if (m_Original) {
158 const CSeq_feat* old_feat = dynamic_cast<const CSeq_feat * >(m_Original.GetPointer());
159 CSeq_feat_Handle oh = m_SEH.GetScope().GetSeq_featHandle(*old_feat);
160 // This is necessary, to make sure that we are in "editing mode"
161 const CSeq_annot_Handle& annot_handle = oh.GetAnnot();
162 CSeq_entry_EditHandle eh = annot_handle.GetParentEntry().GetEditHandle();
163
164 // Now actually edit the feature
165 CSeq_feat_EditHandle feh(oh);
166 CSeq_entry_Handle parent_entry = feh.GetAnnot().GetParentEntry();
167
168 feh.Replace(*feat);
169 if (feh.IsSetData() && feh.GetData().IsCdregion() && feh.IsSetProduct()) {
170 if (parent_entry.IsSet()
171 && parent_entry.GetSet().IsSetClass()
172 && parent_entry.GetSet().GetClass() == CBioseq_set::eClass_nuc_prot) {
173 // already on nuc-prot set, leave it alone
174 } else {
175 CBioseq_set_Handle nuc_parent = parent_entry.GetParentBioseq_set();
176 if (nuc_parent && nuc_parent.IsSetClass() && nuc_parent.GetClass() == CBioseq_set::eClass_nuc_prot) {
177 CSeq_annot_Handle ftable;
178 CSeq_entry_Handle parent_seh = nuc_parent.GetParentEntry();
179 CSeq_annot_CI annot_ci(parent_seh, CSeq_annot_CI::eSearch_entry);
180 for (; annot_ci; ++annot_ci) {
181 if ((*annot_ci).IsFtable()) {
182 ftable = *annot_ci;
183 break;
184 }
185 }
186
187 if (!ftable) {
188 CRef<CSeq_annot> new_annot(new CSeq_annot());
189 new_annot->SetData().SetFtable();
190 CSeq_entry_EditHandle eh = parent_seh.GetEditHandle();
191 ftable = eh.AttachAnnot(*new_annot);
192 }
193
194 CSeq_annot_EditHandle new_annot = ftable.GetEditHandle();
195 new_annot.TakeFeat(feh);
196 }
197 }
198 }
199 } else {
200 if (feat->IsSetData() && feat->GetData().IsCdregion() && feat->IsSetProduct()) {
201 CBioseq_Handle bsh = m_SEH.GetScope().GetBioseqHandle(feat->GetProduct());
202 if (bsh) {
203 CBioseq_set_Handle nuc_parent = bsh.GetParentBioseq_set();
204 if (nuc_parent && nuc_parent.IsSetClass() && nuc_parent.GetClass() == CBioseq_set::eClass_nuc_prot) {
205 m_SEH = nuc_parent.GetParentEntry();
206 }
207 }
208 }
209 CSeq_annot_Handle ftable;
210 CSeq_annot_CI annot_ci(m_SEH, CSeq_annot_CI::eSearch_entry);
211 for (; annot_ci; ++annot_ci) {
212 if ((*annot_ci).IsFtable()) {
213 ftable = *annot_ci;
214 break;
215 }
216 }
217
218 CSeq_entry_EditHandle eh = m_SEH.GetEditHandle();
219
220 if (!ftable) {
221 CRef<CSeq_annot> new_annot(new CSeq_annot());
222 ftable = eh.AttachAnnot(*new_annot);
223 }
224
225 CSeq_annot_EditHandle aeh(ftable);
226 aeh.AddFeat(*feat);
227
228 }
229
230 } else if (inst) {
231 CBioseq_EditHandle beeh = m_SEH.GetSeq().GetEditHandle();
232 beeh.SetInst(*inst);
233 }
234 }
235
236
GetSeqEntryForSeqdesc(CRef<CScope> scope,const CSeqdesc & seq_desc)237 CSeq_entry_Handle GetSeqEntryForSeqdesc (CRef<CScope> scope, const CSeqdesc& seq_desc)
238 {
239 CSeq_entry_Handle seh;
240
241 if (!scope) {
242 return seh;
243 }
244
245 CScope::TTSE_Handles tses;
246 scope->GetAllTSEs(tses, CScope::eAllTSEs);
247 ITERATE (CScope::TTSE_Handles, handle, tses) {
248 for (CSeq_entry_CI entry_ci(*handle, CSeq_entry_CI::fRecursive | CSeq_entry_CI::fIncludeGivenEntry); entry_ci; ++entry_ci) {
249 if (entry_ci->IsSetDescr()) {
250 ITERATE (CBioseq::TDescr::Tdata, dit, entry_ci->GetDescr().Get()) {
251 if (dit->GetPointer() == &seq_desc) {
252 return *entry_ci;
253 }
254 }
255 }
256 }
257 }
258 return seh;
259 }
260
261
262
263
264 END_SCOPE(edit)
265 END_SCOPE(objects)
266 END_NCBI_SCOPE
267
268