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

Go to the SVN repository for this file.

1 /* $Id: bioseq_set_info.cpp 95911 2022-01-14 15:54:47Z vasilche $
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: Eugene Vasilchenko
27 *
28 * File Description:
29 * CSeq_entry_Info info -- entry for data source information about Seq-entry
30 *
31 */
32 
33 
34 #include <ncbi_pch.hpp>
36 #include <objmgr/impl/tse_info.hpp>
41 
46 #include <objects/seq/Bioseq.hpp>
49 #include <objects/seq/Seqdesc.hpp>
50 
51 #include <algorithm>
52 
55 
56 
58  : m_Bioseq_set_Id(-1)
59 {
60 }
61 
62 
64  : m_Bioseq_set_Id(-1)
65 {
66  x_SetObject(seqset);
67 }
68 
69 
71  TObjectCopyMap* copy_map)
72  : TParent(info, copy_map),
73  m_BioseqChunks(info.m_BioseqChunks),
74  m_Bioseq_set_Id(-1)
75 {
76  if ( !copy_map ) {
77  info.x_UpdateComplete();
78  m_DescrChunks.clear();
79  m_AnnotChunks.clear();
80  m_BioseqChunks.clear();
81  }
82  x_SetObject(info, copy_map);
83 }
84 
85 
87 {
88 }
89 
90 
92 {
94  return m_Object;
95 }
96 
97 
99 {
100  x_UpdateCore();
101  return m_Object;
102 }
103 
104 
106 {
108  x_DSMapObject(m_Object, ds);
109  // members
111  (*it)->x_DSAttach(ds);
112  }
113 }
114 
115 
117 {
118  // members
120  (*it)->x_DSDetach(ds);
121  }
124 }
125 
126 
128 {
129  ds.x_Map(obj, this);
130 }
131 
132 
134 {
135  ds.x_Unmap(obj, this);
136 }
137 
138 
140 {
143  if ( IsSetId() ) {
145  if ( m_Bioseq_set_Id >= 0 ) {
147  }
148  }
150  // members
152  (*it)->x_TSEAttach(tse);
153  }
154 }
155 
156 
158 {
159  // members
161  (*it)->x_TSEDetach(tse);
162  }
163  if ( m_Bioseq_set_Id >= 0 ) {
165  m_Bioseq_set_Id = -1;
166  }
168 }
169 
170 
172 {
173  TParent::x_ParentAttach(parent);
174  CSeq_entry& entry = parent.x_GetObject();
175  entry.ParentizeOneLevel();
176  _ASSERT(entry.IsSet() && &entry.GetSet() == m_Object);
178  if ( (*it)->x_GetObject().GetParentEntry() != &entry ) {
179  entry.ParentizeOneLevel();
180  break;
181  }
182  }
183 #ifdef _DEBUG
184  TSeq_set::const_iterator it2 = m_Seq_set.begin();
186  entry.SetSet().SetSeq_set() ) {
187  _ASSERT(it2 != m_Seq_set.end());
188  _ASSERT(&(*it2)->x_GetObject() == *it);
189  _ASSERT((*it)->GetParentEntry() == &entry);
190  ++it2;
191  }
192  _ASSERT(it2 == m_Seq_set.end());
193 #endif
194 }
195 
196 
198 {
200  (*it)->x_GetObject().ResetParentEntry();
201  }
202  TParent::x_ParentDetach(parent);
203 }
204 
205 
207 {
208  m_BioseqChunks.push_back(id);
210 }
211 
212 
214 {
215  return m_BioseqChunks;
216 }
217 
218 
220 {
223  }
225  if ( !m_Seq_set.empty() ) {
226  const CBioseq_set::TSeq_set& seq_set = m_Object->GetSeq_set();
227  _ASSERT(seq_set.size() == m_Seq_set.size());
228  CBioseq_set::TSeq_set::const_iterator it2 = seq_set.begin();
230  if ( flags & fNeedUpdate_core ) {
231  (*it)->x_UpdateCore();
232  }
233  if ( flags & fNeedUpdate_children ) {
234  (*it)->x_Update((flags & fNeedUpdate_children) |
235  (flags >> kNeedUpdate_bits));
236  }
237  _ASSERT(it2->GetPointer() == &(*it)->x_GetObject());
238  ++it2;
239  }
240  }
241  }
243 }
244 
245 
247 {
248  _ASSERT(!m_Object);
249  m_Object.Reset(&obj);
250  if ( HasDataSource() ) {
252  }
253  if ( obj.IsSetSeq_set() ) {
256  m_Seq_set.push_back(info);
258  }
259  }
260  if ( obj.IsSetAnnot() ) {
261  x_SetAnnot();
262  }
263 }
264 
265 
267  TObjectCopyMap* copy_map)
268 {
269  _ASSERT(!m_Object);
270  m_Object = sx_ShallowCopy(info.x_GetObject());
271  if ( HasDataSource() ) {
273  }
274  if ( info.IsSetSeq_set() ) {
275  _ASSERT(m_Object->GetSeq_set().size() == info.m_Seq_set.size());
276  m_Object->SetSeq_set().clear();
277  ITERATE ( TSeq_set, it, info.m_Seq_set ) {
278  AddEntry(Ref(new CSeq_entry_Info(**it, copy_map)));
279  }
280  }
281  if ( info.IsSetAnnot() ) {
282  x_SetAnnot(info, copy_map);
283  }
284 }
285 
286 
288 {
289  CRef<TObject> obj(new TObject);
290  if ( src.IsSetId() ) {
291  obj->SetId(const_cast<TId&>(src.GetId()));
292  }
293  if ( src.IsSetColl() ) {
294  obj->SetColl(const_cast<TColl&>(src.GetColl()));
295  }
296  if ( src.IsSetLevel() ) {
297  obj->SetLevel(src.GetLevel());
298  }
299  if ( src.IsSetClass() ) {
300  obj->SetClass(src.GetClass());
301  }
302  if ( src.IsSetRelease() ) {
303  obj->SetRelease(src.GetRelease());
304  }
305  if ( src.IsSetDate() ) {
306  obj->SetDate(const_cast<TDate&>(src.GetDate()));
307  }
308  if ( src.IsSetDescr() ) {
309  obj->SetDescr().Set() = src.GetDescr().Get();
310  }
311  if ( src.IsSetSeq_set() ) {
312  obj->SetSeq_set() = src.GetSeq_set();
313  }
314  if ( src.IsSetAnnot() ) {
315  obj->SetAnnot() = src.GetAnnot();
316  }
317  return obj;
318 }
319 
320 
322 {
323  int ret = -1;
324  if ( object_id.Which() == object_id.e_Id ) {
325  ret = object_id.GetId();
326  }
327  return ret;
328 }
329 
330 
332 {
333  return m_Object->IsSetDescr();
334 }
335 
336 
338 {
339  return m_Object->CanGetDescr();
340 }
341 
342 
344 {
345  return m_Object->GetDescr();
346 }
347 
348 
350 {
351  return m_Object->SetDescr();
352 }
353 
354 
356 {
357  m_Object->SetDescr(v);
358 }
359 
360 
362 {
363  m_Object->ResetDescr();
364 }
365 
366 
368 {
369  return m_Object->SetAnnot();
370 }
371 
372 
374 {
375  m_Object->ResetAnnot();
376 }
377 
378 
380  int index,
381  bool set_uniqid)
382 {
384  AddEntry(info, index, set_uniqid);
385  return info;
386 }
387 
388 
390  bool set_uniqid)
391 {
392  _ASSERT(!info->HasParent_Info());
393  CBioseq_set::TSeq_set& obj_seq_set = m_Object->SetSeq_set();
394 
395  CRef<CSeq_entry> obj(&info->x_GetObject());
396 
397  //_ASSERT(obj_seq_set.size() == m_Seq_set.size()); quadratic performance
398  if ( size_t(index) >= m_Seq_set.size() ) {
399  obj_seq_set.push_back(obj);
400  m_Seq_set.push_back(info);
401  }
402  else {
403  CBioseq_set::TSeq_set::iterator obj_it = obj_seq_set.begin();
404  for ( int i = 0; i < index; ++i ) {
405  ++obj_it;
406  }
407  obj_seq_set.insert(obj_it, obj);
408  m_Seq_set.insert(m_Seq_set.begin()+index, info);
409  }
411 
412  if (set_uniqid)
413  info->SetBioObjectId(GetTSE_Info().x_RegisterBioObject(*info));
414 }
415 
416 
418 {
419  if ( &info->GetParentBioseq_set_Info() != this ) {
420  NCBI_THROW(CObjMgrException, eAddDataError,
421  "CBioseq_set_Info::x_RemoveEntry: "
422  "not a parent");
423  }
424 
425  CRef<CSeq_entry> obj(const_cast<CSeq_entry*>(&info->x_GetObject()));
426  CBioseq_set::TSeq_set& obj_seq_set = m_Object->SetSeq_set();
427  TSeq_set::iterator info_it =
428  find(m_Seq_set.begin(), m_Seq_set.end(), info);
429  CBioseq_set::TSeq_set::iterator obj_it =
430  find(obj_seq_set.begin(), obj_seq_set.end(), obj);
431 
432  _ASSERT(info_it != m_Seq_set.end());
433  _ASSERT(obj_it != obj_seq_set.end());
434 
436 
437  m_Seq_set.erase(info_it);
438  obj_seq_set.erase(obj_it);
439 }
440 
441 
443 {
444  CRef<CSeq_entry_Info> entry(const_cast<CSeq_entry_Info*>(&info));
445  int index = 0;
446  ITERATE(TSeq_set, it, m_Seq_set) {
447  if (*it == entry)
448  return index;
449  index++;
450  }
451  return -1;
452 }
453 
454 
456 {
457  if ( m_Seq_set.empty() ) {
458  return null;
459  }
460  return m_Seq_set.front();
461 }
462 
463 
465 {
466  CBioseq_set::TSeq_set& obj_seq_set = m_Object->SetSeq_set();
467  CBioseq_set::TSeq_set::iterator insert_iter = obj_seq_set.end();
468  size_t seq_index = m_Seq_set.size();
470  while ( chunk_iter != m_ChunkSeqSets.begin() ) {
471  --chunk_iter;
472  if ( chunk_iter->first > chunk_id ) {
473  seq_index -= chunk_iter->second.count;
474  insert_iter = chunk_iter->second.first_iter;
475  // verify consistency between obj_seq_set (in CBioseq_set) and m_Seq_set (in CBioseq_set_Info)
476  _ASSERT(seq_index < m_Seq_set.size());
477  _ASSERT(m_Seq_set[seq_index]->GetSeq_entryCore() == *chunk_iter->second.first_iter);
478  continue;
479  }
480  // this chunk is before new one
481  ++chunk_iter;
482  break;
483  }
484  size_t insert_count = bioseqs.size();
485  SChunkSeqSet& seq_set = m_ChunkSeqSets[chunk_id];
486  m_Seq_set.insert(m_Seq_set.begin()+seq_index, insert_count, TSeq_set::value_type());
487  for ( auto& i : bioseqs ) {
488  CRef<CSeq_entry> entry(new CSeq_entry);
489  entry->SetSeq(i.GetNCObject());
491  CBioseq_set::TSeq_set::iterator added_iter = obj_seq_set.insert(insert_iter, entry);
492  if ( seq_set.count++ == 0 ) {
493  seq_set.first_iter = added_iter;
494  }
495  _ASSERT(!m_Seq_set[seq_index]);
496  m_Seq_set[seq_index++] = info;
498  }
499 }
500 
501 
502 void CBioseq_set_Info::x_SetChunkBioseqs(const list< CRef<CBioseq> >& bioseqs, int chunk_id)
503 {
504  const int kOrderNa = 0;
505  const int kOrderNonNa = 1;
506  bool has_na = false;
507  bool has_non_na = false;
508  for ( auto& i : bioseqs ) {
509  if ( i->GetInst().IsNa() ) {
510  has_na = true;
511  if ( has_non_na ) {
512  break;
513  }
514  }
515  else {
516  has_non_na = true;
517  if ( has_na ) {
518  break;
519  }
520  }
521  }
522  if ( has_na && has_non_na ) {
523  // split na and non-na
524  list< CRef<CBioseq> > na_bioseqs, non_na_bioseqs;
525  for ( auto& i : bioseqs ) {
526  (i->GetInst().IsNa()? na_bioseqs: non_na_bioseqs).push_back(i);
527  }
528  x_SetChunkBioseqs2(na_bioseqs, TChunkSeqSetsKey(kOrderNa, chunk_id));
529  x_SetChunkBioseqs2(non_na_bioseqs, TChunkSeqSetsKey(kOrderNonNa, chunk_id));
530  }
531  else {
532  x_SetChunkBioseqs2(bioseqs, TChunkSeqSetsKey(has_na? kOrderNa: kOrderNonNa, chunk_id));
533  }
534 }
535 
536 
538 {
539  _ASSERT(!entry->HasParent_Info());
540  entry->x_ParentAttach(*this);
541  _ASSERT(&entry->GetParentBioseq_set_Info() == this);
542  x_AttachObject(*entry);
543 }
544 
545 
547 {
548  _ASSERT(&entry->GetParentBioseq_set_Info() == this);
549  x_DetachObject(*entry);
550  entry->x_ParentDetach(*this);
551  _ASSERT(!entry->HasParent_Info());
552 }
553 
554 
556 {
557  if ( x_DirtyAnnotIndex() ) {
558  GetTSE_Info().UpdateAnnotIndex(*this);
560  }
561 }
562 
563 
565 {
567  for ( size_t i = 0; i < m_Seq_set.size(); ++i ) {
568  m_Seq_set[i]->x_UpdateAnnotIndex(tse);
569  }
570 }
571 
572 
virtual void x_ParentAttach(CSeq_entry_Info &parent)
virtual void x_TSEAttachContents(CTSE_Info &tse)
virtual void x_TSEDetachContents(CTSE_Info &tse)
virtual void x_ParentDetach(CSeq_entry_Info &parent)
virtual void x_DSDetachContents(CDataSource &ds)
void x_DoUpdate(TNeedUpdateFlags flags)
virtual void x_DSAttachContents(CDataSource &ds)
void x_UpdateAnnotIndexContents(CTSE_Info &tse)
TObjAnnot & x_SetObjAnnot(void)
void x_ParentAttach(CSeq_entry_Info &parent)
virtual ~CBioseq_set_Info(void)
const TDescr & x_GetDescr(void) const
const TChunkIds & x_GetBioseqChunkIds() const
virtual void x_TSEAttachContents(CTSE_Info &tse)
void x_DSAttachContents(void)
void RemoveEntry(CRef< CSeq_entry_Info > entry)
void x_ParentDetach(CSeq_entry_Info &parent)
CConstRef< TObject > GetBioseq_setCore(void) const
virtual void x_UpdateAnnotIndexContents(CTSE_Info &tse)
void x_AddBioseqChunkId(TChunkId chunk_id)
CConstRef< TObject > GetCompleteBioseq_set(void) const
TChunkSeqSets m_ChunkSeqSets
bool x_IsSetDescr(void) const
int GetEntryIndex(const CSeq_entry_Info &entry) const
bool x_CanGetDescr(void) const
static CRef< TObject > sx_ShallowCopy(const TObject &obj)
void x_DoUpdate(TNeedUpdateFlags flags)
void UpdateAnnotIndex(void) const
void x_AttachEntry(CRef< CSeq_entry_Info > info)
void x_DetachEntry(CRef< CSeq_entry_Info > info)
void x_SetObject(TObject &obj)
void x_SetChunkBioseqs2(const list< CRef< CBioseq > > &bioseqs, TChunkSeqSetsKey key)
CRef< CSeq_entry_Info > AddEntry(CSeq_entry &entry, int index, bool set_uniqid=false)
vector< CRef< CSeq_entry_Info > > TSeq_set
bool IsSetId(void) const
void x_DSUnmapObject(CConstRef< TObject > obj, CDataSource &ds)
pair< int, TChunkId > TChunkSeqSetsKey
void x_ResetObjAnnot(void)
friend class CSeq_entry_Info
void x_DSMapObject(CConstRef< TObject > obj, CDataSource &ds)
TDescr & x_SetDescr(void)
void x_DSDetachContents(void)
virtual void x_TSEDetachContents(CTSE_Info &tse)
int x_GetBioseq_set_Id(const CObject_id &object_id)
void x_SetChunkBioseqs(const list< CRef< CBioseq > > &bioseqs, int chunk_id)
CConstRef< CSeq_entry_Info > GetFirstEntry(void) const
const TId & GetId(void) const
CRef< TObject > m_Object
void x_Unmap(const CObject *obj, const CTSE_Info_Object *info)
void x_Map(const CObject *obj, const CTSE_Info_Object *info)
Definition: Date.hpp:53
Definition: Dbtag.hpp:53
Base class for all object manager exceptions.
CRef –.
Definition: ncbiobj.hpp:618
@Seq_descr.hpp User-defined methods of the data storage class.
Definition: Seq_descr.hpp:55
TObject & x_GetObject(void)
Definition: Seq_entry.hpp:56
void ParentizeOneLevel(void)
Definition: Seq_entry.cpp:89
void x_UpdateCore(void) const
virtual void SetBioObjectId(const CBioObjectId &id)
void x_SetNeedUpdate(TNeedUpdateFlags flags)
CDataSource & GetDataSource(void) const
void x_LoadChunks(const TChunkIds &chunk_ids) const
void x_DetachObject(CTSE_Info_Object &object)
bool HasDataSource(void) const
@ fNeedUpdate_children
all fields of children objects
const CTSE_Info & GetTSE_Info(void) const
bool x_DirtyAnnotIndex(void) const
void x_UpdateComplete(void) const
void x_AttachObject(CTSE_Info_Object &object)
vector< TChunkId > TChunkIds
@ kNeedUpdate_bits
number of bits for fields
void UpdateAnnotIndex(const CSeq_id_Handle &id) const
Definition: tse_info.cpp:1009
void x_SetBioseq_setId(int key, CBioseq_set_Info *info)
Definition: tse_info.cpp:941
void x_ResetBioseq_setId(int key, CBioseq_set_Info *info)
Definition: tse_info.cpp:957
CBioObjectId x_IndexBioseq_set(CBioseq_set_Info *)
Definition: tse_info.cpp:426
const_iterator begin() const
Definition: map.hpp:151
const_iterator end() const
Definition: map.hpp:152
Definition: map.hpp:338
static uch flags
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
#define NON_CONST_ITERATE(Type, Var, Cont)
Non constant version of ITERATE macro.
Definition: ncbimisc.hpp:822
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
CRef< C > Ref(C *object)
Helper functions to get CRef<> and CConstRef<> objects.
Definition: ncbiobj.hpp:2015
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:773
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define END_SCOPE(ns)
End the previously defined scope.
Definition: ncbistl.hpp:75
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define BEGIN_SCOPE(ns)
Define a new scope.
Definition: ncbistl.hpp:72
E_Choice Which(void) const
Which variant is currently selected.
Definition: Object_id_.hpp:235
TId GetId(void) const
Get the variant data.
Definition: Object_id_.hpp:270
bool IsSetClass(void) const
Check if a value has been assigned to Class data member.
const TDescr & GetDescr(void) const
Get the Descr member data.
TSet & SetSet(void)
Select the variant.
Definition: Seq_entry_.cpp:130
bool IsSetColl(void) const
to identify a collection Check if a value has been assigned to Coll data member.
TClass GetClass(void) const
Get the Class member data.
bool IsSetDate(void) const
Check if a value has been assigned to Date data member.
bool IsSetRelease(void) const
Check if a value has been assigned to Release data member.
const TSet & GetSet(void) const
Get the variant data.
Definition: Seq_entry_.cpp:124
bool IsSetAnnot(void) const
Check if a value has been assigned to Annot data member.
bool IsSetId(void) const
Check if a value has been assigned to Id data member.
bool IsSetSeq_set(void) const
Check if a value has been assigned to Seq_set data member.
const TRelease & GetRelease(void) const
Get the Release member data.
bool IsSetLevel(void) const
nesting level Check if a value has been assigned to Level data member.
bool IsSetDescr(void) const
Check if a value has been assigned to Descr data member.
const TDate & GetDate(void) const
Get the Date member data.
list< CRef< CSeq_annot > > TAnnot
bool IsSet(void) const
Check if variant Set is selected.
Definition: Seq_entry_.hpp:263
const TSeq_set & GetSeq_set(void) const
Get the Seq_set member data.
const TAnnot & GetAnnot(void) const
Get the Annot member data.
const TColl & GetColl(void) const
Get the Coll member data.
list< CRef< CSeq_entry > > TSeq_set
TSeq & SetSeq(void)
Select the variant.
Definition: Seq_entry_.cpp:108
TSeq_set & SetSeq_set(void)
Assign a value to Seq_set data member.
const TId & GetId(void) const
Get the Id member data.
TLevel GetLevel(void) const
Get the Level member data.
const Tdata & Get(void) const
Get the member data.
Definition: Seq_descr_.hpp:166
int i
static MDB_envinfo info
Definition: mdb_load.c:37
double value_type
The numeric datatype used by the parser.
Definition: muParserDef.h:228
CBioseq_set::TSeq_set::iterator first_iter
#define _ASSERT
Modified on Wed Jul 17 13:19:13 2024 by modify_doxy.py rev. 669887