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