1 // $Id: ui_vars_chainparams.cpp,v 1.39 2012/05/15 06:21:48 ewalkup 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 
14 #include "defaults.h"
15 #include "timex.h"      // for GetTime()
16 #include "ui_vars.h"
17 
18 //------------------------------------------------------------------------------------
19 
UIVarsChainParameters(UIVars * myUIVars)20 UIVarsChainParameters::UIVarsChainParameters(UIVars * myUIVars)
21     :
22     UIVarsComponent(myUIVars),
23     adaptiveTemperatures            (defaults::useAdaptiveTemperatures),
24     chainTemperatures               (defaults::chainTemperatures()),
25     dropArrangerRelativeTiming      (defaults::dropArrangerTiming),
26     sizeArrangerRelativeTiming      (defaults::sizeArrangerTiming),
27     haplotypeArrangerRelativeTiming (defaults::haplotypeArrangerTiming),
28     probhapArrangerRelativeTiming   (defaults::probhapArrangerTiming),
29     bayesianArrangerRelativeTiming  (FLAGDOUBLE),
30     locusArrangerRelativeTiming     (FLAGDOUBLE),
31     zilchArrangerRelativeTiming     (0.0),
32     stairArrangerRelativeTiming     (0.0),
33     epochSizeArrangerRelativeTiming (0.0),
34     doBayesianAnalysis              (defaults::useBayesianAnalysis),
35     finalChainSamplingInterval      (defaults::finalInterval),
36     finalNumberOfChains             (defaults::finalNChains),
37     finalNumberOfChainsToDiscard    (defaults::finalDiscard),
38     finalNumberOfSamples            (defaults::finalNSamples),
39     initialChainSamplingInterval    (defaults::initInterval),
40     initialNumberOfChains           (defaults::initNChains),
41     initialNumberOfChainsToDiscard  (defaults::initDiscard),
42     initialNumberOfSamples          (defaults::initNSamples),
43     numberOfReplicates              (defaults::replicates),
44     temperatureInterval             (defaults::temperatureInterval)
45 {
46 }
47 
UIVarsChainParameters(UIVars * myUIVars,const UIVarsChainParameters & chainparams)48 UIVarsChainParameters::UIVarsChainParameters(UIVars * myUIVars, const UIVarsChainParameters& chainparams)
49     : UIVarsComponent(myUIVars),
50       adaptiveTemperatures            (chainparams.adaptiveTemperatures),
51       chainTemperatures               (chainparams.chainTemperatures),
52       dropArrangerRelativeTiming      (chainparams.dropArrangerRelativeTiming),
53       sizeArrangerRelativeTiming      (chainparams.sizeArrangerRelativeTiming),
54       haplotypeArrangerRelativeTiming (chainparams.haplotypeArrangerRelativeTiming),
55       probhapArrangerRelativeTiming   (chainparams.probhapArrangerRelativeTiming),
56       bayesianArrangerRelativeTiming  (chainparams.bayesianArrangerRelativeTiming),
57       locusArrangerRelativeTiming     (chainparams.locusArrangerRelativeTiming),
58       zilchArrangerRelativeTiming     (chainparams.zilchArrangerRelativeTiming),
59       stairArrangerRelativeTiming     (chainparams.stairArrangerRelativeTiming),
60       epochSizeArrangerRelativeTiming (chainparams.epochSizeArrangerRelativeTiming),
61       doBayesianAnalysis              (chainparams.doBayesianAnalysis),
62       finalChainSamplingInterval      (chainparams.finalChainSamplingInterval),
63       finalNumberOfChains             (chainparams.finalNumberOfChains),
64       finalNumberOfChainsToDiscard    (chainparams.finalNumberOfChainsToDiscard),
65       finalNumberOfSamples            (chainparams.finalNumberOfSamples),
66       initialChainSamplingInterval    (chainparams.initialChainSamplingInterval),
67       initialNumberOfChains           (chainparams.initialNumberOfChains),
68       initialNumberOfChainsToDiscard  (chainparams.initialNumberOfChainsToDiscard),
69       initialNumberOfSamples          (chainparams.initialNumberOfSamples),
70       numberOfReplicates              (chainparams.numberOfReplicates),
71       temperatureInterval             (chainparams.temperatureInterval)
72 {
73 }
74 
~UIVarsChainParameters()75 UIVarsChainParameters::~UIVarsChainParameters()
76 {
77 }
78 
GetChainCount() const79 long int UIVarsChainParameters::GetChainCount() const
80 {
81     return chainTemperatures.size();
82 }
83 
GetChainTemperature(long int chainId) const84 double UIVarsChainParameters::GetChainTemperature(long int chainId) const
85 {
86     assert(chainId < (long int)chainTemperatures.size());
87     return chainTemperatures[chainId];
88 }
89 
GetChainTemperatures() const90 DoubleVec1d UIVarsChainParameters::GetChainTemperatures() const
91 {
92     return chainTemperatures;
93 }
94 
GetBayesianArrangerRelativeTiming() const95 double UIVarsChainParameters::GetBayesianArrangerRelativeTiming() const
96 {
97     if (GetDoBayesianAnalysis())
98     {
99         if(bayesianArrangerRelativeTiming <= 0.0)
100         {
101             assert(bayesianArrangerRelativeTiming == FLAGDOUBLE);
102             return GetDropArrangerRelativeTiming();
103         }
104         else
105         {
106             return bayesianArrangerRelativeTiming;
107         }
108     }
109     else
110     {
111         return 0.0;
112     }
113 }
114 
GetLocusArrangerRelativeTiming() const115 double UIVarsChainParameters::GetLocusArrangerRelativeTiming() const
116 {
117     if (GetConstUIVars().traitmodels.AnyJumpingAnalyses() > 0)
118     {
119         if(locusArrangerRelativeTiming <= 0.0)
120         {
121             assert(locusArrangerRelativeTiming == FLAGDOUBLE);
122             return dropArrangerRelativeTiming * .2;
123         }
124         else
125         {
126             return locusArrangerRelativeTiming;
127         }
128     }
129     else
130     {
131         return 0.0;
132     }
133 }
134 
GetDropArrangerRelativeTiming() const135 double UIVarsChainParameters::GetDropArrangerRelativeTiming() const
136 {
137     if (zilchArrangerRelativeTiming > 0)
138     {
139         return 0.0;
140     }
141     return dropArrangerRelativeTiming;
142 }
143 
GetStairArrangerRelativeTiming() const144 double UIVarsChainParameters::GetStairArrangerRelativeTiming() const
145 {
146     return stairArrangerRelativeTiming;
147 }
148 
GetEpochSizeArrangerRelativeTiming() const149 double UIVarsChainParameters::GetEpochSizeArrangerRelativeTiming() const
150 {
151     return epochSizeArrangerRelativeTiming;
152 }
153 
GetSizeArrangerRelativeTiming() const154 double UIVarsChainParameters::GetSizeArrangerRelativeTiming() const
155 {
156     return sizeArrangerRelativeTiming;
157 }
158 
GetZilchArrangerRelativeTiming() const159 double UIVarsChainParameters::GetZilchArrangerRelativeTiming() const
160 {
161     if (GetConstUIVars().datapackplus.AnySimulation())
162     {
163         return zilchArrangerRelativeTiming;
164     }
165     else
166     {
167         return 0.0;
168     }
169 }
170 
GetHaplotypeArrangerPossible() const171 bool UIVarsChainParameters::GetHaplotypeArrangerPossible() const
172 {
173     return GetConstUIVars().datapackplus.CanHapArrange();
174 }
175 
GetHaplotypeArrangerRelativeTiming() const176 double UIVarsChainParameters::GetHaplotypeArrangerRelativeTiming() const
177 {
178     return haplotypeArrangerRelativeTiming;
179 }
180 
GetProbHapArrangerPossible() const181 bool UIVarsChainParameters::GetProbHapArrangerPossible() const
182 {
183     return (GetConstUIVars().traitmodels.AnyJumpingAnalyses() &&
184             GetConstUIVars().datapackplus.AnyRelativeHaplotypes());
185 }
186 
GetProbHapArrangerRelativeTiming() const187 double UIVarsChainParameters::GetProbHapArrangerRelativeTiming() const
188 {
189     return probhapArrangerRelativeTiming;
190 }
191 
GetTemperatureInterval() const192 long int UIVarsChainParameters::GetTemperatureInterval() const
193 {
194     return temperatureInterval;
195 }
196 
GetAdaptiveTemperatures() const197 bool UIVarsChainParameters::GetAdaptiveTemperatures() const
198 {
199     return adaptiveTemperatures;
200 }
201 
GetNumberOfReplicates() const202 long int UIVarsChainParameters::GetNumberOfReplicates() const
203 {
204     return numberOfReplicates;
205 }
206 
GetInitialNumberOfChains() const207 long int UIVarsChainParameters::GetInitialNumberOfChains() const
208 {
209     return initialNumberOfChains;
210 }
211 
GetInitialNumberOfSamples() const212 long int UIVarsChainParameters::GetInitialNumberOfSamples() const
213 {
214     return initialNumberOfSamples;
215 }
216 
GetInitialChainSamplingInterval() const217 long int UIVarsChainParameters::GetInitialChainSamplingInterval() const
218 {
219     return initialChainSamplingInterval;
220 }
221 
GetInitialNumberOfChainsToDiscard() const222 long int UIVarsChainParameters::GetInitialNumberOfChainsToDiscard() const
223 {
224     return initialNumberOfChainsToDiscard;
225 }
226 
GetFinalNumberOfChains() const227 long int UIVarsChainParameters::GetFinalNumberOfChains() const
228 {
229     return finalNumberOfChains;
230 }
231 
GetFinalNumberOfSamples() const232 long int UIVarsChainParameters::GetFinalNumberOfSamples() const
233 {
234     return finalNumberOfSamples;
235 }
236 
GetFinalChainSamplingInterval() const237 long int UIVarsChainParameters::GetFinalChainSamplingInterval() const
238 {
239     return finalChainSamplingInterval;
240 }
241 
GetFinalNumberOfChainsToDiscard() const242 long int UIVarsChainParameters::GetFinalNumberOfChainsToDiscard() const
243 {
244     return finalNumberOfChainsToDiscard;
245 }
246 
GetDoBayesianAnalysis() const247 bool UIVarsChainParameters::GetDoBayesianAnalysis() const
248 {
249     return doBayesianAnalysis;
250 }
251 
SetChainCount(long int chainCount)252 void UIVarsChainParameters::SetChainCount(long int chainCount)
253 {
254     if(chainCount < 1)
255     {
256         throw data_error("There must be a positive number of simultaneous searches");
257     }
258     if (chainCount > defaults::maxNumHeatedChains)
259     {
260         string err = "There must be less than "
261             + ToString(defaults::maxNumHeatedChains)
262             + " multiple searches for a given run. "
263             + " (A reasonably high number is 5.)";
264         throw data_error(err);
265     }
266     if (chainCount > 5)
267     {
268         GetConstUIVars().GetUI()->AddWarning("Warning:  a high number of simultaneous heated chains can cause "
269                                              "LAMARC to run out of memory.  Five chains is probably a reasonably high upper limit.");
270     }
271     while((long int)chainTemperatures.size() < chainCount)
272     {
273         chainTemperatures.push_back(MakeNextChainTemperature(chainTemperatures));
274     }
275     chainTemperatures.resize(chainCount);
276 }
277 
SetChainTemperature(double val,long int chainId)278 void UIVarsChainParameters::SetChainTemperature(double val, long int chainId)
279 {
280     assert(chainId < (long int)chainTemperatures.size());
281     if (val <= 0)
282     {
283         throw data_error("All chain temperatures must be positive.");
284     }
285     chainTemperatures[chainId] = val;
286 }
287 
RescaleDefaultSizeArranger()288 void UIVarsChainParameters::RescaleDefaultSizeArranger()
289 {
290     if (dropArrangerRelativeTiming > 0)
291     {
292         sizeArrangerRelativeTiming = sizeArrangerRelativeTiming * dropArrangerRelativeTiming;
293     }
294 }
295 
SetBayesianArrangerRelativeTiming(double val)296 void UIVarsChainParameters::SetBayesianArrangerRelativeTiming(double val)
297 {
298     if (val < 0.0)
299     {
300         throw data_error("The bayesian rearranger frequency must be positive.");
301     }
302     if (val == 0.0)
303     {
304         if (GetDoBayesianAnalysis() == false) return;
305         throw data_error("The Bayesian rearranger frequency must be positive when a Bayesian analysis is on.\n"
306                          "If you don't want a Bayesian analysis, turn it off in the 'Search Strategy' menu.");
307     }
308     if (GetDoBayesianAnalysis() == false)
309     {
310         throw data_error("You are not performing a Bayesian analysis, and therefore may not turn on the\n"
311                          "Bayesian arranger (the 'bayesian' tag within the 'strategy' tag)");
312     }
313     bayesianArrangerRelativeTiming = val;
314 }
315 
SetLocusArrangerRelativeTiming(double val)316 void UIVarsChainParameters::SetLocusArrangerRelativeTiming(double val)
317 {
318     if (val <= 0.0)
319     {
320         throw data_error("The trait location rearranger frequency must be greater than zero.");
321     }
322     locusArrangerRelativeTiming = val;
323 }
324 
SetDropArrangerRelativeTiming(double val)325 void UIVarsChainParameters::SetDropArrangerRelativeTiming(double val)
326 {
327     // shut this test off for newick testing 8/10 JRM
328     if (val <= 0)
329     {
330         throw data_error("The topology rearranger frequency must be greater than zero.");
331     }
332     zilchArrangerRelativeTiming = 0.0;
333     dropArrangerRelativeTiming = val;
334 }
335 
SetStairArrangerRelativeTiming(double val)336 void UIVarsChainParameters::SetStairArrangerRelativeTiming(double val)
337 {
338     if (val < 0)
339     {
340         throw data_error("The stair rearranger frequency must be positive.");
341     }
342     stairArrangerRelativeTiming = val;
343 }
344 
SetEpochSizeArrangerRelativeTiming(double val)345 void UIVarsChainParameters::SetEpochSizeArrangerRelativeTiming(double val)
346 {
347     if (val < 0)
348     {
349         throw data_error("The epoch-size rearranger frequency must be positive.");
350     }
351     epochSizeArrangerRelativeTiming = val;
352 }
353 
SetSizeArrangerRelativeTiming(double val)354 void UIVarsChainParameters::SetSizeArrangerRelativeTiming(double val)
355 {
356     if (val < 0)
357     {
358         throw data_error("The size rearranger frequency must be positive.");
359     }
360     sizeArrangerRelativeTiming = val;
361 }
362 
SetHaplotypeArrangerRelativeTiming(double val)363 void UIVarsChainParameters::SetHaplotypeArrangerRelativeTiming(double val)
364 {
365     if (val < 0)
366     {
367         throw data_error("The haplotype rearranger frequency must be positive.");
368     }
369     haplotypeArrangerRelativeTiming = val;
370 }
371 
SetProbHapArrangerRelativeTiming(double val)372 void UIVarsChainParameters::SetProbHapArrangerRelativeTiming(double val)
373 {
374     if (val < 0)
375     {
376         throw data_error("The trait haplotype rearranger frequency must be positive.");
377     }
378     probhapArrangerRelativeTiming = val;
379 }
380 
SetZilchArrangerRelativeTiming(double val)381 void UIVarsChainParameters::SetZilchArrangerRelativeTiming(double val)
382 {
383     if (val < 0.0)
384     {
385         throw data_error("The do-nothing rearranger frequency must be positive.");
386     }
387     if (GetConstUIVars().datapackplus.AnySimulation())
388     {
389         zilchArrangerRelativeTiming = val;
390     }
391     else
392     {
393         throw data_error("You may not use the do-nothing arranger if you are not simulating data.");
394     }
395 }
396 
SetTemperatureInterval(long int val)397 void UIVarsChainParameters::SetTemperatureInterval(long int val)
398 {
399     if (val < 1)
400     {
401         throw data_error("The swapping interval must be one or greater.");
402     }
403     temperatureInterval = val;
404 }
405 
SetAdaptiveTemperatures(bool val)406 void UIVarsChainParameters::SetAdaptiveTemperatures(bool val)
407 {
408     adaptiveTemperatures = val;
409     // NOTE: We allow lamarc to use the current (possibly
410     // user-set) temperatures as the starting point for
411     // adaptive temperatures. Jon says this is fine.
412 }
413 
SetNumberOfReplicates(long int val)414 void UIVarsChainParameters::SetNumberOfReplicates(long int val)
415 {
416     if (val < 0)
417     {
418         throw data_error("The number of replicates must be one or greater.");
419     }
420     if (val == 0)
421     {
422         val = 1;
423         GetConstUIVars().GetUI()->AddWarning("The minimum number of replicates is one, meaning, 'Do one analysis'.  "
424                                              "Setting the number of replicates to one, instead of zero.");
425     }
426     numberOfReplicates = val;
427 }
428 
SetInitialNumberOfChains(long int val)429 void UIVarsChainParameters::SetInitialNumberOfChains(long int val)
430 {
431     if (val < 0)
432     {
433         throw data_error("You may not have a negative number of initial chains.");
434     }
435     initialNumberOfChains = val;
436     WarnIfNoSamples();
437 }
438 
SetInitialNumberOfSamples(long int val)439 void UIVarsChainParameters::SetInitialNumberOfSamples(long int val)
440 {
441     if (val < 0)
442     {
443         throw data_error("You may not have a negative number of initial samples.");
444     }
445     initialNumberOfSamples = val;
446     WarnIfNoSamples();
447 }
448 
SetInitialChainSamplingInterval(long int val)449 void UIVarsChainParameters::SetInitialChainSamplingInterval(long int val)
450 {
451     if (val <= 0)
452     {
453         throw data_error("You must have a positive sampling interval.");
454     }
455     initialChainSamplingInterval = val;
456 }
457 
SetInitialNumberOfChainsToDiscard(long int val)458 void UIVarsChainParameters::SetInitialNumberOfChainsToDiscard(long int val)
459 {
460     if (val < 0)
461     {
462         throw data_error("You may not have a negative number of discarded genealogies.");
463     }
464     initialNumberOfChainsToDiscard = val;
465 }
466 
SetFinalNumberOfChains(long int val)467 void UIVarsChainParameters::SetFinalNumberOfChains(long int val)
468 {
469     if (val < 0)
470     {
471         throw data_error("You may not have a negative number of final chains.");
472     }
473     finalNumberOfChains = val;
474     WarnIfNoSamples();
475 }
476 
SetFinalNumberOfSamples(long int val)477 void UIVarsChainParameters::SetFinalNumberOfSamples(long int val)
478 {
479     if (val < 0)
480     {
481         throw data_error("You may not have a negative number of final samples.");
482     }
483     finalNumberOfSamples = val;
484     WarnIfNoSamples();
485 }
486 
SetFinalChainSamplingInterval(long int val)487 void UIVarsChainParameters::SetFinalChainSamplingInterval(long int val)
488 {
489     if (val <= 0)
490     {
491         throw data_error("You must have a positive sampling interval.");
492     }
493     finalChainSamplingInterval = val;
494 }
495 
SetFinalNumberOfChainsToDiscard(long int val)496 void UIVarsChainParameters::SetFinalNumberOfChainsToDiscard(long int val)
497 {
498     if (val < 0)
499     {
500         throw data_error("You may not have a negative number of discarded genealogies.");
501     }
502     finalNumberOfChainsToDiscard = val;
503 }
504 
WarnIfNoSamples()505 void UIVarsChainParameters::WarnIfNoSamples()
506 {
507     if (((initialNumberOfChains == 0) || (initialNumberOfSamples == 0))
508         && ((finalNumberOfChains == 0) || (finalNumberOfSamples == 0)))
509     {
510         GetConstUIVars().GetUI()->AddWarning("Warning:  LAMARC will never sample any trees.");
511     }
512 }
513 
SetDoBayesianAnalysis(bool val)514 void UIVarsChainParameters::SetDoBayesianAnalysis(bool val)
515 {
516     if (val && GetConstUIVars().forces.GetForceOnOff(force_REGION_GAMMA))
517     {
518         throw data_error("Cannot do a Bayesian analysis while attempting to estimate Gamma.");
519     }
520     if (!val && GetConstUIVars().forces.GetForceOnOff(force_DIVERGENCE))
521     {
522         throw data_error("Must do a Bayesian analysis while modeling Divergence.");
523     }
524     doBayesianAnalysis = val;
525 }
526 
MakeNextChainTemperature(const vector<double> temperatures)527 double MakeNextChainTemperature(const vector<double> temperatures)
528 // this assigns temperatures with constant difference between
529 // successive temperatures.
530 {
531     if(temperatures.empty())
532     {
533         assert(false); //How did we get an empty temperature vec?
534         return defaults::minTemperature;
535     }
536     unsigned long int size = temperatures.size();
537     if(size == 1)
538     {
539         return defaults::secondTemperature;
540     }
541     double diff = temperatures[size-1] - temperatures[size-2];
542     return temperatures[size-1] + diff;
543 }
544 
545 //____________________________________________________________________________________
546