1 // $Id: ui_vars_forces.cpp,v 1.90 2012/03/09 22:55:20 jmcgill Exp $
2
3 /*
4 * Copyright 2004 Peter Beerli, Mary Kuhner, Jon Yamato and Joseph Felsenstein
5 *
6 * This software is distributed free of charge for non-commercial use
7 * and is copyrighted. Of course, we do not guarantee that the software
8 * works, and are not responsible for any damage you may cause or have.
9 *
10 */
11
12 #include <cassert>
13 #include <algorithm>
14 #include <deque>
15 #include <map>
16 #include <vector>
17
18 #include "calculators.h"
19 #include "constants.h" // for method_type
20 #include "defaults.h"
21 #include "errhandling.h"
22 #include "registry.h"
23 #include "stringx.h"
24 #include "ui_vars.h"
25 #include "ui_constants.h"
26 #include "ui_vars_forces.h"
27 #include "ui_vars_prior.h"
28 #include "ui_warnings.h"
29 #include "vectorx.h"
30
31 using std::deque;
32 using std::make_pair;
33 using std::map;
34 using std::vector;
35 using std::list;
36
37 //------------------------------------------------------------------------------------
38
UIVarsSingleForce(UIVars * myUIVars,force_type ftype,long int nparams,double defaultVal,method_type methodType,bool canBeSetUnset,bool isOn,long int eventMax,UIVarsPrior defaultPrior)39 UIVarsSingleForce::UIVarsSingleForce
40 (
41 UIVars * myUIVars,
42 force_type ftype,
43 long int nparams,
44 double defaultVal,
45 method_type methodType,
46 bool canBeSetUnset,
47 bool isOn,
48 long int eventMax,
49 UIVarsPrior defaultPrior
50 )
51 :
52 UIVarsComponent(myUIVars),
53 m_numParameters(nparams),
54 m_defaultValue(defaultVal),
55 m_defaultMethodType(methodType),
56 m_canSetOnOff(canBeSetUnset),
57 m_onOff(isOn),
58 m_maxEvents(eventMax),
59 m_profileType(defaults::profileType),
60 m_doProfile(nparams,true),
61 m_userSuppliedStartValues(nparams,FLAGDOUBLE),
62 // we CAN'T have user supplied start values at
63 // the time this structure is created. So we
64 // set them to FLAGDOUBLE. We should never access
65 // these FLAGDOUBLE values because that would
66 // require m_startValueMethodTypes to contain
67 // method_USER, and we assert against that below
68 m_startValueMethodTypes(nparams,methodType),
69 m_pstatusValues(nparams,ParamStatus(pstat_unconstrained)),
70 m_defaultPrior(defaultPrior),
71 m_priors(nparams, defaultPrior),
72 m_useDefaultPrior(nparams, true),
73 m_ftype(ftype)
74 {
75 long i;
76 for (i = 0; i < nparams; ++i)
77 {
78 m_pstatusValues.push_back(ParamStatus(pstat_unconstrained));
79 }
80 assert(methodType != method_USER);
81 assert(m_defaultMethodType != method_USER);
82 // must be a type that comes with a default value
83 // (e.g. method_PROGRAMDEFAULT) or requires calculation
84 // (method_FST or method_WATTERSON)
85 }
86
UIVarsSingleForce(UIVars * myUIVars,const UIVarsSingleForce & singleForce)87 UIVarsSingleForce::UIVarsSingleForce
88 (
89 UIVars * myUIVars,
90 const UIVarsSingleForce& singleForce)
91 :
92 UIVarsComponent(myUIVars),
93 m_numParameters (singleForce.m_numParameters),
94 m_defaultValue (singleForce.m_defaultValue),
95 m_defaultMethodType (singleForce.m_defaultMethodType),
96 m_canSetOnOff (singleForce.m_canSetOnOff),
97 m_onOff (singleForce.m_onOff),
98 m_maxEvents (singleForce.m_maxEvents),
99 m_profileType (singleForce.m_profileType),
100 m_doProfile (singleForce.m_doProfile),
101 m_userSuppliedStartValues (singleForce.m_userSuppliedStartValues),
102 m_startValueMethodTypes (singleForce.m_startValueMethodTypes),
103 m_groups (singleForce.m_groups),
104 m_pstatusValues (singleForce.m_pstatusValues),
105 m_defaultPrior (singleForce.m_defaultPrior),
106 m_priors (singleForce.m_priors),
107 m_useDefaultPrior (singleForce.m_useDefaultPrior),
108 m_ftype (singleForce.m_ftype),
109 m_calculatedStartValues (singleForce.m_calculatedStartValues)
110 {
111 }
112
checkIndexValue(long int index) const113 void UIVarsSingleForce::checkIndexValue(long int index) const
114 {
115 // if you get an assert here, the menu or xml logic
116 // isn't checking something it should be
117 assert(index >= 0);
118 assert(index < GetNumParameters());
119 // However, allowing the user to put in parameter values in the Group
120 // tag means we check here for that validity, and we need to
121 // throw if it fails:
122 if (index < 0)
123 {
124 throw data_error("Invalid (negative) parameter index in checkIndexValue.");
125 }
126 if (index >= GetNumParameters())
127 {
128 throw data_error("Invalid (too large) parameter index in checkIndexValue.");
129 }
130 }
131
AssertOnIllegalStartMethod(method_type method)132 void UIVarsSingleForce::AssertOnIllegalStartMethod(method_type method)
133 {
134 assert(method == method_PROGRAMDEFAULT);
135 // assume that there are no calculation start method
136 // types (such as method_FST or method_WATTERSON) for
137 // an arbitrary force. Those that do have them will
138 // override this method
139 }
140
141 // used to set a start method without providing a value (thus not
142 // suitable for use in Set
SetStartMethod(method_type method,long int index)143 void UIVarsSingleForce::SetStartMethod(method_type method, long int index)
144 {
145 checkIndexValue(index);
146 AssertOnIllegalStartMethod(method);
147 m_startValueMethodTypes[index] = method;
148
149 }
150
SetStartMethods(method_type method)151 void UIVarsSingleForce::SetStartMethods(method_type method)
152 {
153 for (int index = 0; index < GetNumParameters(); index++)
154 {
155 // use this method since we want to pick up
156 // sanity checking done in virtual method
157 // SetStartMethod
158 SetStartMethod(method,index);
159 }
160 }
161
162 string
GetParamName(long int pindex)163 UIVarsSingleForce::GetParamName(long int pindex)
164 {
165 return GetConstUIVars().GetParamNameWithConstraint(m_ftype, pindex);
166 }
167
168 bool
GetLegal() const169 UIVarsSingleForce::GetLegal() const
170 {
171 return (GetOnOff() || m_canSetOnOff);
172 }
173
174 bool
GetDoProfile(long int index) const175 UIVarsSingleForce::GetDoProfile(long int index) const
176 {
177 checkIndexValue(index);
178 ParamStatus mystatus = GetParamstatus(index);
179 if (mystatus.Inferred())
180 {
181 if (GetConstUIVars().chains.GetDoBayesianAnalysis())
182 {
183 return true;
184 }
185 return m_doProfile[index];
186 }
187 else
188 return false;
189 }
190
GetProfileType() const191 proftype UIVarsSingleForce::GetProfileType() const
192 {
193 return m_profileType;
194 }
195
GetProfileType(long int index) const196 proftype UIVarsSingleForce::GetProfileType(long int index) const
197 {
198 checkIndexValue(index);
199 if( GetDoProfile(index))
200 {
201 return m_profileType;
202 }
203 else
204 {
205 return profile_NONE;
206 }
207 }
208
209 string
GetProfileTypeSummaryDescription() const210 UIVarsSingleForce::GetProfileTypeSummaryDescription() const
211 {
212 proftype ptype = GetProfileType();
213 paramlistcondition condition = GetParamListCondition();
214 if(condition == paramlist_NO)
215 {
216 return ToString(condition) + " ";
217 }
218 else
219 {
220 return ToString(ptype) +" (" +ToString(condition) +")";
221 }
222 }
223
224 string
GetPriorTypeSummaryDescription() const225 UIVarsSingleForce::GetPriorTypeSummaryDescription() const
226 {
227 bool somelinear = false;
228 bool somelog = false;
229 for (unsigned long pnum=0; pnum<m_priors.size(); pnum++)
230 {
231 ParamStatus mystatus = GetParamstatus(pnum);
232 if (mystatus.Inferred())
233 {
234 switch(GetPrior(pnum).GetPriorType())
235 {
236 case LINEAR:
237 somelinear = true;
238 break;
239 case LOGARITHMIC:
240 somelog = true;
241 break;
242 }
243 }
244 }
245 if (somelinear && somelog)
246 {
247 return "(mixed linear/log)";
248 }
249 else if (somelinear && (!somelog))
250 {
251 return "(all linear)";
252 }
253 else if (somelog && (!somelinear))
254 {
255 return "(all logarithmic)";
256 }
257 else
258 {
259 return "(none eligible)";
260 }
261 }
262
263 paramlistcondition
GetParamListCondition() const264 UIVarsSingleForce::GetParamListCondition() const
265 {
266 bool seenOff = false;
267 bool seenOn = false;
268 for (int index = 0; index < GetNumParameters(); index++)
269 {
270 // premature optimization being the root of all
271 // evil, I've not chosen to break out of the loop when
272 // seenOn and seenOff are both true, but you can change
273 // it if you want -- ewalkup 8-19-2004
274 if(GetParamValid(index))
275 {
276 if (GetDoProfile(index))
277 {
278 seenOn = true;
279 }
280 else
281 {
282 seenOff = true;
283 }
284 }
285 }
286 if(seenOn)
287 {
288 if(seenOff)
289 {
290 return paramlist_MIX;
291 }
292 else
293 {
294 return paramlist_YES;
295 }
296 }
297 else
298 {
299 return paramlist_NO;
300 }
301 }
302
SetDoProfile(bool doIt,long int index)303 void UIVarsSingleForce::SetDoProfile(bool doIt, long int index)
304 {
305 checkIndexValue(index);
306 long gindex = ParamInGroup(index);
307 ParamStatus mystatus = GetParamstatus(index);
308 if (doIt && !mystatus.Varies())
309 {
310 // Do nothing--we can't turn on profiling for this parameter.
311 if (GetParamValid(index))
312 {
313 string warning = "Warning: " + GetParamName(index) +
314 " may not be profiled because it is currently set to be "
315 + ToString(mystatus.Status()) + ".";
316 GetConstUIVars().GetUI()->AddWarning(warning);
317 }
318 return;
319 }
320 if (GetConstUIVars().chains.GetDoBayesianAnalysis())
321 {
322 if (doIt==false && mystatus.Inferred())
323 {
324 string warning = "Warning: Profiling is always on for all valid parameters in a Bayesian analysis, since profiling takes no extra time.";
325 GetConstUIVars().GetUI()->AddWarning(warning);
326 return;
327 }
328 }
329 m_doProfile[index] = doIt;
330 if (gindex != FLAGLONG)
331 {
332 SetDoProfilesForGroup(doIt, gindex);
333 }
334 }
335
SetDoProfile(bool doIt)336 void UIVarsSingleForce::SetDoProfile(bool doIt)
337 {
338 if (GetConstUIVars().chains.GetDoBayesianAnalysis())
339 {
340 if (doIt==false)
341 {
342 string warning = "Warning: Profiling is always on for all valid parameters in a Bayesian analysis, since profiling takes no extra time.";
343 GetConstUIVars().GetUI()->AddWarning(warning);
344 return;
345 }
346 }
347 for (int index = 0; index < GetNumParameters(); index++)
348 {
349 SetDoProfile(doIt,index);
350 }
351 }
352
SetProfileType(proftype p)353 void UIVarsSingleForce::SetProfileType(proftype p)
354 {
355 m_profileType = p;
356 }
357
GetParamstatus(long int pindex) const358 ParamStatus UIVarsSingleForce::GetParamstatus(long int pindex) const
359 {
360 long int gindex = ParamInGroup(pindex);
361 if (gindex != FLAGLONG)
362 {
363 ParamStatus mystatus = m_groups[gindex].first;
364 if ((mystatus.Status() == pstat_identical) && (pindex == m_groups[gindex].second[0]))
365 {
366 return ParamStatus(pstat_identical_head);
367 //MFIX probably needs changing, need to interface here
368 //with finished UI design
369 }
370 else
371 if ((mystatus.Status() == pstat_multiplicative) && (pindex == m_groups[gindex].second[0]))
372 {
373 return ParamStatus(pstat_multiplicative_head);
374 }
375 else
376 {
377 return mystatus;
378 }
379 }
380 else return m_pstatusValues[pindex];
381 };
382
SetParamstatus(const ParamStatus & mystatus,long int index)383 void UIVarsSingleForce::SetParamstatus(const ParamStatus& mystatus, long int index)
384 {
385 long int gindex = ParamInGroup(index);
386 if (gindex == FLAGLONG)
387 {
388 m_pstatusValues[index] = mystatus;
389 }
390 else
391 {
392 SetGroupParamstatus(mystatus.Status(), gindex);
393 }
394 };
395
GetStartValue(long int pindex) const396 double UIVarsSingleForce::GetStartValue(long int pindex) const
397 {
398 long int gindex = ParamInGroup(pindex);
399 if (gindex == FLAGLONG)
400 {
401 return GetUngroupedStartValue(pindex);
402 }
403 double sum = 0;
404 for (unsigned long int gpindex = 0; gpindex < m_groups[gindex].second.size(); gpindex++)
405 {
406 sum += GetUngroupedStartValue(m_groups[gindex].second[gpindex]);
407 }
408 return (sum/m_groups[gindex].second.size());
409 }
410
GetUngroupedStartValue(long int index) const411 double UIVarsSingleForce::GetUngroupedStartValue(long int index) const
412 {
413 // start value might have been set by the user, or we might
414 // have to grab it from the calculated start values
415
416 double retval = 0.0;
417 if (!GetParamstatus(index).Valid()) return 0.0;
418
419 checkIndexValue(index);
420 method_type thisMethod = m_startValueMethodTypes[index];
421
422 switch(thisMethod)
423 {
424 case method_PROGRAMDEFAULT:
425 retval = m_defaultValue;
426 break;
427 case method_USER:
428 retval = m_userSuppliedStartValues[index];
429 break;
430 default:
431 {
432 // see if we have calculated values for the
433 // start value method type for this parameter
434 map<method_type,DoubleVec1d>::const_iterator it;
435 it = m_calculatedStartValues.find(thisMethod);
436 if(it == m_calculatedStartValues.end())
437 {
438 assert(false);
439 throw implementation_error("Unable to calculate start values for " +
440 ToString(thisMethod) + ".");
441 }
442 // we've populated the m_calculatedStartValues for
443 // this method, so grab them and return the correct
444 // one for this parameter
445 retval = (it->second)[index];
446 break;
447 }
448 }
449 double minval = GetMinStartValue(index);
450 double maxval = GetMaxStartValue(index);
451 assert (maxval > minval);
452 if (retval < minval)
453 {
454 return minval;
455 }
456 if (retval > maxval)
457 {
458 return maxval;
459 }
460 return retval;
461 }
462
463 DoubleVec1d
GetStartValues() const464 UIVarsSingleForce::GetStartValues() const
465 {
466 DoubleVec1d retValue(GetNumParameters(),FLAGDOUBLE);
467 // the user may have calculated start values and
468 // then hand-edited some of them, so we need to
469 // populate a vector with the individual values
470 for(size_t i = 0; i < retValue.size(); i++)
471 {
472 retValue[i] = GetStartValue(i);
473 }
474 return retValue;
475 }
476
GetMinStartValue(long int pindex) const477 double UIVarsSingleForce::GetMinStartValue(long int pindex) const
478 {
479 ParamStatus mystatus = GetParamstatus(pindex);
480 if (!mystatus.Valid()) return 0;
481 if (GetConstUIVars().chains.GetDoBayesianAnalysis())
482 {
483 if (mystatus.Status() != pstat_constant)
484 {
485 return GetPrior(pindex).GetLowerBound();
486 }
487 }
488 switch(m_ftype)
489 {
490 case force_COAL:
491 return defaults::minTheta;
492 case force_MIG:
493 case force_DIVMIG:
494 return defaults::minMigRate;
495 case force_DISEASE:
496 return defaults::minDiseaseRate;
497 case force_REC:
498 return defaults::minRecRate;
499 case force_EXPGROWSTICK:
500 case force_GROW:
501 return defaults::minGrowRate;
502 case force_REGION_GAMMA:
503 return defaults::minGammaOverRegions;
504 break;
505 case force_LOGSELECTSTICK:
506 case force_LOGISTICSELECTION:
507 return defaults::minLSelectCoeff;
508 break;
509 case force_DIVERGENCE:
510 return defaults::minEpoch;
511 break;
512 default:
513 assert(false); //Uncaught force type.
514 }
515 return 0.0; //To prevent compiler warning.
516 }
517
GetMaxStartValue(long int pindex) const518 double UIVarsSingleForce::GetMaxStartValue(long int pindex) const
519 {
520 ParamStatus mystatus = GetParamstatus(pindex);
521 if (!mystatus.Valid()) return 0;
522 if (GetConstUIVars().chains.GetDoBayesianAnalysis())
523 {
524 if (mystatus.Status() != pstat_constant)
525 {
526 return GetPrior(pindex).GetUpperBound();
527 }
528 }
529 switch(m_ftype)
530 {
531 case force_COAL:
532 return defaults::maxTheta;
533 case force_MIG:
534 case force_DIVMIG:
535 return defaults::maxMigRate;
536 case force_DISEASE:
537 return defaults::maxDiseaseRate;
538 case force_REC:
539 return defaults::maxRecRate;
540 case force_EXPGROWSTICK:
541 case force_GROW:
542 return defaults::maxGrowRate;
543 case force_REGION_GAMMA:
544 return defaults::maxGammaOverRegions;
545 break;
546 case force_LOGSELECTSTICK:
547 case force_LOGISTICSELECTION:
548 return defaults::maxLSelectCoeff;
549 break;
550 case force_DIVERGENCE:
551 return defaults::maxEpoch;
552 break;
553 default:
554 assert(false); //Uncaught force type.
555 }
556 return 1000.0; // To prevent compiler warning.
557 }
558
SetUserStartValue(double startVal,long int index)559 void UIVarsSingleForce::SetUserStartValue(double startVal, long int index)
560 {
561 checkIndexValue(index);
562 bool isinvalid = !GetParamstatus(index).Valid();
563 if (isinvalid)
564 {
565 if (startVal != 0)
566 {
567 string warning = "Warning: " + GetParamName(index) +
568 " ignores any attempt to set the starting value, since it has been set invalid.";
569 GetConstUIVars().GetUI()->AddWarning(warning);
570 }
571 return;
572 }
573 double minval = GetMinStartValue(index);
574 double maxval = GetMaxStartValue(index);
575 assert ((maxval > minval) || isinvalid);
576 if (startVal < minval)
577 {
578 startVal = minval;
579 string warning = "Warning: the minimum value for " + GetParamName(index) +
580 " is " + ToString(minval) + ": setting the starting value there.";
581 GetConstUIVars().GetUI()->AddWarning(warning);
582 }
583 if (startVal > maxval)
584 {
585 startVal = maxval;
586 string warning = "Warning: the maximum value for " + GetParamName(index) +
587 " is " + ToString(maxval) + ": setting the starting value there.";
588 GetConstUIVars().GetUI()->AddWarning(warning);
589 }
590 long int gindex = ParamInGroup(index);
591 if (gindex != FLAGLONG)
592 {
593 for (unsigned long int gpindex = 0; gpindex < m_groups[gindex].second.size(); gpindex++)
594 {
595 long int pindex = m_groups[gindex].second[gpindex];
596 m_userSuppliedStartValues[pindex]=startVal;
597 m_startValueMethodTypes[pindex] = method_USER;
598 }
599 }
600 else
601 {
602 m_userSuppliedStartValues[index]=startVal;
603 m_startValueMethodTypes[index] = method_USER; // don't use SetStartMethod
604 // here -- it can block use
605 // of method_USER since
606 // the UI shouldn't set
607 // method_USER without
608 // going through this method
609 }
610 }
611
SetUserStartValues(double startVal)612 void UIVarsSingleForce::SetUserStartValues(double startVal)
613 {
614 for (int pindex = 0; pindex < GetNumParameters(); pindex++)
615 {
616 if (!GetParamstatus(pindex).Valid())
617 {
618 SetUserStartValue(startVal,pindex);
619 }
620 }
621 }
622
GetStartMethod(long int index) const623 method_type UIVarsSingleForce::GetStartMethod(long int index) const
624 {
625 checkIndexValue(index);
626 return m_startValueMethodTypes[index];
627 }
628
SetTrueValue(double trueVal,long int index)629 void UIVarsSingleForce::SetTrueValue(double trueVal, long int index)
630 {
631 checkIndexValue(index);
632 if (!GetParamstatus(index).Valid())
633 {
634 if (trueVal != 0)
635 {
636 string warning = "Warning: " + GetParamName(index) +
637 " ignores any attempt to set the starting value, since it has been set invalid.";
638 GetConstUIVars().GetUI()->AddWarning(warning);
639 }
640 return;
641 }
642 if (m_truevalues.empty())
643 {
644 m_truevalues.resize(GetNumParameters());
645 }
646 m_truevalues[index] = trueVal;
647 }
648
GetTrueValue(long int index) const649 double UIVarsSingleForce::GetTrueValue(long int index) const
650 {
651 checkIndexValue(index);
652 if (m_truevalues.empty()) return FLAGDOUBLE; // JDEBUG
653 else return m_truevalues[index];
654 }
655
GetPrior(long int pindex) const656 const UIVarsPrior& UIVarsSingleForce::GetPrior(long int pindex) const
657 {
658 if (pindex == uiconst::GLOBAL_ID)
659 {
660 return m_defaultPrior;
661 }
662 checkIndexValue(pindex);
663 if (GetUseDefaultPrior(pindex))
664 {
665 return m_defaultPrior;
666 }
667 return m_priors[pindex];
668 };
669
GetPriorType(long int pindex) const670 priortype UIVarsSingleForce::GetPriorType(long int pindex) const
671 {
672 checkIndexValue(pindex);
673 return GetPrior(pindex).GetPriorType();
674 };
675
GetLowerBound(long int pindex) const676 double UIVarsSingleForce::GetLowerBound(long int pindex) const
677 {
678 checkIndexValue(pindex);
679 return GetPrior(pindex).GetLowerBound();
680 };
681
GetUpperBound(long int pindex) const682 double UIVarsSingleForce::GetUpperBound(long int pindex) const
683 {
684 checkIndexValue(pindex);
685 return GetPrior(pindex).GetUpperBound();
686 };
687
688 #ifdef LAMARC_NEW_FEATURE_RELATIVE_SAMPLING
GetRelativeSampling(long int pindex) const689 long UIVarsSingleForce::GetRelativeSampling(long int pindex) const
690 {
691 checkIndexValue(pindex);
692 return GetPrior(pindex).GetRelativeSampling();
693 };
694 #endif
695
SetPriorType(priortype ptype,long int pindex)696 void UIVarsSingleForce::SetPriorType(priortype ptype, long int pindex)
697 {
698 checkIndexValue(pindex);
699 long int gindex = ParamInGroup(pindex);
700 if (gindex == FLAGLONG)
701 {
702 SetUngroupedPriorType(ptype, pindex);
703 }
704 else for (unsigned long int gpindex = 0; gpindex < m_groups[gindex].second.size(); gpindex++)
705 {
706 SetUngroupedPriorType(ptype, m_groups[gindex].second[gpindex]);
707 }
708 }
709
SetUngroupedPriorType(priortype ptype,long int pindex)710 void UIVarsSingleForce::SetUngroupedPriorType(priortype ptype, long int pindex)
711 {
712 if (GetUseDefaultPrior(pindex))
713 {
714 m_useDefaultPrior[pindex] = false;
715 m_priors[pindex] = m_defaultPrior;
716 }
717 m_priors[pindex].SetPriorType(ptype);
718 }
719
720 #ifdef LAMARC_NEW_FEATURE_RELATIVE_SAMPLING
SetRelativeSampling(long rate,long int pindex)721 void UIVarsSingleForce::SetRelativeSampling(long rate, long int pindex)
722 {
723 checkIndexValue(pindex);
724 long int gindex = ParamInGroup(pindex);
725 if (gindex == FLAGLONG)
726 {
727 SetUngroupedRelativeSampling(rate, pindex);
728 }
729 else
730 for (unsigned long int gpindex = 0; gpindex < m_groups[gindex].second.size(); gpindex++)
731 {
732 SetUngroupedRelativeSampling(rate, m_groups[gindex].second[gpindex]);
733 }
734 }
735
SetUngroupedRelativeSampling(long rate,long int pindex)736 void UIVarsSingleForce::SetUngroupedRelativeSampling(long rate, long int pindex)
737 {
738 checkIndexValue(pindex);
739 if (GetUseDefaultPrior(pindex))
740 {
741 m_useDefaultPrior[pindex] = false;
742 m_priors[pindex] = m_defaultPrior;
743 }
744 m_priors[pindex].SetRelativeSampling(rate);
745 }
746
747 #endif
748
SetLowerBound(double bound,long int pindex)749 void UIVarsSingleForce::SetLowerBound(double bound, long int pindex)
750 {
751 checkIndexValue(pindex);
752 long int gindex = ParamInGroup(pindex);
753 if (gindex == FLAGLONG)
754 {
755 SetUngroupedLowerBound(bound, pindex);
756 }
757 else
758 for (unsigned long int gpindex = 0; gpindex < m_groups[gindex].second.size(); gpindex++)
759 {
760 SetUngroupedLowerBound(bound, m_groups[gindex].second[gpindex]);
761 }
762 }
763
SetUngroupedLowerBound(double bound,long int pindex)764 void UIVarsSingleForce::SetUngroupedLowerBound(double bound, long int pindex)
765 {
766 checkIndexValue(pindex);
767 if (GetUseDefaultPrior(pindex))
768 {
769 m_useDefaultPrior[pindex] = false;
770 m_priors[pindex] = m_defaultPrior;
771 }
772 m_priors[pindex].SetLowerBound(bound);
773 }
774
SetUpperBound(double bound,long int pindex)775 void UIVarsSingleForce::SetUpperBound(double bound, long int pindex)
776 {
777 checkIndexValue(pindex);
778 long int gindex = ParamInGroup(pindex);
779 if (gindex == FLAGLONG)
780 {
781 SetUngroupedUpperBound(bound, pindex);
782 }
783 else for (unsigned long int gpindex = 0; gpindex < m_groups[gindex].second.size(); gpindex++)
784 {
785 SetUngroupedUpperBound(bound, m_groups[gindex].second[gpindex]);
786 }
787 }
788
SetUngroupedUpperBound(double bound,long int pindex)789 void UIVarsSingleForce::SetUngroupedUpperBound(double bound, long int pindex)
790 {
791 checkIndexValue(pindex);
792 if (GetUseDefaultPrior(pindex))
793 {
794 m_useDefaultPrior[pindex] = false;
795 m_priors[pindex] = m_defaultPrior;
796 }
797 m_priors[pindex].SetUpperBound(bound);
798 }
799
800 //------------------------------------------------------------------------------------
801
GetDefaultPrior() const802 const UIVarsPrior& UIVarsSingleForce::GetDefaultPrior() const
803 {
804 return m_defaultPrior;
805 };
806
GetUseDefaultPrior(long int pindex) const807 bool UIVarsSingleForce::GetUseDefaultPrior(long int pindex) const
808 {
809 checkIndexValue(pindex);
810 return m_useDefaultPrior[pindex];
811 };
812
GetDefaultPriorType() const813 priortype UIVarsSingleForce::GetDefaultPriorType() const
814 {
815 return m_defaultPrior.GetPriorType();
816 };
817
GetDefaultLowerBound() const818 double UIVarsSingleForce::GetDefaultLowerBound() const
819 {
820 return m_defaultPrior.GetLowerBound();
821 };
822
GetDefaultUpperBound() const823 double UIVarsSingleForce::GetDefaultUpperBound() const
824 {
825 return m_defaultPrior.GetUpperBound();
826 };
827
828 #ifdef LAMARC_NEW_FEATURE_RELATIVE_SAMPLING
GetDefaultRelativeSampling() const829 long UIVarsSingleForce::GetDefaultRelativeSampling() const
830 {
831 return m_defaultPrior.GetRelativeSampling();
832 };
833 #endif
834
SetUseDefaultPrior(bool val,long int pindex)835 void UIVarsSingleForce::SetUseDefaultPrior(bool val, long int pindex)
836 {
837 checkIndexValue(pindex);
838 m_useDefaultPrior[pindex] = val;
839 };
840
SetUseAllDefaultPriors()841 void UIVarsSingleForce::SetUseAllDefaultPriors()
842 {
843 for (unsigned long int pindex = 0; pindex < m_useDefaultPrior.size(); pindex++)
844 {
845 m_useDefaultPrior[pindex] = true;
846 }
847 };
848
SetDefaultPriorType(priortype ptype)849 void UIVarsSingleForce::SetDefaultPriorType(priortype ptype)
850 {
851 m_defaultPrior.SetPriorType(ptype);
852 }
853
SetDefaultLowerBound(double bound)854 void UIVarsSingleForce::SetDefaultLowerBound(double bound)
855 {
856 m_defaultPrior.SetLowerBound(bound);
857 }
858
SetDefaultUpperBound(double bound)859 void UIVarsSingleForce::SetDefaultUpperBound(double bound)
860 {
861 m_defaultPrior.SetUpperBound(bound);
862 }
863
864 #ifdef LAMARC_NEW_FEATURE_RELATIVE_SAMPLING
SetDefaultRelativeSampling(long rate)865 void UIVarsSingleForce::SetDefaultRelativeSampling(long rate)
866 {
867 m_defaultPrior.SetRelativeSampling(rate);
868 }
869 #endif
870
871 //------------------------------------------------------------------------------------
872
873 void
SetMaxEvents(long int events)874 UIVarsSingleForce::SetMaxEvents(long int events)
875 {
876 if (m_ftype != force_GROW && m_ftype != force_COAL && events <= 0)
877 {
878 throw data_error("The maximum number of events for force " + ToString(m_ftype) + " must be greater than zero.");
879 }
880 m_maxEvents = events;
881 }
882
883 void
SetOnOff(bool onOffVal)884 UIVarsSingleForce::SetOnOff(bool onOffVal)
885 {
886 assert( m_canSetOnOff || ( onOffVal == m_onOff ) );
887 m_onOff = onOffVal;
888 }
889
890 bool
GetParamValid(long int id) const891 UIVarsSingleForce::GetParamValid(long int id) const
892 {
893 return (GetOnOff() && (id >= 0) && (id < m_numParameters));
894 }
895
896 bool
GetParamUnique(long int id) const897 UIVarsSingleForce::GetParamUnique(long int id) const
898 {
899 long int gindex = ParamInGroup(id);
900 if (gindex == FLAGLONG) return true;
901 if (m_groups[gindex].second[0] == id) return true;
902 return false;
903 }
904
SomeVariableParams() const905 bool UIVarsSingleForce::SomeVariableParams() const
906 {
907 for (long int pnum = 0; pnum < m_numParameters; pnum++)
908 {
909 if (GetParamstatus(pnum).Varies()) return true;
910 }
911 return false; // nothing ever varied
912 }
913
AddGroup(ParamStatus mystatus,LongVec1d indices)914 void UIVarsSingleForce::AddGroup(ParamStatus mystatus, LongVec1d indices)
915 {
916 assert(indices.size() > 1);
917
918 //Make a new ParamGroup and put it into m_groups. Don't just put 'indices'
919 // into it because we need to check each entry in it.
920 LongVec1d blanklist;
921 ParamGroup newgroup = make_pair(mystatus,blanklist);
922 m_groups.push_back(newgroup);
923 long int gindex = m_groups.size()-1; //<-OK because we just added one.
924
925 //AddGroup is at the interface between the user and the program, whether
926 // through the menu or through the XML. As such, the indexes used start
927 // at one instead of zero--this is where that is changed for the program.
928 for (unsigned long int vecindex = 0; vecindex < indices.size(); vecindex++)
929 {
930 AddParamToGroup(indices[vecindex] - 1, gindex);
931 }
932 }
933
AddParamToGroup(long int pindex,long int gindex)934 void UIVarsSingleForce::AddParamToGroup(long int pindex, long int gindex)
935 {
936 checkGIndexValue(gindex);
937 checkIndexValue(pindex);
938 if (ParamInGroup(pindex) != FLAGLONG)
939 {
940 string e = "Invalid parameter indexes in group constraints for force "
941 + ToString(m_ftype)
942 + ": The same parameter index is included in more than one group.";
943 throw data_error(e);
944 }
945 if (m_groups[gindex].second.size() > 0)
946 {
947 //copy the prior to the new parameter.
948 long int onegroupparam = m_groups[gindex].second[0];
949 m_useDefaultPrior[pindex] = m_useDefaultPrior[onegroupparam];
950 m_priors[pindex] = m_priors[onegroupparam];
951 }
952 m_groups[gindex].second.push_back(pindex);
953 std::sort(m_groups[gindex].second.begin(), m_groups[gindex].second.end());
954 }
955
AddParamToNewGroup(long int pindex)956 void UIVarsSingleForce::AddParamToNewGroup(long int pindex)
957 {
958 checkIndexValue(pindex);
959 if (ParamInGroup(pindex) != FLAGLONG)
960 {
961 throw data_error("Cannot add a parameter to a new group because it is already in a group.");
962 }
963 LongVec1d pindices;
964 pindices.push_back(pindex);
965 ParamGroup newgroup = make_pair(defaults::groupPstat, pindices);
966 m_groups.push_back(newgroup);
967 }
968
RemoveParamIfInAGroup(long int pindex)969 void UIVarsSingleForce::RemoveParamIfInAGroup(long int pindex)
970 {
971 long int gnum = ParamInGroup(pindex);
972 if (gnum != FLAGLONG)
973 {
974 for (vector<long int>::iterator gpindex = m_groups[gnum].second.begin();
975 gpindex != m_groups[gnum].second.end(); )
976 {
977 if ((*gpindex) == pindex)
978 {
979 ParamStatus old_pstat = GetGroupParamstatus(gnum);
980 gpindex = m_groups[gnum].second.erase(gpindex);
981 if (m_groups[gnum].second.size() == 0)
982 {
983 //Delete the group--it's empty.
984 m_groups.erase(m_groups.begin() + gnum);
985 }
986 if (old_pstat.Grouped())
987 {
988 SetParamstatus(ParamStatus(pstat_unconstrained), pindex);
989 }
990 else
991 {
992 SetParamstatus(old_pstat, pindex);
993 }
994 return;
995 }
996 else
997 {
998 gpindex++;
999 }
1000 }
1001 }
1002 }
1003
SetGroupParamstatus(ParamStatus pstat,long int gindex)1004 void UIVarsSingleForce::SetGroupParamstatus(ParamStatus pstat, long int gindex)
1005 {
1006 // MDEBUG not correct for multiplicative!
1007 if (pstat.Status() == pstat_unconstrained)
1008 {
1009 pstat = ParamStatus(pstat_identical);
1010 GetConstUIVars().GetUI()->AddWarning("Warning: Groups may not be set 'unconstrained'; setting to 'identical' instead.");
1011 }
1012 checkGIndexValue(gindex);
1013 m_groups[gindex].first = pstat;
1014 }
1015
GetGroupParamstatus(long int gindex) const1016 ParamStatus UIVarsSingleForce::GetGroupParamstatus(long int gindex) const
1017 {
1018 checkGIndexValue(gindex);
1019 return m_groups[gindex].first;
1020 }
1021
GetGroupParamList(long int gindex) const1022 LongVec1d UIVarsSingleForce::GetGroupParamList(long int gindex) const
1023 {
1024 checkGIndexValue(gindex);
1025 return m_groups[gindex].second;
1026 }
1027
ParamInGroup(long int pindex) const1028 long int UIVarsSingleForce::ParamInGroup(long int pindex) const
1029 {
1030 checkIndexValue(pindex);
1031 for (long int gindex = 0; gindex < static_cast<long int>(m_groups.size()); gindex++)
1032 {
1033 for (unsigned long int gpindex = 0; gpindex < m_groups[gindex].second.size(); gpindex++)
1034 {
1035 if (pindex == m_groups[gindex].second[gpindex])
1036 {
1037 return static_cast<long int>(gindex);
1038 }
1039 }
1040 }
1041 return FLAGLONG;
1042 }
1043
SetDoProfilesForGroup(bool doIt,long int gindex)1044 void UIVarsSingleForce::SetDoProfilesForGroup(bool doIt, long int gindex)
1045 {
1046 //Since this is a private function that runs from SetDoProfile(), all the
1047 // error checking has already been done, and we need only set the
1048 // appropriate values.
1049 checkGIndexValue(gindex);
1050 for (unsigned long int gpindex = 0; gpindex < m_groups[gindex].second.size(); gpindex++)
1051 {
1052 m_doProfile[m_groups[gindex].second[gpindex]] = doIt;
1053 }
1054 }
1055
checkGIndexValue(long int gindex) const1056 void UIVarsSingleForce::checkGIndexValue(long int gindex) const
1057 {
1058 if (gindex==FLAGLONG) return;
1059 assert (gindex >= 0);
1060 if (gindex<0)
1061 throw data_error("Error: group index value less than zero.");
1062 assert(gindex < static_cast<long int>(m_groups.size()));
1063 if (gindex >= static_cast<long int>(m_groups.size()))
1064 throw data_error("Error: group index value greater than the number of groups.");
1065 }
1066
AreGroupsValid() const1067 bool UIVarsSingleForce::AreGroupsValid() const
1068 {
1069 LongVec1d allpindices;
1070 for (unsigned long int gindex = 0; gindex < m_groups.size(); gindex++)
1071 {
1072 if (m_groups[gindex].second.size() < 2) return false;
1073 allpindices.insert(allpindices.end(), m_groups[gindex].second.begin(), m_groups[gindex].second.end());
1074 }
1075 std::sort(allpindices.begin(), allpindices.end());
1076 for (unsigned long int gpindex=1; gpindex<allpindices.size(); gpindex++)
1077 {
1078 if (allpindices[gpindex] == allpindices[gpindex-1])
1079 return false;
1080 }
1081 return true;
1082 }
1083
FixGroups()1084 void UIVarsSingleForce::FixGroups()
1085 {
1086 //First, we remove any parameter that existed in more than one group. This
1087 // shouldn't ever be the case due to checks in AddParamToGroup, but hey.
1088 // First we have to find them again.
1089 LongVec1d allpindices;
1090 for (unsigned long int gindex = 0; gindex < m_groups.size(); gindex++)
1091 {
1092 allpindices.insert(allpindices.end(), m_groups[gindex].second.begin(), m_groups[gindex].second.end());
1093 }
1094 std::sort(allpindices.begin(), allpindices.end());
1095 for (unsigned long int gpindex=1; gpindex<allpindices.size(); gpindex++)
1096 {
1097 if (allpindices[gpindex] == allpindices[gpindex-1])
1098 {
1099 RemoveParamIfInAGroup(allpindices[gpindex]);
1100 //This removes the param from all groups. It's not the ideal solution,
1101 // and the real solution is to never get in this situation in the first
1102 // place. Which should be covered in AddParamToGroup. So we're set.
1103 }
1104 }
1105
1106 //Now, any parameter status flags that are 'joint' or 'identical' but do
1107 // not correspond with any group are set to 'unconstrained'.
1108 for (long int pindex = 0; pindex < m_numParameters; pindex++)
1109 {
1110 ParamStatus mystatus = GetParamstatus(pindex);
1111 if (mystatus.Grouped())
1112 {
1113 if (ParamInGroup(pindex) == FLAGLONG)
1114 {
1115 SetParamstatus(ParamStatus(pstat_unconstrained), pindex);
1116 }
1117 }
1118 //Also, any truly invalid parameters (i.e. the migration diagonals) may
1119 // not be in a group, nor may they be set to some status other than
1120 // 'invalid'.
1121 if (!GetParamValid(pindex))
1122 {
1123 RemoveParamIfInAGroup(pindex);
1124 SetParamstatus(ParamStatus(pstat_invalid), pindex);
1125 }
1126 }
1127
1128 //Now, any group with only one parameter in it is deleted, setting the
1129 // corresponding ParamStatus appropriately.
1130 for (vector<ParamGroup>::iterator giter = m_groups.begin();
1131 giter != m_groups.end();) // <- iterator incremented below.
1132 {
1133 if ((*giter).second.size() == 0)
1134 {
1135 giter = m_groups.erase(giter);
1136 }
1137 else if ((*giter).second.size() == 1)
1138 {
1139 long int pindex = (*giter).second[0];
1140 ParamStatus mystatus((*giter).first);
1141 if (mystatus.Grouped())
1142 {
1143 SetParamstatus(ParamStatus(pstat_unconstrained), pindex);
1144 }
1145 else
1146 {
1147 SetParamstatus(ParamStatus((*giter).first), pindex);
1148 }
1149 giter = m_groups.erase(giter);
1150 }
1151 else
1152 {
1153 ++giter;
1154 }
1155 }
1156 }
1157
1158 //------------------------------------------------------------------------------------
1159
UIVars2DForce(UIVars * myUIVars,force_type ftype,long int numPartitions,double defaultVal,method_type methodType,bool canBeSetUnset,bool isOn,long int eventMax,UIVarsPrior defaultPrior)1160 UIVars2DForce::UIVars2DForce
1161 ( UIVars * myUIVars,
1162 force_type ftype,
1163 long int numPartitions,
1164 double defaultVal,
1165 method_type methodType,
1166 bool canBeSetUnset,
1167 bool isOn,
1168 long int eventMax,
1169 UIVarsPrior defaultPrior
1170 )
1171 :
1172 UIVarsSingleForce(
1173 myUIVars,
1174 ftype,
1175 numPartitions*numPartitions,
1176 defaultVal,
1177 methodType,
1178 canBeSetUnset, // can't change original on/off setting
1179 isOn,
1180 eventMax,
1181 defaultPrior),
1182 m_npartitions(numPartitions)
1183 {
1184 // EWFIX.P5 DIMENSIONS -- we need the 1D <=> 2D translation objects
1185 //Make the diagonals of the parameter statuses (stati?) invalid.
1186 for (long int diagonal = 1; diagonal <= numPartitions; diagonal++)
1187 {
1188 SetParamstatus(ParamStatus(pstat_invalid), ((diagonal-1)*numPartitions + diagonal)-1);
1189 }
1190 }
1191
UIVars2DForce(UIVars * myUIVars,const UIVars2DForce & twoD)1192 UIVars2DForce::UIVars2DForce
1193 ( UIVars * myUIVars, const UIVars2DForce & twoD )
1194 :
1195 UIVarsSingleForce(myUIVars,twoD),
1196 m_npartitions(twoD.m_npartitions)
1197 {
1198 }
1199
AssertOnIllegalStartMethod(method_type method)1200 void UIVars2DForce::AssertOnIllegalStartMethod(method_type method)
1201 {
1202 assert( (method == method_FST) || (method == method_PROGRAMDEFAULT) );
1203 }
1204
1205 bool
GetParamValid(long int id) const1206 UIVars2DForce::GetParamValid(long int id) const
1207 {
1208 bool possible = UIVarsSingleForce::GetParamValid(id);
1209 if(possible)
1210 {
1211 // NB I believe this means "is it off-diagonal"?
1212 // MDEBUG This may need to be overridden in DivMig, but I don't
1213 // know how as it requires the Epoch structure to determine which
1214 // off-diagonal entries are invalid
1215 const UIVars& vars = GetConstUIVars();
1216 long int numPops = vars.datapackplus.GetNPartitionsByForceType(m_ftype);
1217 long int intoIndex = id / numPops;
1218 long int fromIndex = id % numPops;
1219 return (intoIndex != fromIndex);
1220 }
1221 return false;
1222 }
1223
1224 //AreZeroesValid checks to make sure that we haven't set so many migration
1225 // events to zero (and constant) that we can no longer coalesce. Note that
1226 // setting a parameter to 'pstat_invalid' means that we are setting it to zero
1227 // and constant, too.
1228 //
1229 // This function could make suggestions about what to fix, but it suggestions
1230 // are unlikely to be biologically relevant for the populations involved,
1231 // so it seems better to just force the user to make their own changes, or just
1232 // remove all 0/constant constraints.
1233 //
1234 // If it is to make suggestions, it would need to be non-const.
1235
1236 bool
AreZeroesValid() const1237 UIVars2DForce::AreZeroesValid() const
1238 {
1239 //The goal of this algorithm is to find 'Rome', a mythical land from which
1240 // all of your current populations descended. In a migration system with
1241 // no constraints, all partitions could be Rome, but we only need to find
1242 // one to satisfy our test. If we find at least one Rome, we return true,
1243 // and if not, we return false.
1244 //
1245 // First, we make two lists that will hold partition indexes in them,
1246 // 'reached' and 'unreached'. At the beginning, everything is in
1247 // 'unreached'.
1248
1249 list<long int> reached, unreached;
1250 for (long int partind = 0; partind < m_npartitions; partind++)
1251 unreached.push_back(partind);
1252
1253 // Now we seize a partition at random (0) to see if it's Rome.
1254 long int testRome = 0;
1255
1256 // Now we loop until we return either true or false.
1257 while (true)
1258 {
1259 //First, we don't have to worry about getting to testRome. We also
1260 // don't need to add testRome to 'reached', since that list is only
1261 // used to back away from testRome if need be.
1262 unreached.remove(testRome);
1263
1264 //Check to see who we can get to in 'unreached' from Rome. We only
1265 // test routes that go through the unreached list, since everything in
1266 // the 'reached' list has already been exhaustively searched.
1267 UpdateReachList(testRome, unreached, reached);
1268
1269 //Check to see if we're done.
1270 if (unreached.size() == 0) return true;
1271
1272 //Otherwise, we need a new Rome candidate. If our system is valid, Rome
1273 // *must* be in the 'unreached' group. (If it wasn't, our old testRome
1274 // would have to have also been a valid Rome: If everyone can come from
1275 // Rome by definition, and people in Rome can come from testRome, testRome
1276 // is also a valid 'Rome'.)
1277 testRome = PickANewRome(testRome, unreached, reached);
1278
1279 //If PickANewRome failed, our system is invalid--return false;
1280 if (testRome == FLAGLONG) return false;
1281
1282 //Otherwise, we can go ahead and loop with our new Rome. Before we do,
1283 // though, we can clear out our 'reached' list. We can do this because
1284 // not only do we know that migrants from our new testRome can get to
1285 // everywhere in 'reached', we *also* know that nothing in 'reached' can
1286 // get to 'unreached'--testRome and the other 'unreached' entries are the
1287 // only possibilities left.
1288 //
1289 // So, we clear 'reached'. This has the effect of making our next loop
1290 // still more efficient.
1291 reached.clear();
1292 }
1293 }
1294
UpdateReachList(long int testRome,list<long int> & unreached,list<long int> & reached) const1295 void UIVars2DForce::UpdateReachList(long int testRome, list<long int>& unreached,
1296 list<long int>& reached) const
1297 {
1298 list<long int> oneStepAway;
1299 oneStepAway.push_back(testRome);
1300
1301 while (oneStepAway.size() > 0)
1302 {
1303 list<long int> twoStepsAway;
1304 for (list<long int>::iterator partfrom = oneStepAway.begin();
1305 partfrom != oneStepAway.end(); partfrom++)
1306 {
1307 for (list<long int>::iterator partto = unreached.begin();
1308 partto != unreached.end(); partto++)
1309 {
1310 if (CanReach((*partfrom), (*partto)))
1311 {
1312 twoStepsAway.push_back((*partto));
1313 }
1314 }
1315 }
1316 for (list<long int>::iterator stepit = oneStepAway.begin();
1317 stepit != oneStepAway.end(); stepit++ )
1318 {
1319 reached.push_back((*stepit));
1320 unreached.remove((*stepit));
1321 }
1322 oneStepAway = twoStepsAway;
1323 }
1324 }
1325
PickANewRome(long int oldRome,list<long int> unreached,list<long int> reached) const1326 long int UIVars2DForce::PickANewRome(long int oldRome, list<long int> unreached,
1327 list<long int> reached) const
1328 {
1329 list<long int> intermediates;
1330 intermediates.push_back(oldRome);
1331 reached.remove(oldRome);
1332 while (intermediates.size() > 0)
1333 {
1334 list<long int> newintermediates;
1335 for (list<long int>::iterator partto = intermediates.begin();
1336 partto != intermediates.end(); partto++)
1337 {
1338 //Check to see if we can get to anything in the 'unreached' list.
1339 // If so, that's our new Rome candidate, and we're done.
1340 for (list<long int>::iterator partfrom = unreached.begin();
1341 partfrom != unreached.end(); partfrom++)
1342 {
1343 if (CanReach((*partfrom), (*partto)))
1344 {
1345 return (*partfrom);
1346 }
1347 }
1348 //We didn't get to 'unreached' directly; try going through the 'reached'
1349 // list. If we find anything, we can remove it from 'reached'.
1350 for (list<long int>::iterator partfrom = reached.begin();
1351 partfrom != reached.end();)
1352 {
1353 if (CanReach((*partfrom), (*partto)))
1354 {
1355 newintermediates.push_back(*partfrom);
1356 reached.erase(partfrom++);
1357 }
1358 else
1359 {
1360 partfrom++;
1361 }
1362 }
1363 }
1364 intermediates = newintermediates;
1365 }
1366
1367 //We never found any way to get to oldRome from anything in unreached.
1368 // Hence, our network is invalid.
1369 return FLAGLONG;
1370 }
1371
CanReach(long int partfrom,long int partto) const1372 bool UIVars2DForce::CanReach(long int partfrom, long int partto) const
1373 {
1374 long int pindex = partto*m_npartitions + partfrom;
1375 if (GetParamstatus(pindex).Valid())
1376 {
1377 double pval = GetStartValue(pindex);
1378 // If the start value is zero, the populations are unconnected at least
1379 // for the first tree, and that is a problem even in a Bayesian run.
1380 if (pval == 0.0) return false;
1381 else return true;
1382 }
1383 else
1384 return false;
1385 }
1386
1387 //------------------------------------------------------------------------------------
1388 //------------------------------------------------------------------------------------
1389
UIVarsCoalForce(UIVars * myUIVars,long int numCrossPartitions)1390 UIVarsCoalForce::UIVarsCoalForce(UIVars * myUIVars, long int numCrossPartitions)
1391 : UIVarsSingleForce(
1392 myUIVars,
1393 force_COAL,
1394 numCrossPartitions,
1395 defaults::theta, //
1396 defaults::thetaMethod,
1397 false, // Coal force can't be turned off ever
1398 true, // Coal force always ON
1399 defaults::coalEvents,
1400 UIVarsPrior(myUIVars->GetUI(),
1401 force_COAL,
1402 defaults::priortypeTheta,
1403 #ifdef LAMARC_NEW_FEATURE_RELATIVE_SAMPLING
1404 defaults::samplingRate,
1405 #endif
1406 defaults::lowerboundTheta,
1407 defaults::upperboundTheta)
1408 )
1409 {
1410 }
1411
UIVarsCoalForce(UIVars * myUIVars,const UIVarsCoalForce & coalForce)1412 UIVarsCoalForce::UIVarsCoalForce(UIVars * myUIVars, const UIVarsCoalForce& coalForce)
1413 :
1414 UIVarsSingleForce(myUIVars,coalForce)
1415 {
1416 }
1417
AssertOnIllegalStartMethod(method_type method)1418 void UIVarsCoalForce::AssertOnIllegalStartMethod(method_type method)
1419 {
1420 assert( (method == method_FST) ||
1421 (method == method_WATTERSON) ||
1422 (method == method_PROGRAMDEFAULT));
1423 if ((method==method_FST) && !(GetConstUIVars().forces.GetForceLegal(force_MIG)))
1424 {
1425 throw data_error("The FST method is only available for data sets with more than one population.");
1426 }
1427 }
1428
1429 void
FillCalculatedStartValues()1430 UIVarsCoalForce::FillCalculatedStartValues()
1431 {
1432 // do FST values
1433 if(GetConstUIVars().datapackplus.GetNCrossPartitions() > 1)
1434 {
1435 DoubleVec1d estimates;
1436 std::deque<bool> isCalculated;
1437 const UIVars& vars = GetConstUIVars();
1438 DoubleVec1d regionalthetascalars(vars.datapackplus.GetEffectivePopSizes());
1439 DoubleVec2d regionalmurates(vars.datamodel.GetRelativeMuRates());
1440 ThetaFSTMultiregion(registry.GetDataPack(), regionalthetascalars, regionalmurates, estimates, isCalculated);
1441 m_calculatedStartValues.erase(method_FST);
1442 m_calculatedStartValues.insert(make_pair(method_FST,estimates));
1443
1444 std::set<string> defaultedEstimates;
1445 for (long int pindex = 0; pindex < static_cast<long int>(isCalculated.size()); pindex++)
1446 {
1447 if (!isCalculated[pindex])
1448 {
1449 string name = GetParamName(pindex);
1450 defaultedEstimates.insert(name);
1451 }
1452 }
1453 if (defaultedEstimates.size())
1454 {
1455 std::set<string>::iterator onename;
1456 string warning = "Warning: calculating FST estimates for ";
1457 for (onename = defaultedEstimates.begin(); onename != defaultedEstimates.end(); onename++)
1458 {
1459 warning += "\"" + *onename + "\", ";
1460 }
1461 warning += "is impossible due to the data for the populations involved. If the FST method is invoked to obtain starting values for those parameters, defaults will be used instead.";
1462 GetConstUIVars().GetUI()->AddWarning(warning);
1463 }
1464 }
1465 // do Watterson values
1466 {
1467 DoubleVec1d estimates;
1468 std::deque<bool> isCalculated;
1469 const UIVars& vars = GetConstUIVars();
1470 DoubleVec1d regionalthetascalars(vars.datapackplus.GetEffectivePopSizes());
1471 DoubleVec2d regionalmurates(vars.datamodel.GetRelativeMuRates());
1472 ThetaWattersonMultiregion(registry.GetDataPack(), regionalthetascalars,
1473 regionalmurates, estimates, isCalculated);
1474 m_calculatedStartValues.erase(method_WATTERSON);
1475 m_calculatedStartValues.insert(make_pair(method_WATTERSON,estimates));
1476
1477 std::set<string> defaultedEstimates;
1478 for (long int pindex = 0; pindex < static_cast<long int>(isCalculated.size()); pindex++)
1479 {
1480 if (!isCalculated[pindex])
1481 {
1482 string name = GetParamName(pindex);
1483 defaultedEstimates.insert(name);
1484 }
1485 }
1486 if (defaultedEstimates.size())
1487 {
1488 std::set<string>::iterator onename;
1489 string warning = "Warning: calculating Watterson estimates for ";
1490 for (onename = defaultedEstimates.begin();
1491 onename != defaultedEstimates.end(); onename++)
1492 {
1493 warning += "\"" + *onename + "\", ";
1494 }
1495 warning += "is impossible because one or more genetic regions have no data or only one data point in the corresponding population(s). If the Watterson method is invoked to obtain starting values for theta, defaults will be used in that calculation.";
1496 GetConstUIVars().GetUI()->AddWarning(warning);
1497 }
1498 }
1499 }
1500
1501 bool
AreZeroesValid() const1502 UIVarsCoalForce::AreZeroesValid() const
1503 {
1504 //No force can be invalid or zero for coalescence. It can't even start at
1505 // zero, regardless of whether it's held there.
1506 for (long int pindex = 0; pindex<GetNumParameters(); pindex++)
1507 {
1508 if (!GetParamstatus(pindex).Valid())
1509 {
1510 return false;
1511 }
1512 if (GetStartValue(pindex) == 0.0)
1513 {
1514 return false;
1515 }
1516 }
1517 return true;
1518 }
1519
1520 //------------------------------------------------------------------------------------
1521
UIVarsMigForce(UIVars * myUIVars,long int numPopulations,bool onOrOff)1522 UIVarsMigForce::UIVarsMigForce (UIVars * myUIVars, long int numPopulations, bool onOrOff)
1523 :
1524 UIVars2DForce(
1525 myUIVars,
1526 force_MIG,
1527 numPopulations,
1528 defaults::migration,
1529 defaults::migMethod,
1530 false, // can't change original on/off setting
1531 onOrOff,
1532 defaults::migEvents,
1533 UIVarsPrior(myUIVars->GetUI(),
1534 force_MIG,
1535 defaults::priortypeMig,
1536 #ifdef LAMARC_NEW_FEATURE_RELATIVE_SAMPLING
1537 defaults::samplingRate,
1538 #endif
1539 defaults::lowerboundMig,
1540 defaults::upperboundMig)
1541 )
1542 {
1543 }
1544
UIVarsMigForce(UIVars * myUIVars,const UIVarsMigForce & migForce)1545 UIVarsMigForce::UIVarsMigForce
1546 ( UIVars * myUIVars, const UIVarsMigForce & migForce)
1547 :
1548 UIVars2DForce(myUIVars,migForce)
1549 {
1550 }
1551
1552 void
FillCalculatedStartValues()1553 UIVarsMigForce::FillCalculatedStartValues()
1554 {
1555 DoubleVec1d estimates;
1556 std::deque<bool> isCalculated;
1557 const UIVars& vars = GetConstUIVars();
1558 DoubleVec2d regionalmurates(vars.datamodel.GetRelativeMuRates());
1559 MigFSTMultiregion(registry.GetDataPack(), regionalmurates,
1560 estimates, isCalculated);
1561 m_calculatedStartValues.erase(method_FST);
1562 m_calculatedStartValues.insert(make_pair(method_FST,estimates));
1563
1564 std::set<string> defaultedEstimates;
1565 for (long int pindex = 0; pindex < static_cast<long int>(isCalculated.size()); pindex++)
1566 {
1567 if (!isCalculated[pindex])
1568 {
1569 string name = GetParamName(pindex);
1570 defaultedEstimates.insert(name);
1571 }
1572 }
1573 if (defaultedEstimates.size())
1574 {
1575 std::set<string>::iterator onename;
1576 string warning = uiwarn::calcFST_0;
1577 for (onename = defaultedEstimates.begin(); onename != defaultedEstimates.end(); onename++)
1578 {
1579 warning += "\"" + *onename + "\", ";
1580 }
1581 warning += uiwarn::calcFST_1;
1582 GetConstUIVars().GetUI()->AddWarning(warning);
1583 //LS DEBUG: This warning is always printed out when the user
1584 // first fires up LAMARC, and never afterwards, due to the fact
1585 // that FST is the default starting method for Migration. If
1586 // this changes, the text of this method should probably change,
1587 // too.
1588 }
1589 }
1590
1591 //-------------------------------------------------------------------------------------
1592
UIVarsDivMigForce(UIVars * myUIVars,long int numPopulations,bool onOrOff)1593 UIVarsDivMigForce::UIVarsDivMigForce (UIVars * myUIVars, long int numPopulations, bool onOrOff)
1594 :
1595 UIVars2DForce(
1596 myUIVars,
1597 force_DIVMIG,
1598 numPopulations,
1599 defaults::divMigration,
1600 defaults::divMigMethod,
1601 false, // can't change original on/off setting
1602 onOrOff,
1603 defaults::migEvents,
1604 UIVarsPrior(myUIVars->GetUI(),
1605 force_DIVMIG,
1606 defaults::priortypeDivMig,
1607 #ifdef LAMARC_NEW_FEATURE_RELATIVE_SAMPLING
1608 defaults::samplingRate,
1609 #endif
1610 defaults::lowerboundDivMig,
1611 defaults::upperboundDivMig)
1612 )
1613 {
1614 }
1615
UIVarsDivMigForce(UIVars * myUIVars,const UIVarsDivMigForce & divmigForce)1616 UIVarsDivMigForce::UIVarsDivMigForce
1617 ( UIVars * myUIVars, const UIVarsDivMigForce & divmigForce)
1618 :
1619 UIVars2DForce(myUIVars,divmigForce)
1620 {
1621 }
1622
AssertOnIllegalStartMethod(method_type method)1623 void UIVarsDivMigForce::AssertOnIllegalStartMethod(method_type method)
1624 {
1625 assert(method == method_PROGRAMDEFAULT); // can't use FST here
1626 }
1627
1628 //------------------------------------------------------------------------------------
1629 //------------------------------------------------------------------------------------
1630
UIVarsDivergenceForce(UIVars * myUIVars,long int nDivPopulations)1631 UIVarsDivergenceForce::UIVarsDivergenceForce(UIVars * myUIVars, long int nDivPopulations)
1632 : UIVarsSingleForce(
1633 myUIVars,
1634 force_DIVERGENCE,
1635 (nDivPopulations-1)/2, // truncation deliberate
1636 defaults::epochtime,
1637 defaults::divMethod,
1638 // MDEBUG not sure about the values of these two bools
1639 true, // Divergence force can't be turned off ever
1640 false, // Divergence force always ON
1641 defaults::epochEvents,
1642 UIVarsPrior(myUIVars->GetUI(),
1643 force_DIVERGENCE,
1644 defaults::priortypeEpoch,
1645 #ifdef LAMARC_NEW_FEATURE_RELATIVE_SAMPLING
1646 defaults::samplingRate,
1647 #endif
1648 defaults::lowerboundEpoch,
1649 defaults::upperboundEpoch)
1650 )
1651 {
1652 // the Divergence parameters, which are epoch times, must be specially marked
1653 long i;
1654 for (i = 0; i < (nDivPopulations-1)/2; ++i)
1655 {
1656 // JDEBUG, need to do something here? MakeParamAnEpochTime(i);
1657 }
1658 }
1659
UIVarsDivergenceForce(UIVars * myUIVars,const UIVarsDivergenceForce & divForce)1660 UIVarsDivergenceForce::UIVarsDivergenceForce(UIVars * myUIVars, const UIVarsDivergenceForce& divForce)
1661 :
1662 UIVarsSingleForce(myUIVars,divForce)
1663 {
1664 // copy epoch info
1665 newpops = divForce.newpops;
1666 ancestors = divForce.ancestors;
1667 }
1668
AssertOnIllegalStartMethod(method_type method)1669 void UIVarsDivergenceForce::AssertOnIllegalStartMethod(method_type method)
1670 {
1671 assert (method == method_PROGRAMDEFAULT);
1672 }
1673
1674 bool
AreZeroesValid() const1675 UIVarsDivergenceForce::AreZeroesValid() const
1676 {
1677 //No parameter can be invalid or zero for divergence. It can't even start at
1678 // zero, regardless of whether it's held there.
1679 for (long int pindex = 0; pindex<GetNumParameters(); pindex++)
1680 {
1681 if (!GetParamstatus(pindex).Valid())
1682 {
1683 return false;
1684 }
1685 if (GetStartValue(pindex) == 0.0)
1686 {
1687 return false;
1688 }
1689 }
1690 return true;
1691 }
1692
1693 void
AddNewPops(const vector<string> & newp)1694 UIVarsDivergenceForce::AddNewPops(const vector<string>& newp)
1695 {
1696 newpops.push_back(newp);
1697 }
1698
1699 void
AddAncestor(const string & anc)1700 UIVarsDivergenceForce::AddAncestor(const string& anc)
1701 {
1702 ancestors.push_back(anc);
1703 }
1704
1705 vector<vector<string> >
GetNewPops() const1706 UIVarsDivergenceForce::GetNewPops() const
1707 {
1708 return newpops;
1709 }
1710
1711 vector<string>
GetAncestors() const1712 UIVarsDivergenceForce::GetAncestors () const
1713 {
1714 return ancestors;
1715 }
1716
1717 string
GetAncestor(long index) const1718 UIVarsDivergenceForce::GetAncestor (long index) const
1719 {
1720 return ancestors[index];
1721 }
1722
1723 //------------------------------------------------------------------------------------
1724
UIVarsDiseaseForce(UIVars * myUIVars,long int numDiseaseStates,bool isLegal)1725 UIVarsDiseaseForce::UIVarsDiseaseForce(
1726 UIVars * myUIVars,
1727 long int numDiseaseStates,
1728 bool isLegal)
1729 :
1730 UIVars2DForce(
1731 myUIVars,
1732 force_DISEASE,
1733 numDiseaseStates,
1734 defaults::disease,
1735 defaults::diseaseMethod,
1736 false, // EWFIX.P5 DISEASE change false => isLegal later
1737 // when we figure out how to accomodate
1738 // change in number of theta and growth
1739 // params when disease forces are turned
1740 // on and off in the menu
1741 isLegal,
1742 defaults::diseaseEvents,
1743 UIVarsPrior(myUIVars->GetUI(),
1744 force_DISEASE,
1745 defaults::priortypeDisease,
1746 #ifdef LAMARC_NEW_FEATURE_RELATIVE_SAMPLING
1747 defaults::samplingRate,
1748 #endif
1749 defaults::lowerboundDisease,
1750 defaults::upperboundDisease)
1751 ),
1752 location(defaults::diseaseLocation)
1753 {
1754 //LS NOTE: When we get multiple diseases states in, this is the place to
1755 // set up the invalid and identical parameters (re: the tic-tac-toe setup
1756 // we talked about on Joe's blackboard)
1757 //
1758 /* For example: say we have two traits, Aa, and XYZ. You can set things up:
1759
1760 AX AY AZ aX aY aZ
1761 AX -- ++ ++ ++ -- --
1762 AY ++ -- ++ -- ++ --
1763 AZ ++ ++ -- -- -- ++
1764
1765 aX ++ -- -- -- ++ ++
1766 aY -- ++ -- ++ -- ++
1767 aZ -- -- ++ ++ ++ --
1768
1769 So all the ++'s are possible, and all the --'s are set 'invalid', like the
1770 diagonal. Additionally, if A->a is constant, and not influenced by
1771 the current XYZ, you can set AX->aX, AY->aY, and AZ->aZ to be equal to
1772 each other, and likewise for the other sets of rates.
1773 */
1774 }
1775
UIVarsDiseaseForce(UIVars * myUIVars,const UIVarsDiseaseForce & diseaseForce)1776 UIVarsDiseaseForce::UIVarsDiseaseForce
1777 ( UIVars * myUIVars, const UIVarsDiseaseForce & diseaseForce)
1778 :
1779 UIVars2DForce(myUIVars,diseaseForce),
1780 location(diseaseForce.location)
1781 {
1782 }
1783
1784 //------------------------------------------------------------------------------------
1785
UIVarsRecForce(UIVars * myUIVars,bool canTurnOn)1786 UIVarsRecForce::UIVarsRecForce(UIVars * myUIVars, bool canTurnOn)
1787 :
1788 UIVarsSingleForce(
1789 myUIVars,
1790 force_REC,
1791 1L, // only one param value for recombine
1792 defaults::recombinationRate,
1793 defaults::recMethod,
1794 canTurnOn, // recombine illegal for unlinked data
1795 false, // recombine force not required when possible
1796 defaults::recEvents,
1797 UIVarsPrior(myUIVars->GetUI(),
1798 force_REC,
1799 defaults::priortypeRec,
1800 #ifdef LAMARC_NEW_FEATURE_RELATIVE_SAMPLING
1801 defaults::samplingRate,
1802 #endif
1803 defaults::lowerboundRec,
1804 defaults::upperboundRec)
1805 )
1806 {
1807 }
1808
UIVarsRecForce(UIVars * myUIVars,const UIVarsRecForce & recForce)1809 UIVarsRecForce::UIVarsRecForce(UIVars * myUIVars, const UIVarsRecForce& recForce)
1810 :
1811 UIVarsSingleForce(myUIVars,recForce)
1812 {
1813 }
1814
1815 bool
AreZeroesValid() const1816 UIVarsRecForce::AreZeroesValid() const
1817 {
1818 //Recombination can be zero. You might as well not have it on if so,
1819 // but who are we to quibble? Also, if we allow different populations to
1820 // have different rec values at some point, any of them could be zero.
1821 return true;
1822 }
1823
GetOnOff() const1824 bool UIVarsRecForce::GetOnOff() const
1825 {
1826 if (GetConstUIVars().traitmodels.AnyMappingAnalyses()) return true;
1827 return UIVarsSingleForce::GetOnOff();
1828 }
1829
SetOnOff(bool onOffVal)1830 void UIVarsRecForce::SetOnOff(bool onOffVal)
1831 {
1832 if (GetConstUIVars().traitmodels.AnyMappingAnalyses() && !onOffVal)
1833 {
1834 throw data_error("Cannot turn off recombination when there are traits to be mapped.");
1835 }
1836 if (GetConstUIVars().datapackplus.AnySNPDataWithDefaultLocations() && onOffVal)
1837 {
1838 throw data_error("We cannot accurately estimate recombination as there is SNP data whose locations are unknown. "
1839 "If you want to estimate recombination, go back to the converter and use a map file to tell it where the sequenced SNPs are. "
1840 "See the documentation: the \"Length and Spacing Information with Segment Coordinates\" section in "
1841 "genetic_map.html for how to do this within the GUI converter, or the \"Segments\" section "
1842 "of converter_cmd.html for how to do this using the converter command file.");
1843 }
1844 UIVarsSingleForce::SetOnOff(onOffVal);
1845 }
1846
1847 //------------------------------------------------------------------------------------
1848
UIVarsRegionGammaForce(UIVars * myUIVars)1849 UIVarsRegionGammaForce::UIVarsRegionGammaForce(UIVars * myUIVars)
1850 :
1851 UIVarsSingleForce(
1852 myUIVars,
1853 force_REGION_GAMMA,
1854 1L, // only one param value for region gamma
1855 defaults::gammaOverRegions,
1856 defaults::recMethod,
1857 true, // legal to turn on--ONLY for multi-region data
1858 false, // this "force" is not required
1859 0, // no such thing as region gamma "events"
1860 UIVarsPrior(myUIVars->GetUI(),
1861 force_REC, //BUGBUG!!! no prior allowed!
1862 defaults::priortypeRec, //what to do???
1863 #ifdef LAMARC_NEW_FEATURE_RELATIVE_SAMPLING
1864 defaults::samplingRate,
1865 #endif
1866 defaults::lowerboundRec,
1867 defaults::upperboundRec)
1868 )
1869 {
1870 if (GetConstUIVars().datapackplus.GetNumRegions() == 1)
1871 {
1872 m_canSetOnOff = false;
1873 }
1874 }
1875
UIVarsRegionGammaForce(UIVars * myUIVars,const UIVarsRegionGammaForce & regionGammaForce)1876 UIVarsRegionGammaForce::UIVarsRegionGammaForce(UIVars * myUIVars, const UIVarsRegionGammaForce& regionGammaForce)
1877 :
1878 UIVarsSingleForce(myUIVars,regionGammaForce)
1879 {
1880 }
1881
GetOnOff() const1882 bool UIVarsRegionGammaForce::GetOnOff() const
1883 {
1884 if (GetConstUIVars().datapackplus.GetNumRegions() == 1) return false;
1885 if (GetConstUIVars().chains.GetDoBayesianAnalysis()) return false;
1886 if (GetConstUIVars().forces.GetForceOnOff(force_GROW)) return false;
1887 return UIVarsSingleForce::GetOnOff();
1888 }
1889
1890 void
SetOnOff(bool onOffVal)1891 UIVarsRegionGammaForce::SetOnOff(bool onOffVal)
1892 {
1893 if (GetConstUIVars().datapackplus.GetNumRegions() == 1 && onOffVal)
1894 {
1895 throw data_error("Cannot analyze the region gamma when there is only one region to analyze.");
1896 }
1897 if (GetConstUIVars().chains.GetDoBayesianAnalysis() && onOffVal)
1898 {
1899 throw data_error("Cannot analyze the region gamma during a Bayesian analysis.");
1900 }
1901 if (GetConstUIVars().forces.GetForceOnOff(force_GROW) && onOffVal)
1902 {
1903 throw data_error("Cannot analyze the region gamma if you are simultaneously estimating the growth rate.");
1904 return;
1905 }
1906 UIVarsSingleForce::SetOnOff(onOffVal);
1907 }
1908
1909 bool
AreZeroesValid() const1910 UIVarsRegionGammaForce::AreZeroesValid() const
1911 {
1912 if (!GetParamstatus(0).Valid())
1913 return false;
1914 if (GetStartValue(0) == 0.0)
1915 return false;
1916
1917 return true;
1918 }
1919
1920 //------------------------------------------------------------------------------------
1921
UIVarsGrowForce(UIVars * myUIVars,long int numCrossPartitions)1922 UIVarsGrowForce::UIVarsGrowForce(UIVars * myUIVars, long int numCrossPartitions)
1923 :
1924 UIVarsSingleForce(
1925 myUIVars,
1926 force_GROW,
1927 numCrossPartitions,
1928 defaults::growth,
1929 defaults::growMethod,
1930 true, // growth force always legal to turn on
1931 false, // growth force not required when possible
1932 defaults::growEvents,
1933 UIVarsPrior(myUIVars->GetUI(),
1934 force_GROW,
1935 defaults::priortypeGrowth,
1936 #ifdef LAMARC_NEW_FEATURE_RELATIVE_SAMPLING
1937 defaults::samplingRate,
1938 #endif
1939 defaults::lowerboundGrowth,
1940 defaults::upperboundGrowth)
1941 ),
1942 growthType(defaults::growType)
1943 {
1944 }
1945
UIVarsGrowForce(UIVars * myUIVars,const UIVarsGrowForce & growForce)1946 UIVarsGrowForce::UIVarsGrowForce(UIVars * myUIVars, const UIVarsGrowForce& growForce)
1947 :
1948 UIVarsSingleForce(myUIVars,growForce),
1949 growthType(growForce.growthType)
1950 {
1951 }
1952
1953 bool
AreZeroesValid() const1954 UIVarsGrowForce::AreZeroesValid() const
1955 {
1956 //Any growth can be zero; even up to all of them.
1957 return true;
1958 }
1959
1960 // We don't currently have any STAIRSTEP models, so the case statement
1961 // is probably wrong for when we have them... Jon 2006/09/15
1962 growth_scheme
GetGrowthScheme() const1963 UIVarsGrowForce::GetGrowthScheme() const
1964 {
1965 switch(growthType)
1966 {
1967 case growth_CURVE:
1968 return growth_EXP;
1969 break;
1970 case growth_STICK: // not sure what this case is, assuming
1971 // that we can use the same as STICKEXP for
1972 // now
1973 case growth_STICKEXP:
1974 return growth_EXP;
1975 break;
1976 }
1977 return growth_EXP;
1978 }
1979
1980 void
SetGrowthScheme(growth_scheme g)1981 UIVarsGrowForce::SetGrowthScheme(growth_scheme g)
1982 {
1983 // this is currently a no-op, as soon as we get STAIRSTEP
1984 // we'll need something else, probably ickly complicated here
1985 // in order to account for interlocking nature with growth_type
1986 // management...refactor growth_type? Jon 2006/09/15
1987 }
1988
1989 force_type
GetPhase2Type(force_type f) const1990 UIVarsGrowForce::GetPhase2Type(force_type f) const
1991 {
1992 if (growthType == growth_STICKEXP) return force_EXPGROWSTICK;
1993
1994 return f;
1995 }
1996
1997 //LS NOTE: Cannot have a parallel 'GetOnOff' for growth here that checks
1998 // whether gamma is on or off, because gamma checks if *growth* is on or off.
1999 // If you try it, you'll get an infinite loop. Yes, this has been... verified.
2000
SetOnOff(bool onOffVal)2001 void UIVarsGrowForce::SetOnOff(bool onOffVal)
2002 {
2003 if (GetConstUIVars().forces.GetForceOnOff(force_REGION_GAMMA))
2004 {
2005 throw data_error("Cannot estimate growth if you are simulataneously estimating the region gamma.");
2006 return;
2007 }
2008 UIVarsSingleForce::SetOnOff(onOffVal);
2009 }
2010
2011 //-------------------------------------------------------------
2012
UIVarsLogisticSelectionForce(UIVars * myUIVars,long numCrossPartitions)2013 UIVarsLogisticSelectionForce::UIVarsLogisticSelectionForce
2014 ( UIVars * myUIVars, long numCrossPartitions)
2015 :
2016 UIVarsSingleForce(
2017 myUIVars,
2018 force_LOGISTICSELECTION,
2019 1, // there's only one selection coefficient
2020 defaults::logisticSelection,
2021 defaults::lselectMethod,
2022 true, // always legal to turn on
2023 false, // but it's not required
2024 defaults::lselectEvents,
2025 UIVarsPrior(myUIVars->GetUI(),
2026 force_LOGISTICSELECTION,
2027 defaults::priortypeLSelect,
2028 #ifdef LAMARC_NEW_FEATURE_RELATIVE_SAMPLING
2029 defaults::samplingRate,
2030 #endif
2031 defaults::lowerboundLSelect,
2032 defaults::upperboundLSelect)
2033 )
2034 ,selectionType(defaults::selectionType) // MCHECK major allele freq here?
2035 {
2036 if (2 != numCrossPartitions)
2037 m_canSetOnOff = false;
2038 }
2039
UIVarsLogisticSelectionForce(UIVars * myUIVars,const UIVarsLogisticSelectionForce & logisticSelectionForce)2040 UIVarsLogisticSelectionForce::UIVarsLogisticSelectionForce(UIVars * myUIVars,
2041 const UIVarsLogisticSelectionForce& logisticSelectionForce) :
2042 UIVarsSingleForce(myUIVars, logisticSelectionForce)
2043 {
2044 }
2045
2046 bool
AreZeroesValid() const2047 UIVarsLogisticSelectionForce::AreZeroesValid() const
2048 {
2049 // Sure; zero means selection isn't acting.
2050 return true;
2051 }
2052
2053 force_type
GetPhase2Type(force_type f) const2054 UIVarsLogisticSelectionForce::GetPhase2Type(force_type f) const
2055 {
2056 if (selectionType == selection_STOCHASTIC) return force_LOGSELECTSTICK;
2057
2058 return f;
2059 }
2060
2061 //-------------------------------------------------------------
2062
2063 bool
operator ()(force_type ft) const2064 UIVarsForces::IsInactive::operator()(force_type ft) const
2065 {
2066 const UIVarsSingleForce & theForce
2067 = m_vars_forces.getForceRegardlessOfLegality(ft);
2068 bool isInactive = !(theForce.GetOnOff());
2069 return isInactive;
2070 }
2071
IsInactive(const UIVarsForces & vars_forces)2072 UIVarsForces::IsInactive::IsInactive(const UIVarsForces& vars_forces)
2073 : m_vars_forces(vars_forces)
2074 {
2075 }
2076
~IsInactive()2077 UIVarsForces::IsInactive::~IsInactive()
2078 {
2079 }
2080
2081 bool
operator ()(force_type ft) const2082 UIVarsForces::IsIllegal::operator()(force_type ft) const
2083 {
2084 const UIVarsSingleForce & theForce
2085 = m_vars_forces.getForceRegardlessOfLegality(ft);
2086 bool isIllegal = (!theForce.GetLegal());
2087 return isIllegal;
2088 }
2089
IsIllegal(const UIVarsForces & vars_forces)2090 UIVarsForces::IsIllegal::IsIllegal(const UIVarsForces& vars_forces)
2091 : m_vars_forces(vars_forces)
2092 {
2093 }
2094
~IsIllegal()2095 UIVarsForces::IsIllegal::~IsIllegal()
2096 {
2097 }
2098
UIVarsForces(UIVars * myUIVars,long int nCrossPartitions,long int nMigPopulations,long int nDivPopulations,long int nDiseaseStates,bool canMeasureRecombination)2099 UIVarsForces::UIVarsForces(UIVars * myUIVars,long int nCrossPartitions, long int nMigPopulations,
2100 long int nDivPopulations, long int nDiseaseStates,bool canMeasureRecombination)
2101 :
2102 UIVarsComponent(myUIVars),
2103 coalForce(myUIVars,nCrossPartitions),
2104 diseaseForce(myUIVars,nDiseaseStates,(nDiseaseStates >= 2)),
2105 growForce(myUIVars,nCrossPartitions),
2106 migForce(myUIVars,nMigPopulations,(nMigPopulations >= 2)),
2107 divMigForce(myUIVars,nDivPopulations,(nDivPopulations > 2)),
2108 divForce(myUIVars,nDivPopulations), // yes, integer division with truncation is desired
2109 recForce(myUIVars,canMeasureRecombination),
2110 regionGammaForce(myUIVars),
2111 logisticSelectionForce(myUIVars,nCrossPartitions)
2112 {
2113 //requires that both datapackplus and datamodel be set up in uivars.
2114 FillCalculatedStartValues();
2115 }
2116
UIVarsForces(UIVars * myUIVars,const UIVarsForces & forcesRef)2117 UIVarsForces::UIVarsForces(UIVars * myUIVars, const UIVarsForces& forcesRef)
2118 :
2119 UIVarsComponent(myUIVars),
2120 coalForce(myUIVars,forcesRef.coalForce),
2121 diseaseForce(myUIVars,forcesRef.diseaseForce),
2122 growForce(myUIVars,forcesRef.growForce),
2123 migForce(myUIVars,forcesRef.migForce),
2124 divMigForce(myUIVars,forcesRef.divMigForce),
2125 divForce(myUIVars,forcesRef.divForce),
2126 recForce(myUIVars,forcesRef.recForce),
2127 regionGammaForce(myUIVars,forcesRef.regionGammaForce),
2128 logisticSelectionForce(myUIVars,forcesRef.logisticSelectionForce)
2129 {
2130 }
2131
~UIVarsForces()2132 UIVarsForces::~UIVarsForces()
2133 {
2134 }
2135
2136 void
FillCalculatedStartValues()2137 UIVarsForces::FillCalculatedStartValues()
2138 {
2139 coalForce.FillCalculatedStartValues();
2140 migForce.FillCalculatedStartValues();
2141 }
2142
GetForceSizes() const2143 LongVec1d UIVarsForces::GetForceSizes() const
2144 {
2145 LongVec1d retVec;
2146 vector<force_type> forces = GetActiveForces();
2147 for (unsigned long int fnum = 0; fnum < forces.size(); fnum++)
2148 {
2149 retVec.push_back(getLegalForce(forces[fnum]).GetNumParameters());
2150 }
2151 return retVec;
2152 }
2153
2154 ForceTypeVec1d
GetActiveForces() const2155 UIVarsForces::GetActiveForces() const
2156 {
2157 ForceTypeVec1d returnVec = GetLegalForces();
2158 returnVec.erase(
2159 std::remove_if(returnVec.begin(),returnVec.end(),IsInactive(*this)),
2160 returnVec.end());
2161 return returnVec;
2162 }
2163
2164 ForceTypeVec1d
GetPhase2ActiveForces() const2165 UIVarsForces::GetPhase2ActiveForces() const
2166 {
2167 ForceTypeVec1d tempVec = GetActiveForces();
2168 ForceTypeVec1d returnVec;
2169 for (unsigned long fnum=0; fnum<tempVec.size(); fnum++)
2170 {
2171 returnVec.push_back(getLegalForce(tempVec[fnum]).GetPhase2Type(tempVec[fnum]));
2172 }
2173 return returnVec;
2174 }
2175
2176 ForceTypeVec1d
GetLegalForces() const2177 UIVarsForces::GetLegalForces() const
2178 {
2179 ForceTypeVec1d returnVec = GetPossibleForces();
2180 returnVec.erase(
2181 std::remove_if(returnVec.begin(),returnVec.end(),IsIllegal(*this)),
2182 returnVec.end());
2183 return returnVec;
2184 }
2185
2186 ForceTypeVec1d
GetPossibleForces() const2187 UIVarsForces::GetPossibleForces() const
2188 {
2189 //This is where the so-called 'canonical order' of forces in LAMARC
2190 // gets set up. If we add a new force, add it here appropriately.
2191 ForceTypeVec1d returnVec;
2192 returnVec.push_back(force_COAL);
2193 returnVec.push_back(force_MIG);
2194 returnVec.push_back(force_DIVMIG);
2195 returnVec.push_back(force_DISEASE);
2196 returnVec.push_back(force_REC);
2197 returnVec.push_back(force_GROW);
2198 returnVec.push_back(force_DIVERGENCE);
2199 returnVec.push_back(force_LOGISTICSELECTION);
2200 returnVec.push_back(force_REGION_GAMMA);
2201 return returnVec;
2202 }
2203
GetNumGroups(force_type ftype) const2204 long int UIVarsForces::GetNumGroups(force_type ftype) const
2205 {
2206 return getLegalForce(ftype).GetNumGroups();
2207 }
2208
ParamInGroup(force_type ftype,long int pindex) const2209 long int UIVarsForces::ParamInGroup(force_type ftype, long int pindex) const
2210 {
2211 return getLegalForce(ftype).ParamInGroup(pindex);
2212 }
2213
2214 bool
GetForceCanTurnOnOff(force_type ftype) const2215 UIVarsForces::GetForceCanTurnOnOff(force_type ftype) const
2216 {
2217 const UIVarsSingleForce & thisForce = getForceRegardlessOfLegality(ftype);
2218 return thisForce.GetCanSetOnOff();
2219 }
2220
2221 bool
GetForceLegal(force_type ftype) const2222 UIVarsForces::GetForceLegal(force_type ftype) const
2223 {
2224 const UIVarsSingleForce & thisForce = getForceRegardlessOfLegality(ftype);
2225 return thisForce.GetLegal();
2226 }
2227
2228 bool
GetForceZeroesValidity(force_type ftype) const2229 UIVarsForces::GetForceZeroesValidity(force_type ftype) const
2230 {
2231 const UIVarsSingleForce & thisForce = getForceRegardlessOfLegality(ftype);
2232 return thisForce.AreZeroesValid();
2233 }
2234
2235 void
FixGroups(force_type ftype)2236 UIVarsForces::FixGroups(force_type ftype)
2237 {
2238 UIVarsSingleForce & thisForce = getLegalForce(ftype);
2239 thisForce.FixGroups();
2240 }
2241
2242 const UIVarsSingleForce &
getLegalForce(force_type ftype) const2243 UIVarsForces::getLegalForce(force_type ftype) const
2244 {
2245 // if you change this method, make sure you change the
2246 // non-const version and getForceRegardlessOfLegality too!!
2247 switch(ftype)
2248 {
2249 case force_COAL:
2250 assert(coalForce.GetLegal());
2251 return coalForce;
2252 break;
2253 case force_MIG:
2254 assert(migForce.GetLegal());
2255 return migForce;
2256 break;
2257 case force_DIVMIG:
2258 assert(divMigForce.GetLegal());
2259 return divMigForce;
2260 break;
2261 case force_EXPGROWSTICK:
2262 case force_GROW:
2263 assert(growForce.GetLegal());
2264 return growForce;
2265 break;
2266 case force_REC:
2267 assert(recForce.GetLegal());
2268 return recForce;
2269 break;
2270 case force_DISEASE:
2271 assert(diseaseForce.GetLegal());
2272 return diseaseForce;
2273 break;
2274 case force_LOGSELECTSTICK:
2275 case force_LOGISTICSELECTION:
2276 assert(logisticSelectionForce.GetLegal());
2277 return logisticSelectionForce;
2278 break;
2279 case force_REGION_GAMMA:
2280 assert(regionGammaForce.GetLegal());
2281 return regionGammaForce;
2282 break;
2283 case force_DIVERGENCE:
2284 assert(divForce.GetLegal());
2285 return divForce;
2286 break;
2287 default:
2288 assert(false); //Uncaught force type.
2289 }
2290 throw implementation_error("UIVarsForces::getLegalForce(force_type) given an unknown force type.");
2291 }
2292
2293 UIVarsSingleForce &
getLegalForce(force_type ftype)2294 UIVarsForces::getLegalForce(force_type ftype)
2295 {
2296 // if you change this method, make sure you change the
2297 // const version and getForceRegardlessOfLegality too!!
2298 switch(ftype)
2299 {
2300 case force_COAL:
2301 assert(coalForce.GetLegal());
2302 return coalForce;
2303 break;
2304 case force_MIG:
2305 assert(migForce.GetLegal());
2306 return migForce;
2307 break;
2308 case force_DIVMIG:
2309 assert(divMigForce.GetLegal());
2310 return divMigForce;
2311 break;
2312 case force_EXPGROWSTICK:
2313 case force_GROW:
2314 assert(growForce.GetLegal());
2315 return growForce;
2316 break;
2317 case force_REC:
2318 assert(recForce.GetLegal());
2319 return recForce;
2320 break;
2321 case force_DISEASE:
2322 assert(diseaseForce.GetLegal());
2323 return diseaseForce;
2324 break;
2325 case force_LOGSELECTSTICK:
2326 case force_LOGISTICSELECTION:
2327 assert(logisticSelectionForce.GetLegal());
2328 return logisticSelectionForce;
2329 break;
2330 case force_REGION_GAMMA:
2331 assert(regionGammaForce.GetLegal());
2332 return regionGammaForce;
2333 break;
2334 case force_DIVERGENCE:
2335 assert(divForce.GetLegal());
2336 return divForce;
2337 break;
2338 default:
2339 assert(false); //Uncaught force type.
2340 }
2341 throw implementation_error("UIVarsForces::getLegalForce(force_type) given an unknown force type.");
2342 }
2343
2344 const UIVarsSingleForce &
getForceRegardlessOfLegality(force_type ftype) const2345 UIVarsForces::getForceRegardlessOfLegality(force_type ftype) const
2346 {
2347 // if you change this method, make sure you change the
2348 // const and non-const versions of getLegalForce
2349 switch(ftype)
2350 {
2351 case force_COAL:
2352 return coalForce;
2353 break;
2354 case force_MIG:
2355 return migForce;
2356 break;
2357 case force_DIVMIG:
2358 return divMigForce;
2359 break;
2360 case force_EXPGROWSTICK:
2361 case force_GROW:
2362 return growForce;
2363 break;
2364 case force_REC:
2365 return recForce;
2366 break;
2367 case force_DISEASE:
2368 return diseaseForce;
2369 break;
2370 case force_LOGSELECTSTICK:
2371 case force_LOGISTICSELECTION:
2372 return logisticSelectionForce;
2373 break;
2374 case force_REGION_GAMMA:
2375 return regionGammaForce;
2376 break;
2377 case force_DIVERGENCE:
2378 return divForce;
2379 break;
2380 default:
2381 assert(false); //Uncaught force type.
2382 }
2383 throw implementation_error("UIVarsForces::getForceRegardlessOfLegality(force_type) given an unknown force type.");
2384 }
2385
2386 long int
GetNumParameters(force_type force) const2387 UIVarsForces::GetNumParameters(force_type force) const
2388 {
2389 return getLegalForce(force).GetNumParameters();
2390 }
2391
2392 bool
GetForceOnOff(force_type force) const2393 UIVarsForces::GetForceOnOff (force_type force) const
2394 {
2395 const UIVarsSingleForce & thisForce = getForceRegardlessOfLegality(force);
2396 return thisForce.GetOnOff();
2397 }
2398
2399 long int
GetMaxEvents(force_type force) const2400 UIVarsForces::GetMaxEvents (force_type force) const
2401 {
2402 return getLegalForce(force).GetMaxEvents();
2403 }
2404
2405 proftype
GetProfileType(force_type force) const2406 UIVarsForces::GetProfileType (force_type force) const
2407 {
2408 return getLegalForce(force).GetProfileType();
2409 }
2410
2411 proftype
GetProfileType(force_type force,long int id) const2412 UIVarsForces::GetProfileType (force_type force, long int id) const
2413 {
2414 return getLegalForce(force).GetProfileType(id);
2415 }
2416
2417 string
GetProfileTypeSummaryDescription(force_type force) const2418 UIVarsForces::GetProfileTypeSummaryDescription(force_type force) const
2419 {
2420 return getLegalForce(force).GetProfileTypeSummaryDescription();
2421 }
2422
2423 ParamStatus
GetParamstatus(force_type force,long int id) const2424 UIVarsForces::GetParamstatus (force_type force, long int id) const
2425 {
2426 if (id == uiconst::GLOBAL_ID)
2427 {
2428 //LS NOTE: This is called this way from uiParameter::Min and ::Max in force_interface.cpp
2429 return ParamStatus(pstat_unconstrained);
2430 }
2431 return getLegalForce(force).GetParamstatus(id);
2432 }
2433
2434 ParamStatus
GetGroupParamstatus(force_type force,long int id) const2435 UIVarsForces::GetGroupParamstatus (force_type force, long int id) const
2436 {
2437 return getLegalForce(force).GetGroupParamstatus(id);
2438 }
2439
2440 LongVec1d
GetGroupParamList(force_type force,long int id) const2441 UIVarsForces::GetGroupParamList (force_type force, long int id) const
2442 {
2443 return getLegalForce(force).GetGroupParamList(id);
2444 }
2445
2446 // MFIX This looked bad in merge; functions GetIdentGroups and GetMultGroups may
2447 // not be functional or correct.
2448 // JDEBUG -- this is a short term kludge to get something/anything in,
2449 // it is wrong WRONG wrong!
2450 vector<ParamGroup>
GetIdentGroups(force_type force) const2451 UIVarsForces::GetIdentGroups (force_type force) const
2452 {
2453 return getLegalForce(force).GetGroups();
2454 }
2455
2456 // JDEBUG -- this is a short term kludge to get something/anything in,
2457 // it is wrong WRONG wrong!
2458 vector<ParamGroup>
GetMultGroups(force_type force) const2459 UIVarsForces::GetMultGroups (force_type force) const
2460 {
2461 return getLegalForce(force).GetGroups();
2462 }
2463
2464 double
GetStartValue(force_type force,long int id) const2465 UIVarsForces::GetStartValue (force_type force, long int id) const
2466 {
2467 return getLegalForce(force).GetStartValue(id);
2468 }
2469
2470 double
GetTrueValue(force_type force,long int id) const2471 UIVarsForces::GetTrueValue (force_type force, long int id) const
2472 {
2473 return getLegalForce(force).GetTrueValue(id);
2474 }
2475
2476 force_type
GetPhase2Type(force_type force) const2477 UIVarsForces::GetPhase2Type (force_type force) const
2478 {
2479 return getLegalForce(force).GetPhase2Type(force);
2480 }
2481
2482 method_type
GetStartMethod(force_type force,long int id) const2483 UIVarsForces::GetStartMethod (force_type force, long int id) const
2484 {
2485 return getLegalForce(force).GetStartMethod(id);
2486 }
2487
2488 DoubleVec1d
GetStartValues(force_type force) const2489 UIVarsForces::GetStartValues (force_type force) const
2490 {
2491 return getLegalForce(force).GetStartValues();
2492 }
2493
2494 long int
GetDiseaseLocation() const2495 UIVarsForces::GetDiseaseLocation() const
2496 {
2497 assert(diseaseForce.GetLegal());
2498 return diseaseForce.GetLocation();
2499 }
2500
2501 growth_type
GetGrowthType() const2502 UIVarsForces::GetGrowthType() const
2503 {
2504 return growForce.GetGrowthType();
2505 }
2506
2507 growth_scheme
GetGrowthScheme() const2508 UIVarsForces::GetGrowthScheme() const
2509 {
2510 return growForce.GetGrowthScheme();
2511 }
2512
2513 bool
GetDoProfile(force_type force,long int id) const2514 UIVarsForces::GetDoProfile(force_type force, long int id) const
2515 {
2516 return getLegalForce(force).GetDoProfile(id);
2517 }
2518
2519 bool
GetParamValid(force_type force,long int id) const2520 UIVarsForces::GetParamValid(force_type force, long int id) const
2521 {
2522 return getLegalForce(force).GetParamValid(id);
2523 }
2524
2525 bool
GetParamUnique(force_type force,long int id) const2526 UIVarsForces::GetParamUnique(force_type force, long int id) const
2527 {
2528 return getLegalForce(force).GetParamUnique(id);
2529 }
2530
2531 //Getters/setters for Bayesian information
GetPrior(force_type force,long int pindex) const2532 const UIVarsPrior& UIVarsForces::GetPrior(force_type force, long int pindex) const
2533 {
2534 if (pindex == uiconst::GLOBAL_ID)
2535 {
2536 return getLegalForce(force).GetDefaultPrior();
2537 }
2538 return getLegalForce(force).GetPrior(pindex);
2539 }
2540
GetDefaultPrior(force_type force) const2541 const UIVarsPrior& UIVarsForces::GetDefaultPrior(force_type force) const
2542 {
2543 return getLegalForce(force).GetDefaultPrior();
2544 }
2545
GetUseDefaultPrior(force_type force,long int pindex) const2546 bool UIVarsForces::GetUseDefaultPrior(force_type force, long int pindex) const
2547 {
2548 return getLegalForce(force).GetUseDefaultPrior(pindex);
2549 }
2550
GetPriorType(force_type force,long int pindex) const2551 priortype UIVarsForces::GetPriorType(force_type force, long int pindex) const
2552 {
2553 if (pindex == uiconst::GLOBAL_ID)
2554 {
2555 return getLegalForce(force).GetDefaultPriorType();
2556 }
2557 return getLegalForce(force).GetPriorType(pindex);
2558 }
2559
GetLowerBound(force_type force,long int pindex) const2560 double UIVarsForces::GetLowerBound(force_type force, long int pindex) const
2561 {
2562 if (pindex == uiconst::GLOBAL_ID)
2563 {
2564 return getLegalForce(force).GetDefaultLowerBound();
2565 }
2566 return getLegalForce(force).GetLowerBound(pindex);
2567 }
2568
2569 selection_type
GetSelectionType() const2570 UIVarsForces::GetSelectionType() const
2571 {
2572 return logisticSelectionForce.GetSelectionType();
2573 }
2574
GetUpperBound(force_type force,long int pindex) const2575 double UIVarsForces::GetUpperBound(force_type force, long int pindex) const
2576 {
2577 if (pindex == uiconst::GLOBAL_ID)
2578 {
2579 return getLegalForce(force).GetDefaultUpperBound();
2580 }
2581 return getLegalForce(force).GetUpperBound(pindex);
2582 }
2583
2584 #ifdef LAMARC_NEW_FEATURE_RELATIVE_SAMPLING
GetRelativeSampling(force_type force,long int pindex) const2585 long UIVarsForces::GetRelativeSampling(force_type force, long int pindex) const
2586 {
2587 if (pindex == uiconst::GLOBAL_ID)
2588 {
2589 return getLegalForce(force).GetDefaultRelativeSampling();
2590 }
2591 return getLegalForce(force).GetRelativeSampling(pindex);
2592 }
2593 #endif
2594
SetUseDefaultPrior(bool use,force_type force,long int pindex)2595 void UIVarsForces::SetUseDefaultPrior(bool use, force_type force, long int pindex)
2596 {
2597 getLegalForce(force).SetUseDefaultPrior(use, pindex);
2598 }
2599
SetUseDefaultPriorsForForce(force_type force)2600 void UIVarsForces::SetUseDefaultPriorsForForce(force_type force)
2601 {
2602 getLegalForce(force).SetUseAllDefaultPriors();
2603 }
2604
SetPriorType(priortype ptype,force_type force,long int pindex)2605 void UIVarsForces::SetPriorType(priortype ptype, force_type force, long int pindex)
2606 {
2607 if (pindex == uiconst::GLOBAL_ID)
2608 {
2609 getLegalForce(force).SetDefaultPriorType(ptype);
2610 }
2611 else getLegalForce(force).SetPriorType(ptype, pindex);
2612 }
2613
2614 #ifdef LAMARC_NEW_FEATURE_RELATIVE_SAMPLING
SetRelativeSampling(long rate,force_type force,long int pindex)2615 void UIVarsForces::SetRelativeSampling(long rate, force_type force, long int pindex)
2616 {
2617 if (pindex == uiconst::GLOBAL_ID)
2618 {
2619 getLegalForce(force).SetDefaultRelativeSampling(rate);
2620 }
2621 else getLegalForce(force).SetRelativeSampling(rate, pindex);
2622 }
2623 #endif
2624
2625
SetLowerBound(double bound,force_type force,long int pindex)2626 void UIVarsForces::SetLowerBound(double bound, force_type force, long int pindex)
2627 {
2628 if (pindex == uiconst::GLOBAL_ID)
2629 {
2630 getLegalForce(force).SetDefaultLowerBound(bound);
2631 }
2632 else getLegalForce(force).SetLowerBound(bound, pindex);
2633 }
2634
SetUpperBound(double bound,force_type force,long int pindex)2635 void UIVarsForces::SetUpperBound(double bound, force_type force, long int pindex)
2636 {
2637 if (pindex == uiconst::GLOBAL_ID)
2638 {
2639 getLegalForce(force).SetDefaultUpperBound(bound);
2640 }
2641 else getLegalForce(force).SetUpperBound(bound, pindex);
2642 }
2643
GetPriorTypeSummaryDescription(force_type force) const2644 string UIVarsForces::GetPriorTypeSummaryDescription(force_type force) const
2645 {
2646 return getLegalForce(force).GetPriorTypeSummaryDescription();
2647 }
2648
GetPriorTypeSummaryDescription(force_type force,long int pindex,bool sayDefault) const2649 string UIVarsForces::GetPriorTypeSummaryDescription(force_type force, long int pindex, bool sayDefault) const
2650 {
2651 if (pindex != uiconst::GLOBAL_ID)
2652 {
2653 ParamStatus mystatus = getLegalForce(force).GetParamstatus(pindex);
2654 if (!mystatus.Inferred()) return "<" + ToString(mystatus.Status()) + ">";
2655 // otherwise do the stuff below
2656 }
2657 string desc = getLegalForce(force).GetPrior(pindex).GetSummaryDescription();
2658 if (pindex != uiconst::GLOBAL_ID)
2659 {
2660 if (sayDefault)
2661 {
2662 if (getLegalForce(force).GetUseDefaultPrior(pindex))
2663 {
2664 desc = "<default>";
2665 }
2666 }
2667 }
2668 return desc;
2669 }
2670
2671 void
SetForceOnOff(bool onOffVal,force_type force)2672 UIVarsForces::SetForceOnOff (bool onOffVal, force_type force)
2673 {
2674 if(GetForceCanTurnOnOff(force))
2675 {
2676 return getLegalForce(force).SetOnOff(onOffVal);
2677 }
2678 else
2679 {
2680 if (onOffVal != GetForceOnOff(force))
2681 {
2682 assert(false);
2683 string msg;
2684 msg = "Unable to turn ";
2685 if (onOffVal)
2686 {
2687 msg += "on";
2688 }
2689 else
2690 {
2691 msg += "off";
2692 }
2693 msg += " the force " + ToString(force)
2694 + " for this dataset. Try removing the force entirely from the "
2695 "XML input file.";
2696 throw data_error(msg);
2697 }
2698 }
2699 }
2700
2701 void
SetMaxEvents(long int maxEvents,force_type force)2702 UIVarsForces::SetMaxEvents (long int maxEvents, force_type force)
2703 {
2704 return getLegalForce(force).SetMaxEvents(maxEvents);
2705 }
2706
2707 void
SetProfileType(proftype ptype,force_type force)2708 UIVarsForces::SetProfileType (proftype ptype, force_type force)
2709 {
2710 return getLegalForce(force).SetProfileType(ptype);
2711 }
2712
2713 void
SetProfileType(proftype ptype)2714 UIVarsForces::SetProfileType (proftype ptype)
2715 {
2716 // OK, so it's pretty weird to do this for all of the
2717 // forces, since some of them will not be legal, but
2718 // hey, if we're never accessing them, we can certainly
2719 // write to them, huh?
2720 coalForce.SetProfileType(ptype);
2721 diseaseForce.SetProfileType(ptype);
2722 growForce.SetProfileType(ptype);
2723 migForce.SetProfileType(ptype);
2724 recForce.SetProfileType(ptype);
2725 logisticSelectionForce.SetProfileType(ptype);
2726 regionGammaForce.SetProfileType(ptype);
2727 }
2728
2729 void
SetDoProfile(bool doProfile,force_type force,long int id)2730 UIVarsForces::SetDoProfile (bool doProfile, force_type force, long int id)
2731 {
2732 getLegalForce(force).SetDoProfile(doProfile,id);
2733 }
2734
2735 void
SetDoProfile(bool doProfile,force_type force)2736 UIVarsForces::SetDoProfile (bool doProfile, force_type force)
2737 {
2738 getLegalForce(force).SetDoProfile(doProfile);
2739 }
2740
2741 void
SetDoProfile(bool doProfile)2742 UIVarsForces::SetDoProfile (bool doProfile)
2743 {
2744 // OK, so it's pretty wierd to do this for all of the
2745 // forces, since some of them will not be legal, but
2746 // hey, if we're never accessing them, we can certainly
2747 // write to them, huh?
2748 coalForce.SetDoProfile(doProfile);
2749 diseaseForce.SetDoProfile(doProfile);
2750 growForce.SetDoProfile(doProfile);
2751 migForce.SetDoProfile(doProfile);
2752 recForce.SetDoProfile(doProfile);
2753 logisticSelectionForce.SetDoProfile(doProfile);
2754 regionGammaForce.SetDoProfile(doProfile);
2755 }
2756
2757 void
SetStartMethod(method_type meth,force_type ftype,long int id)2758 UIVarsForces::SetStartMethod(method_type meth, force_type ftype, long int id)
2759 {
2760 getLegalForce(ftype).SetStartMethod(meth,id);
2761 }
2762
2763 void
SetParamstatus(const ParamStatus & mystatus,force_type ftype,long int id)2764 UIVarsForces::SetParamstatus (const ParamStatus& mystatus, force_type ftype, long int id)
2765 {
2766 getLegalForce(ftype).SetParamstatus(mystatus,id);
2767 }
2768
2769 void
SetGroupParamstatus(ParamStatus pstat,force_type ftype,long int id)2770 UIVarsForces::SetGroupParamstatus (ParamStatus pstat, force_type ftype, long int id)
2771 {
2772 getLegalForce(ftype).SetGroupParamstatus(pstat,id);
2773 }
2774
2775 void
AddGroup(LongVec1d params,force_type ftype,long int id)2776 UIVarsForces::AddGroup (LongVec1d params, force_type ftype, long int id)
2777 {
2778 getLegalForce(ftype).AddGroup(defaults::groupPstat, params);
2779 }
2780
2781 void
RemoveParamFromGroup(force_type ftype,long int id)2782 UIVarsForces::RemoveParamFromGroup(force_type ftype, long int id)
2783 {
2784 getLegalForce(ftype).RemoveParamIfInAGroup(id);
2785 }
2786
2787 void
AddParamToGroup(force_type ftype,long int pindex,long int gindex)2788 UIVarsForces::AddParamToGroup(force_type ftype, long int pindex, long int gindex)
2789 {
2790 getLegalForce(ftype).AddParamToGroup(pindex, gindex);
2791 }
2792
2793 void
AddParamToNewGroup(force_type ftype,long int pindex)2794 UIVarsForces::AddParamToNewGroup(force_type ftype, long int pindex)
2795 {
2796 getLegalForce(ftype).AddParamToNewGroup(pindex);
2797 }
2798
2799 void
SetUserStartValue(double startValue,force_type ftype,long int id)2800 UIVarsForces::SetUserStartValue(double startValue, force_type ftype, long int id)
2801 {
2802 getLegalForce(ftype).SetUserStartValue(startValue,id);
2803 }
2804
2805 void
SetTrueValue(double startValue,force_type ftype,long int id)2806 UIVarsForces::SetTrueValue(double startValue, force_type ftype, long int id)
2807 {
2808 getLegalForce(ftype).SetTrueValue(startValue,id);
2809 }
2810
2811 void
SetAllThetaStartValues(double startValue)2812 UIVarsForces::SetAllThetaStartValues(double startValue)
2813 {
2814 getLegalForce(force_COAL).SetUserStartValues(startValue);
2815 }
2816
2817 void
SetAllThetaStartValuesFST()2818 UIVarsForces::SetAllThetaStartValuesFST()
2819 {
2820 getLegalForce(force_COAL).SetStartMethods(method_FST);
2821 }
2822
2823 void
SetAllThetaStartValuesWatterson()2824 UIVarsForces::SetAllThetaStartValuesWatterson()
2825 {
2826 getLegalForce(force_COAL).SetStartMethods(method_WATTERSON);
2827 }
2828
2829 void
SetThetaStartValue(double startValue,long int id)2830 UIVarsForces::SetThetaStartValue (double startValue, long int id)
2831 {
2832 getLegalForce(force_COAL).SetUserStartValue(startValue,id);
2833 }
2834
2835 void
SetAllMigrationStartValues(double startValue)2836 UIVarsForces::SetAllMigrationStartValues(double startValue)
2837 {
2838 getLegalForce(force_MIG).SetUserStartValues(startValue);
2839 }
2840
2841 void
SetAllMigrationStartValuesFST()2842 UIVarsForces::SetAllMigrationStartValuesFST()
2843 {
2844 getLegalForce(force_MIG).SetStartMethods(method_FST);
2845 }
2846
2847 void
SetMigrationStartValue(double startValue,long int id)2848 UIVarsForces::SetMigrationStartValue (double startValue, long int id)
2849 {
2850 getLegalForce(force_MIG).SetUserStartValue(startValue,id);
2851 }
2852
2853 void
SetDivergenceEpochStartTime(double startValue,long int id)2854 UIVarsForces::SetDivergenceEpochStartTime (double startValue, long int id)
2855 {
2856 getLegalForce(force_DIVERGENCE).SetUserStartValue(startValue,id);
2857 }
2858
2859 void
SetAllDivMigrationStartValues(double startValue)2860 UIVarsForces::SetAllDivMigrationStartValues(double startValue)
2861 {
2862 getLegalForce(force_DIVMIG).SetUserStartValues(startValue);
2863 }
2864
2865 #if 0 // JREMOVE, JDEBUG, passes testing then remove this function
2866 void
2867 UIVarsForces::SetAllDivMigrationStartValuesFST()
2868 {
2869 assert(false);
2870 getLegalForce(force_DIVMIG).SetStartMethods(method_FST);
2871 }
2872 #endif
2873
2874 void
SetDivMigrationStartValue(double startValue,long int id)2875 UIVarsForces::SetDivMigrationStartValue (double startValue, long int id)
2876 {
2877 getLegalForce(force_DIVMIG).SetUserStartValue(startValue,id);
2878 }
2879
2880 void
SetAllDiseaseStartValues(double startValue)2881 UIVarsForces::SetAllDiseaseStartValues(double startValue)
2882 {
2883 getLegalForce(force_DISEASE).SetUserStartValues(startValue);
2884 }
2885
2886 void
SetDiseaseStartValue(double startValue,long int id)2887 UIVarsForces::SetDiseaseStartValue(double startValue, long int id)
2888 {
2889 getLegalForce(force_DISEASE).SetUserStartValue(startValue,id);
2890 }
2891
2892 void
SetAllGrowthStartValues(double startValue)2893 UIVarsForces::SetAllGrowthStartValues(double startValue)
2894 {
2895 getLegalForce(force_GROW).SetUserStartValues(startValue);
2896 }
2897
2898 void
SetGrowthStartValue(double startValue,long int id)2899 UIVarsForces::SetGrowthStartValue(double startValue, long int id)
2900 {
2901 getLegalForce(force_GROW).SetUserStartValue(startValue,id);
2902 }
2903
2904 void
SetGrowthType(growth_type gType)2905 UIVarsForces::SetGrowthType(growth_type gType)
2906 {
2907 growForce.SetGrowthType(gType);
2908 }
2909
2910 void
SetGrowthScheme(growth_scheme gScheme)2911 UIVarsForces::SetGrowthScheme(growth_scheme gScheme)
2912 {
2913 growForce.SetGrowthScheme(gScheme);
2914 }
2915
2916 void
SetRecombinationStartValue(double startValue)2917 UIVarsForces::SetRecombinationStartValue(double startValue)
2918 {
2919 getLegalForce(force_REC).SetUserStartValues(startValue);
2920 }
2921
2922 void
SetLogisticSelectionCoefficientStartValue(double startValue)2923 UIVarsForces::SetLogisticSelectionCoefficientStartValue(double startValue)
2924 {
2925 getLegalForce(force_LOGISTICSELECTION).SetUserStartValues(startValue);
2926 }
2927
2928 void
SetRegionGammaStartValue(double startValue)2929 UIVarsForces::SetRegionGammaStartValue(double startValue)
2930 {
2931 getLegalForce(force_REGION_GAMMA).SetUserStartValues(startValue);
2932 }
2933
2934 void
SetSelectionType(selection_type sType)2935 UIVarsForces::SetSelectionType(selection_type sType)
2936 {
2937 logisticSelectionForce.SetSelectionType(sType);
2938 }
2939
2940 void
SetDiseaseLocation(long int location)2941 UIVarsForces::SetDiseaseLocation(long int location)
2942 {
2943 assert(diseaseForce.GetLegal());
2944 diseaseForce.SetLocation(location);
2945 }
2946
AreZeroesValid(force_type forceId)2947 bool UIVarsForces::AreZeroesValid(force_type forceId)
2948 {
2949 return getLegalForce(forceId).AreZeroesValid();
2950 }
2951
SomeVariableParams() const2952 bool UIVarsForces::SomeVariableParams() const
2953 {
2954 vector<force_type> forces = GetActiveForces();
2955 for (unsigned long int fnum = 0; fnum < forces.size(); fnum++)
2956 {
2957 if (getLegalForce(forces[fnum]).SomeVariableParams())
2958 {
2959 return true;
2960 }
2961 }
2962 return false;
2963 }
2964
GetEpochAncestorName(long id) const2965 std::string UIVarsForces::GetEpochAncestorName(long id) const
2966 {
2967 assert(divForce.GetLegal());
2968 std::vector<string> names = divForce.GetAncestors();
2969 //std::vector<string> mine = names[id];
2970 std::string retval = names[id];
2971 return retval;
2972 }
2973
GetEpochDescendentNames(long id) const2974 std::string UIVarsForces::GetEpochDescendentNames(long id) const
2975 {
2976 assert(divForce.GetLegal());
2977 std::vector< std::vector <string> > names = divForce.GetNewPops();
2978 std::vector<string> mine = names[id];
2979 std::string retval = mine[0] + " " + mine[1];
2980 return retval;
2981 }
2982
2983 //____________________________________________________________________________________
2984