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

Go to the SVN repository for this file.

1 /* $Id: macro_fn_loc_constr.cpp 46736 2021-09-20 16:48:49Z asztalos $
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: Andrea Asztalos
27  *
28  */
29 
30 #include <ncbi_pch.hpp>
31 #include <sstream>
34 
35 /** @addtogroup GUI_MACRO_SCRIPTS_UTIL
36  *
37  * @{
38  */
39 
41 BEGIN_SCOPE(macro)
43 
44 /// class CMacroFunction_LocPartialTest - tests whether the location is 5'/3' partial
45 /// ISPARTIALSTART() - returns true if it is 5' partial
46 /// ISPARTIALSTOP() - returns true if it is 3' partial
47 ///
48 const char* CMacroFunction_LocPartialTest::sm_PartialStart = "ISPARTIALSTART";
49 const char* CMacroFunction_LocPartialTest::sm_PartialStop = "ISPARTIALSTOP";
50 
52 {
53  CRef<CScope> scope = m_DataIter->GetScopedObject().scope;
54  if (!scope)
55  return;
56 
58  CObjectInfo oi;
60 
61  if (m_Args.empty()) {
62  oi = m_DataIter->GetEditedObject();
63  objs.push_back(CMQueryNodeValue::SResolvedField(CObjectInfo(), oi));
64  }
65  else {
66  objs = m_Args[0]->GetObjects();
67  }
68 
69  if (objs.empty())
70  return;
71 
72 
73  // when multiple features, return true if there is at least one feature that is partial
74  bool one_partial_start = false, one_partial_stop = false;
75  for (auto&& it : objs) {
76  CSeq_feat* edit_feat = CTypeConverter<CSeq_feat>::SafeCast(it.field.GetObjectPtr());
77  if (!edit_feat)
78  NCBI_THROW(CException, eUnknown, "Feature expected for checking partialness");
79 
80  const CSeq_loc& loc = edit_feat->GetLocation();
81  switch (m_TestCase) {
83  one_partial_start |= loc.IsPartialStart(eExtreme_Biological);
84  break;
85  case ELocEndType::eStop:
86  one_partial_stop |= loc.IsPartialStop(eExtreme_Biological);
87  break;
88  default:
89  break;
90  }
91  }
92 
93  switch (m_TestCase) {
96  m_Result->SetBool(one_partial_start);
97  break;
98  case ELocEndType::eStop:
100  m_Result->SetBool(one_partial_stop);
101  break;
102  default:
103  break;
104  }
105 }
106 
108 {
109  return (m_Args.empty() || (m_Args.size() == 1 && (m_Args[0]->AreObjects() || m_Args[0]->IsNotSet())));
110 }
111 
112 
113 //////////////////////////////////////////////////////////////////////////////
114 /// class CMacroFunction_LocEnd
115 /// Start() and Stop() - return the positional extremes of a location
116 ///
117 const char* CMacroFunction_LocEnd::sm_Start = "START";
118 const char* CMacroFunction_LocEnd::sm_Stop = "STOP";
120 {
121  m_Result->SetNotSet();
122  CObjectInfo oi;
123 
124  oi = m_DataIter->GetEditedObject();
126  CRef<CScope> scope = m_DataIter->GetScopedObject().scope;
127  if (!edit_feat || !scope)
128  return;
129 
130  const CSeq_loc& loc = edit_feat->GetLocation();
131  TSeqPos pos = 0;
132  switch (m_TestCase) {
133  case ELocEndType::eStart:
134  pos = loc.GetStart(eExtreme_Positional);
135  break;
136  case ELocEndType::eStop:
137  pos = loc.GetStop(eExtreme_Positional);
138  break;
139  default:
140  break;
141  }
142 
143  bool one_based = (m_Args.size() == 1) ? m_Args[0]->GetBool() : false;
144  if (one_based) {
145  pos++;
146  }
147  m_Result->SetInt(pos);
148 }
149 
151 {
152  return (m_Args.empty() || (m_Args.size() == 1 && m_Args[0]->IsBool()));
153 }
154 
155 
156 //////////////////////////////////////////////////////////////////////////////
157 /// CMacroFunction_LocationStrand - function returns the strand of the location
158 /// STRAND() - returns the corresponding string if it's set.
159 ///
160 DEFINE_MACRO_FUNCNAME(CMacroFunction_LocationStrand, "STRAND")
161 void CMacroFunction_LocationStrand::TheFunction()
162 {
163  CObjectInfo oi = m_DataIter->GetEditedObject();
165  if (!edit_feat)
166  return;
167 
168  m_Result->SetNotSet();
169 
170  const CSeq_loc& loc = edit_feat->GetLocation();
171  if (loc.IsSetStrand()) {
172  string strand = ENUM_METHOD_NAME(ENa_strand)()->FindName(loc.GetStrand(), true);
173  m_Result->SetString(strand);
174  }
175 }
176 
177 bool CMacroFunction_LocationStrand::x_ValidArguments() const
178 {
179  return (m_Args.empty());
180 }
181 
182 
183 //////////////////////////////////////////////////////////////////////////////
184 /// CMacroFunction_LocationStrandSymbol - function returns the strand of the location
185 /// STRANDSYMBOL() - returns "." (no strand) or "+" or "-".
186 ///
187 DEFINE_MACRO_FUNCNAME(CMacroFunction_LocationStrandSymbol, "STRANDSYMBOL")
188 void CMacroFunction_LocationStrandSymbol::TheFunction()
189 {
190  CObjectInfo oi = m_DataIter->GetEditedObject();
192  if (!edit_feat)
193  return;
194 
195  m_Result->SetNotSet();
196 
197  const CSeq_loc& loc = edit_feat->GetLocation();
198  if (!loc.IsSetStrand()) {
199  m_Result->SetString(".");
200  return;
201  }
202 
203  switch(loc.GetStrand()) {
205  m_Result->SetString("+");
206  break;
208  m_Result->SetString("-");
209  break;
210  default:
211  m_Result->SetString(".");
212  break;
213  }
214 }
215 
216 bool CMacroFunction_LocationStrandSymbol::x_ValidArguments() const
217 {
218  return (m_Args.empty());
219 }
220 
221 //////////////////////////////////////////////////////////////////////////////
222 /// class CMacroFunction_LocationType - obtain information about the type of location
223 /// ISLOCATIONTYPE(loc_type) - returns true if type of location is loc_type
224 /// parameter "loc_type" can be one of: "single-interval", "ordered", "joined"
225 ///
227 void CMacroFunction_LocationType::TheFunction()
228 {
229  CObjectInfo oi = m_DataIter->GetEditedObject();
231  if (!edit_feat)
232  return;
233 
234  const CSeq_loc& loc = edit_feat->GetLocation();
235  const string& location_type = m_Args[0]->GetString();
236 
238  if (NStr::EqualNocase(location_type, "single-interval")) {
239  loc_cons->SetLocation_type(eLocation_type_constraint_single_interval);
240  } else if (NStr::EqualNocase(location_type, "ordered")) {
241  loc_cons->SetLocation_type(eLocation_type_constraint_ordered);
242  } else if (NStr::EqualNocase(location_type, "joined")) {
243  loc_cons->SetLocation_type(eLocation_type_constraint_joined);
244  }
245 
246  bool match = x_Match(loc, *loc_cons);
247  m_Result->SetDataType(CMQueryNodeValue::eBool);
248  m_Result->SetBool(match);
249 }
250 
251 
253 {
254  bool has_null = false;
255  int num_intervals = 0;
256 
258  return false; // different than the one present in the toolkit
259 
260  for (CSeq_loc_CI loc_iter(loc); loc_iter; ++loc_iter) {
261  if (loc_iter.GetEmbeddingSeq_loc().Which() == CSeq_loc::e_Null) {
262  has_null = true;
263  } else if (!loc_iter.IsEmpty()) {
264  num_intervals ++;
265  }
266  }
267 
269  if (num_intervals == 1) {
270  return true;
271  }
272  } else if (loc_cons.GetLocation_type() == eLocation_type_constraint_joined) {
273  if (num_intervals > 1 && !has_null) {
274  return true;
275  }
276  } else if (loc_cons.GetLocation_type() == eLocation_type_constraint_ordered) {
277  if (num_intervals > 1 && has_null && loc.Which() == CSeq_loc::e_Mix) { // different
278  return true;
279  }
280  }
281 
282  return false;
283 }
284 
286 {
287  return (m_Args.size() == 1 && m_Args[0]->IsString());
288 }
289 
290 //////////////////////////////////////////////////////////////////////////////
291 /// class CMacroFunction_LocationSeqType
292 /// IS_SEQ_AA(["location"]) - returns true if the sequence identified by this location is a protein
293 /// IS_SEQ_NA(["location"]) - returns true if the sequence identified by this location is a nucleotide sequence
294 /// Initially, a parameter was necessary to specify the location, but later on this requirement was removed
295 const char* CMacroFunction_LocationSeqType::sm_SeqNa = "IS_SEQ_NA";
296 const char* CMacroFunction_LocationSeqType::sm_SeqAa = "IS_SEQ_AA";
298 {
299  CObjectInfo oi = m_DataIter->GetEditedObject();
301  if (!edit_feat)
302  return;
303 
304  const CSeq_loc* loc = nullptr;
305  if (m_Args.empty()) {
306  loc = &(edit_feat->GetLocation());
307  }
308  else if (m_Args.size() == 1 && !m_Args[0]->GetString().empty()) {
309  loc = s_GetLocation(m_Args[0]->GetString(), m_DataIter);
310  }
311  if (!loc)
312  return;
313 
314  SConstScopedObject sobject = m_DataIter->GetScopedObject();
315  CBioseq_Handle bsh;
316  try {
317  bsh = sobject.scope->GetBioseqHandle(*loc);
318  }
319  catch (const CException&) {
320  return;
321  }
322 
323  bool value = false;
324  if ((bsh.IsNucleotide() && m_Seqtype == eSeqtype_constraint_nuc) ||
326  value = true;
327  }
328 
331 }
332 
334 {
335  return (m_Args.empty() || (m_Args.size() == 1 && m_Args[0]->IsString()));
336 }
337 
338 
340 {
341  CObjectInfo objInfo = iter->GetEditedObject();
342  CMQueryNodeValue::TObs res_oi;
343  if (!GetFieldsByName(&res_oi, objInfo, field_name) || res_oi.size() != 1)
344  return nullptr;
345 
346  // location - is a pointer to a choice type
347  if (res_oi.front().field.GetTypeFamily() == eTypeFamilyPointer) {
348  CObjectInfo oi = res_oi.front().field.GetPointedObject();
349  if (oi.GetTypeFamily() == eTypeFamilyChoice) {
351  if (loc) {
352  return loc;
353  }
354  }
355  }
356  return nullptr;
357 }
358 
359 //////////////////////////////////////////////////////////////////////////////
360 /// class CMacroFunction_LocationDistConstraint
361 /// DISTFROMSTART() [>][=][<] distance
362 /// DISTFROMSTOP()
363 ///
364 const char* CMacroFunction_LocationDistConstraint::sm_FromStart = "DISTFROMSTART";
365 const char* CMacroFunction_LocationDistConstraint::sm_FromStop = "DISTFROMSTOP";
367 {
368  m_Result->SetNotSet();
369  CObjectInfo oi;
370 
371  if (m_Args.empty()) {
372  oi = m_DataIter->GetEditedObject();
373  }
374  else {
375  CMQueryNodeValue::TObs res_oi = m_Args[0]->GetObjects();
376  if (res_oi.size() != 1)
377  return;
378  oi = res_oi.front().field;
379  }
380 
382  CRef<CScope> scope = m_DataIter->GetScopedObject().scope;
383  if (!feat || !scope)
384  return;
385 
386  const CSeq_loc& loc = feat->GetLocation();
387  CBioseq_Handle bsh;
388  try {
389  bsh = scope->GetBioseqHandle(loc);
390  }
391  catch (const CException&) {
392  return;
393  }
394 
395  TSeqPos start = loc.GetStart(eExtreme_Positional);
396  TSeqPos stop = loc.GetStop(eExtreme_Positional);
397  ENa_strand strand = loc.GetStrand();
398  int diff = 0; // difference between respective ends of feature and sequence
399 
400  switch (m_TestCase) {
401  case ELocEndType::eStart:
402  if (strand == eNa_strand_minus) {
403  diff = bsh.GetBioseqLength() - 1 - stop;
404  } else {
405  diff = start;
406  }
407  break;
408  case ELocEndType::eStop:
409  if (strand == eNa_strand_minus) {
410  diff = start;
411  } else {
412  diff = bsh.GetBioseqLength() - 1 - stop;
413  }
414  break;
415  default:
416  break;
417  }
418 
419  m_Result->SetInt(diff);
420 }
421 
423 {
424  return (m_Args.empty() || (m_Args.size() == 1 && (m_Args[0]->AreObjects() || m_Args[0]->IsNotSet())));
425 }
426 
427 END_SCOPE(macro)
429 
430 /* @} */
@ eExtreme_Positional
numerical value
Definition: Na_strand.hpp:63
@ eExtreme_Biological
5' and 3'
Definition: Na_strand.hpp:62
CBioseq_Handle –.
CObjectInfo –.
Definition: objectinfo.hpp:597
namespace ncbi::objects::
Definition: Seq_feat.hpp:58
Seq-loc iterator class – iterates all intervals from a seq-loc in the correct order.
Definition: Seq_loc.hpp:453
unsigned int TSeqPos
Type for sequence locations and lengths.
Definition: ncbimisc.hpp:875
#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
static const char * sm_Stop
static const char * sm_SeqNa
class CMacroFunction_LocationSeqType IS_SEQ_AA(["location"]) - returns true if the sequence identifie...
virtual void TheFunction()
Function implementation.
static const char * sm_PartialStart
class CMacroFunction_LocPartialTest - tests whether the location is 5'/3' partial ISPARTIALSTART() - ...
list< SResolvedField > TObs
Definition: macro_exec.hpp:92
void SetBool(bool data)
Definition: macro_exec.hpp:127
static const char * sm_FromStart
class CMacroFunction_LocationDistConstraint DISTFROMSTART() [>][=][<] distance DISTFROMSTOP()
void SetDataType(EType dt)
Definition: macro_exec.hpp:121
virtual bool x_ValidArguments() const
Tests the number and the type of function arguments.
virtual bool x_ValidArguments() const
Tests the number and the type of function arguments.
virtual bool x_ValidArguments() const
Tests the number and the type of function arguments.
virtual void TheFunction()
Function implementation.
virtual bool x_ValidArguments() const
Tests the number and the type of function arguments.
bool GetFieldsByName(CMQueryNodeValue::TObs *results, const CObjectInfo &oi_i, const string &field_name)
Resolve existing dot qualified ASN.1 name (field_name) starting from the object information instance ...
static objects::CSeq_loc * s_GetLocation(const string &field_name, CIRef< IMacroBioDataIter > iter)
bool x_Match(const objects::CSeq_loc &loc, const objects::CLocation_constraint &loc_cons)
objects::ESeqtype_constraint m_Seqtype
CRef< CMQueryNodeValue > m_Result
virtual void TheFunction()
Function implementation.
#define DEFINE_MACRO_FUNCNAME(CL_NAME, FN_NAME)
void SetInt(Int8 data)
Definition: macro_exec.hpp:128
virtual bool x_ValidArguments() const
Tests the number and the type of function arguments.
CIRef< IMacroBioDataIter > m_DataIter
virtual void TheFunction()
Function implementation.
static const char * sm_Start
class CMacroFunction_LocEnd Start() and Stop() - return the positional extremes of a location
CRef< objects::CScope > scope
Definition: objects.hpp:53
#define ENUM_METHOD_NAME(EnumName)
Definition: serialbase.hpp:994
static const TObjectType * SafeCast(TTypeInfo type)
Definition: serialutil.hpp:76
@ eTypeFamilyChoice
Definition: serialdef.hpp:141
@ eTypeFamilyPointer
Definition: serialdef.hpp:143
bool IsPartialStart(ESeqLocExtremes ext) const
check start or stop of location for e_Lim fuzz
Definition: Seq_loc.cpp:3222
ENa_strand GetStrand(void) const
Get the location's strand.
Definition: Seq_loc.cpp:882
TSeqPos GetStart(ESeqLocExtremes ext) const
Return start and stop positions of the seq-loc.
Definition: Seq_loc.cpp:915
bool IsSetStrand(EIsSetStrand flag=eIsSetStrand_Any) const
Check if strand is set for any/all part(s) of the seq-loc depending on the flag.
Definition: Seq_loc.cpp:858
bool IsPartialStop(ESeqLocExtremes ext) const
Definition: Seq_loc.cpp:3251
TSeqPos GetStop(ESeqLocExtremes ext) const
Definition: Seq_loc.cpp:963
CObjectInfo GetPointedObject(void) const
Get data and type information of object to which this type refers.
Definition: objectinfo.cpp:102
TObjectPtr GetObjectPtr(void) const
Get pointer to object.
ETypeFamily GetTypeFamily(void) const
Get data type family.
CBioseq_Handle GetBioseqHandle(const CSeq_id &id)
Get bioseq handle by seq-id.
Definition: scope.cpp:95
bool IsNucleotide(void) const
TSeqPos GetBioseqLength(void) const
bool IsProtein(void) const
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define USING_SCOPE(ns)
Use the specified namespace.
Definition: ncbistl.hpp:78
#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
static bool EqualNocase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-insensitive equality of a substring with another string.
Definition: ncbistr.hpp:5353
TLocation_type GetLocation_type(void) const
Get the Location_type member data.
@ eSeqtype_constraint_prot
@ eSeqtype_constraint_nuc
@ eLocation_type_constraint_ordered
@ eLocation_type_constraint_joined
@ eLocation_type_constraint_any
@ eLocation_type_constraint_single_interval
const TLocation & GetLocation(void) const
Get the Location member data.
Definition: Seq_feat_.hpp:1117
ENa_strand
strand of nucleic acid
Definition: Na_strand_.hpp:64
E_Choice Which(void) const
Which variant is currently selected.
Definition: Seq_loc_.hpp:475
@ eNa_strand_plus
Definition: Na_strand_.hpp:66
@ eNa_strand_minus
Definition: Na_strand_.hpp:67
@ e_Null
not placed
Definition: Seq_loc_.hpp:98
Functions that resolve field names described in asn format.
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
static int match(register const pcre_uchar *eptr, register const pcre_uchar *ecode, const pcre_uchar *mstart, int offset_top, match_data *md, eptrblock *eptrb, unsigned int rdepth)
Definition: pcre_exec.c:513
Modified on Fri Jun 14 16:47:35 2024 by modify_doxy.py rev. 669887