1 /* $Id: Int_fuzz.cpp 311373 2011-07-11 19:16:41Z grichenk $
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: .......
27 *
28 * File Description:
29 * .......
30 *
31 * Remark:
32 * This code was originally generated by application DATATOOL
33 * using specifications from the ASN data definition file
34 * 'general.asn'.
35 *
36 * ===========================================================================
37 */
38
39 // standard includes
40
41 // generated includes
42 #include <ncbi_pch.hpp>
43 #include <objects/general/Int_fuzz.hpp>
44
45 #include <algorithm>
46 #include <set>
47 #include <math.h>
48
49 // generated classes
50
51 BEGIN_NCBI_SCOPE
52
53 BEGIN_objects_SCOPE // namespace ncbi::objects::
54
55 // destructor
~CInt_fuzz(void)56 CInt_fuzz::~CInt_fuzz(void)
57 {
58 }
59
60
GetLabel(string * label,TSeqPos pos,bool right) const61 void CInt_fuzz::GetLabel(string* label, TSeqPos pos, bool right) const
62 {
63 char lim = 0;
64 switch (Which()) {
65 case CInt_fuzz::e_P_m:
66 (*label) += "<+-" + NStr::IntToString(GetP_m()) + ">";
67 break;
68 case CInt_fuzz::e_Range:
69 (*label) += "<" + NStr::IntToString(GetRange().GetMin()) +
70 "." + NStr::IntToString(GetRange().GetMax()) + ">";
71 break;
72 case CInt_fuzz::e_Pct:
73 (*label) += "<" + NStr::IntToString(GetPct()) + "%>";
74 break;
75 case CInt_fuzz::e_Lim:
76 switch (GetLim()) {
77 case eLim_unk:
78 case eLim_other:
79 (*label) += "<?>";
80 break;
81 case eLim_gt:
82 lim = '>';
83 break;
84 case eLim_lt:
85 lim = '<';
86 break;
87 case eLim_tr:
88 lim = 'r';
89 break;
90 case eLim_tl:
91 lim = '^';
92 break;
93 default:
94 break;
95 }
96 break;
97 default:
98 break;
99 }
100
101 if (lim && lim != 'r') {
102 (*label) += lim;
103 lim = 0;
104 }
105
106 if (right) {
107 (*label) += NStr::IntToString(pos + 1);
108 }
109
110 if (lim == 'r') {
111 (*label) += '^';
112 }
113
114 if (!right) {
115 (*label) += NStr::IntToString(pos + 1);
116 }
117 }
118
119
AssignTranslated(const CInt_fuzz & f2,TSeqPos n1,TSeqPos n2)120 void CInt_fuzz::AssignTranslated(const CInt_fuzz& f2, TSeqPos n1, TSeqPos n2)
121 {
122 switch (f2.Which()) {
123 case e_Range:
124 SetRange().SetMin(f2.GetRange().GetMin() + n1 - n2);
125 SetRange().SetMax(f2.GetRange().GetMax() + n1 - n2);
126 break;
127 case e_Pct:
128 // use double to avoid overflow
129 SetPct((TSeqPos)((double)f2.GetPct() * n1 / n2));
130 break;
131 case e_Alt:
132 ITERATE (TAlt, it, f2.GetAlt()) {
133 SetAlt().push_back(*it + n1 - n2);
134 }
135 break;
136 default:
137 Assign(f2);
138 break;
139 }
140 }
141
142
Add(const CInt_fuzz & f2,TSeqPos & n1,TSeqPos n2,ECombine mode)143 void CInt_fuzz::Add(const CInt_fuzz& f2, TSeqPos& n1, TSeqPos n2,
144 ECombine mode)
145 {
146 static const double kInfinity = 1.0e20;
147 bool hit_pct = false, hit_unk = false, hit_circle = false;
148 double min_delta = 0.0, max_delta = 0.0;
149 set<TSignedSeqPos> offsets;
150 for (int i = 0; i < 2; ++i) {
151 const CInt_fuzz& f = i ? f2 : *this;
152 TSeqPos n = i ? n2 : n1;
153
154 switch (f.Which()) {
155 case e_P_m:
156 min_delta -= f.GetP_m();
157 max_delta += f.GetP_m();
158 break;
159
160 case e_Range:
161 min_delta -= n - f.GetRange().GetMin();
162 max_delta += f.GetRange().GetMax() - n;
163 break;
164
165 case e_Pct:
166 min_delta -= 0.001 * n * f.GetPct();
167 max_delta += 0.001 * n * f.GetPct();
168 hit_pct = true;
169 break;
170
171 case e_Lim:
172 switch (f.GetLim()) {
173 case eLim_unk:
174 hit_unk = (!hit_unk || mode != eReduce);
175 min_delta = -kInfinity;
176 // fall through
177 case eLim_gt:
178 max_delta = kInfinity;
179 break;
180 case eLim_lt:
181 min_delta = -kInfinity;
182 break;
183 case eLim_tr:
184 min_delta += 0.5;
185 max_delta += 0.5;
186 break;
187 case eLim_tl:
188 min_delta -= 0.5;
189 max_delta -= 0.5;
190 break;
191 case eLim_circle:
192 hit_circle = (!hit_circle || mode != eReduce);
193 break;
194 default:
195 break;
196 }
197 break;
198
199 case e_Alt:
200 {
201 if (f.GetAlt().empty()) {
202 break;
203 }
204 if (offsets.empty()) {
205 ITERATE (TAlt, it, f.GetAlt()) {
206 offsets.insert(*it - n);
207 }
208 } else if (mode == eReduce) {
209 // possibly too optimistic; endpoints may balance better
210 // than interior points
211 min_delta = max_delta = f.GetAlt().front();
212 ITERATE (TAlt, it, f.GetAlt()) {
213 if (*it < min_delta) {
214 min_delta = *it;
215 } else if (*it > max_delta) {
216 max_delta = *it;
217 }
218 }
219 min_delta += *offsets.rbegin();
220 max_delta += *offsets.begin();
221 offsets.clear();
222 } else {
223 set<TSignedSeqPos> offsets0(offsets);
224 offsets.clear();
225 ITERATE (set<TSignedSeqPos>, it, offsets0) {
226 ITERATE (TAlt, it2, f.GetAlt()) {
227 offsets.insert(*it + *it2 - n);
228 }
229 }
230 }
231 break;
232 }
233
234 default:
235 break;
236 }
237
238 if (mode == eReduce && max_delta - min_delta < kInfinity / 2) {
239 swap(min_delta, max_delta);
240 }
241 }
242
243 if (min_delta > max_delta) {
244 swap(min_delta, max_delta);
245 }
246
247 TSignedSeqPos min_delta_sp = TSignedSeqPos(floor(min_delta + 0.5));
248 TSignedSeqPos max_delta_sp = TSignedSeqPos(floor(max_delta + 0.5));
249
250 if (min_delta < -kInfinity / 2) {
251 if (max_delta > kInfinity / 2) {
252 if ( /* mode == eReduce && */ !hit_unk ) {
253 // assume cancellation
254 SetP_m(0);
255 } else {
256 SetLim(eLim_unk);
257 }
258 } else {
259 if ( !offsets.empty() ) {
260 n1 += *offsets.rbegin();
261 }
262 n1 += max_delta_sp;
263 SetLim(eLim_lt);
264 }
265 } else if (max_delta > kInfinity / 2) {
266 if ( !offsets.empty() ) {
267 n1 += *offsets.begin();
268 }
269 n1 += min_delta_sp;
270 SetLim(eLim_gt);
271 } else if ( !offsets.empty() ) {
272 if (max_delta - min_delta < 0.5) {
273 TAlt& alt = SetAlt();
274 alt.clear();
275 ITERATE(set<TSignedSeqPos>, it, offsets) {
276 alt.push_back(n1 + *it + min_delta_sp);
277 }
278 } else if (mode == eReduce) {
279 TRange& r = SetRange();
280 min_delta += *offsets.rbegin();
281 max_delta += *offsets.begin();
282 if (min_delta > max_delta) {
283 swap(min_delta, max_delta);
284 }
285 r.SetMin(n1 + min_delta_sp);
286 r.SetMax(n1 + max_delta_sp);
287 } else {
288 // assume there's enough spread to cover any gaps
289 TRange& r = SetRange();
290 r.SetMin(n1 + min_delta_sp + *offsets.begin());
291 r.SetMax(n1 + max_delta_sp + *offsets.rbegin());
292 }
293 } else if (max_delta - min_delta < 0.5) { // single point identified
294 double delta = 0.5 * (min_delta + max_delta);
295 double rdelta = floor(delta + 0.5);
296 n1 += (TSignedSeqPos)rdelta;
297 if (delta - rdelta > 0.25) {
298 SetLim(eLim_tr);
299 } else if (delta - rdelta < -0.25) {
300 SetLim(eLim_tl);
301 } else if (hit_circle) {
302 SetLim(eLim_circle);
303 } else {
304 SetP_m(0);
305 }
306 } else if (hit_pct) {
307 n1 += (TSignedSeqPos)floor(0.5 * (min_delta + max_delta + 1));
308 SetPct((TSeqPos)floor(500.0 * (max_delta - min_delta) / n1 + 0.5));
309 } else if (min_delta + max_delta < 0.5) { // symmetric
310 SetP_m(max_delta_sp);
311 } else {
312 TRange& r = SetRange();
313 r.SetMin(n1 + min_delta_sp);
314 r.SetMax(n1 + max_delta_sp);
315 }
316 }
317
318
Negate(TSeqPos n)319 void CInt_fuzz::Negate(TSeqPos n)
320 {
321 switch (Which()) {
322 case e_P_m:
323 case e_Pct:
324 break; // already symmetric
325
326 case e_Range:
327 {
328 TRange& r = SetRange();
329 TSeqPos old_max = r.GetMax();
330 r.SetMax(n + n - r.GetMin());
331 r.SetMin(n + n - old_max);
332 break;
333 }
334
335 case e_Lim:
336 switch (GetLim()) {
337 case eLim_gt: SetLim(eLim_lt); break;
338 case eLim_lt: SetLim(eLim_gt); break;
339 case eLim_tr: SetLim(eLim_tl); break;
340 case eLim_tl: SetLim(eLim_tr); break;
341 default: break;
342 }
343 break;
344
345 case e_Alt:
346 NON_CONST_ITERATE(TAlt, it, SetAlt()) {
347 *it = n + n - *it;
348 }
349 break;
350
351 default:
352 break;
353 }
354 }
355
356
357 END_objects_SCOPE // namespace ncbi::objects::
358
359 END_NCBI_SCOPE
360
361 /* Original file checksum: lines: 61, chars: 1885, CRC32: bf6aceba */
362