1 // $Id: ui_vars_datapackplus.cpp,v 1.34 2012/03/09 22:55:20 jmcgill Exp $
2
3 /*
4 Copyright 2002 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 #include <cassert>
12 #include <set>
13
14 #include "datapack.h"
15 #include "dlmodel.h"
16 #include "errhandling.h"
17 #include "region.h"
18 #include "stringx.h"
19 #include "ui_vars.h"
20 #include "ui_vars_datapackplus.h"
21 #include "ui_strings.h"
22
23 //------------------------------------------------------------------------------------
24
UIVarsDataPackPlus(UIVars * myUIVars,DataPack & dp)25 UIVarsDataPackPlus::UIVarsDataPackPlus(UIVars * myUIVars, DataPack& dp)
26 : UIVarsComponent(myUIVars),
27 datapack(dp),
28 m_effectivePopSizes(),
29 m_simulateData()
30 {
31 for (long regnum=0; regnum<GetNumRegions(); regnum++)
32 {
33 m_effectivePopSizes.push_back(datapack.GetRegion(regnum).GetEffectivePopSize());
34 deque<bool> nosims(GetNumLoci(regnum), false);
35 m_simulateData.push_back(nosims);
36 }
37 }
38
UIVarsDataPackPlus(UIVars * myUIVars,const UIVarsDataPackPlus & dpp)39 UIVarsDataPackPlus::UIVarsDataPackPlus(UIVars * myUIVars, const UIVarsDataPackPlus& dpp)
40 : UIVarsComponent(myUIVars),
41 datapack(dpp.datapack),
42 m_effectivePopSizes(dpp.m_effectivePopSizes),
43 m_simulateData(dpp.m_simulateData)
44 {
45 }
46
~UIVarsDataPackPlus()47 UIVarsDataPackPlus::~UIVarsDataPackPlus()
48 {
49 }
50
51 long
GetMaxLoci() const52 UIVarsDataPackPlus::GetMaxLoci() const
53 {
54 long maxL = 0;
55 long numRegions = GetNumRegions();
56 for(long i=0; i < numRegions; i++)
57 {
58 long lociCount = GetNumLoci(i);
59 if(lociCount > maxL)
60 {
61 maxL = lociCount;
62 }
63 }
64
65 return maxL;
66 }
67
68 long
GetNumRegions() const69 UIVarsDataPackPlus::GetNumRegions() const
70 {
71 return datapack.GetNRegions();
72 }
73
74 long
GetNumLoci(long regIndex) const75 UIVarsDataPackPlus::GetNumLoci(long regIndex) const
76 {
77 return datapack.GetRegion(regIndex).GetNloci();
78 }
79
80 long
GetNCrossPartitions() const81 UIVarsDataPackPlus::GetNCrossPartitions() const
82 {
83 return datapack.GetNCrossPartitions();
84 }
85
86 long
GetNPartitionsByForceType(force_type ft) const87 UIVarsDataPackPlus::GetNPartitionsByForceType(force_type ft) const
88 {
89 return datapack.GetNPartitionsByForceType(ft);
90 }
91
GetEffectivePopSize(long region) const92 double UIVarsDataPackPlus::GetEffectivePopSize(long region) const
93 {
94 return m_effectivePopSizes[region];
95 }
96
GetNumIndividualsWithMultipleHaplotypes(long region,string lname) const97 long UIVarsDataPackPlus::GetNumIndividualsWithMultipleHaplotypes(long region, string lname) const
98 {
99 long nMultiInd=0;
100 const IndVec individuals = datapack.GetRegion(region).GetIndividuals();
101 for (unsigned long ind=0; ind<individuals.size(); ind++)
102 {
103 if (individuals[ind].GetHaplotypesFor(lname, 0).MultipleHaplotypes())
104 {
105 nMultiInd++;
106 }
107 }
108 return nMultiInd;
109 }
110
GetSimulateData(long region,long locus) const111 bool UIVarsDataPackPlus::GetSimulateData(long region, long locus) const
112 {
113 if (region < 0 || locus < 0)
114 {
115 assert(false); //Don't ask about this! (probably FLAGLONG or the like)
116 return false;
117 }
118 return m_simulateData[region][locus];
119 }
120
121 // LS NOTE: This should move into the converter eventually. Probably.
SetEffectivePopSize(long region,double size)122 void UIVarsDataPackPlus::SetEffectivePopSize(long region, double size)
123 {
124 if (size <= 0)
125 {
126 throw data_error("The effective population size must be positive.");
127 }
128 assert(region < GetNumRegions());
129 if (region >= static_cast<long>(m_effectivePopSizes.size()))
130 {
131 throw implementation_error("Unable to set this region's size--vector not long enough.");
132 }
133 m_effectivePopSizes[region] = size;
134
135 // may need to update start values at this point
136 GetUIVars().forces.FillCalculatedStartValues();
137 }
138
SetSimulateData(long region,long locus,bool sim)139 void UIVarsDataPackPlus::SetSimulateData(long region, long locus, bool sim)
140 {
141 m_simulateData[region][locus] = sim;
142 }
143
RevertAllMovingLoci()144 void UIVarsDataPackPlus::RevertAllMovingLoci()
145 {
146 for (long reg=0; reg<GetNumRegions(); reg++)
147 {
148 datapack.GetRegion(reg).RevertMovingLoci();
149 }
150 }
151
152 bool
CanHapArrange() const153 UIVarsDataPackPlus::CanHapArrange() const
154 {
155 return datapack.CanHapArrange();
156 }
157
158 bool
HasSomeNucleotideData() const159 UIVarsDataPackPlus::HasSomeNucleotideData() const
160 {
161 for (long reg=0; reg<GetNumRegions(); reg++)
162 {
163 for (long loc=0; loc<GetNumLoci(reg); loc++)
164 {
165 if ((GetDataType(reg, loc) == dtype_DNA) || (GetDataType(reg, loc) == dtype_SNP))
166 {
167 return true;
168 }
169 }
170 }
171 return false;
172 }
173
174 bool
HasSomeMsatData() const175 UIVarsDataPackPlus::HasSomeMsatData() const
176 {
177 for (long reg=0; reg<GetNumRegions(); reg++)
178 {
179 for (long loc=0; loc<GetNumLoci(reg); loc++)
180 {
181 if (GetDataType(reg, loc) == dtype_msat)
182 {
183 return true;
184 }
185 }
186 }
187 return false;
188 }
189
190 bool
HasSomeKAlleleData() const191 UIVarsDataPackPlus::HasSomeKAlleleData() const
192 {
193 for (long reg=0; reg<GetNumRegions(); reg++)
194 {
195 for (long loc=0; loc<GetNumLoci(reg); loc++)
196 {
197 if (GetDataType(reg, loc) == dtype_kallele)
198 {
199 return true;
200 }
201 }
202 }
203 return false;
204 }
205
206 string
GetCrossPartitionName(long index) const207 UIVarsDataPackPlus::GetCrossPartitionName(long index) const
208 {
209 return GetCrossPartitionNames()[index];
210 }
211
212 StringVec1d
GetCrossPartitionNames() const213 UIVarsDataPackPlus::GetCrossPartitionNames() const
214 {
215 return datapack.GetAllCrossPartitionNames();
216 }
217
218 string
GetForcePartitionName(force_type ft,long index) const219 UIVarsDataPackPlus::GetForcePartitionName(force_type ft, long index) const
220 {
221 StringVec1d names = GetForcePartitionNames(ft);
222 return names[index];
223 }
224
225 StringVec1d
GetForcePartitionNames(force_type ft) const226 UIVarsDataPackPlus::GetForcePartitionNames(force_type ft) const
227 {
228 return datapack.GetAllPartitionNames(ft);
229 }
230
231 string
GetLocusName(long regionIndex,long locusIndex) const232 UIVarsDataPackPlus::GetLocusName(long regionIndex, long locusIndex) const
233 {
234 string name = datapack.GetRegion(regionIndex).GetLocus(locusIndex).GetName();
235 string locID;
236 //LS DEBUG MAPPING: When IsMovable is no longer sufficient to tell if
237 // something is a trait or not, (i.e. if it's being used to partition data)
238 // this will need to be changed.
239 if (datapack.GetRegion(regionIndex).GetLocus(locusIndex).IsMovable())
240 {
241 locID = ", trait ";
242 }
243 else
244 {
245 if (datapack.GetRegion(regionIndex).GetNloci() == 1)
246 {
247 //We assume that if there is only one locus in a region, the thing
248 // that has better name recognition is the region, not the locus.
249 locID = ": ";
250 name = datapack.GetRegion(regionIndex).GetRegionName();
251 }
252 else
253 {
254 locID = ", segment " + indexToKey(locusIndex) + " : ";
255 }
256 }
257
258 string fullname = "Region "+indexToKey(regionIndex) + locID + name;
259 return fullname;
260 }
261
262 long
GetLocusIndex(long regionIndex,string locusName) const263 UIVarsDataPackPlus::GetLocusIndex(long regionIndex, string locusName) const
264 {
265 return datapack.GetRegion(regionIndex).GetLocusIndex(locusName);
266 }
267
268 bool
HasLocus(long regionIndex,string locusName) const269 UIVarsDataPackPlus::HasLocus(long regionIndex, string locusName) const
270 {
271 return datapack.GetRegion(regionIndex).HasLocus(locusName);
272 }
273
274 string
GetRegionName(long index) const275 UIVarsDataPackPlus::GetRegionName(long index) const
276 {
277 string name = datapack.GetRegion(index).GetRegionName();
278 string fullname = "Region "+indexToKey(index)+" : "+name;
279 return fullname;
280 }
281
282 string
GetSimpleRegionName(long index) const283 UIVarsDataPackPlus::GetSimpleRegionName(long index) const
284 {
285 return datapack.GetRegion(index).GetRegionName();
286 }
287
288 string
GetParamName(force_type ftype,long index,bool doLongName) const289 UIVarsDataPackPlus::GetParamName(force_type ftype, long index,bool doLongName) const
290 {
291 string pname = "";
292 long fromIndex;
293 long toIndex;
294 long nstates;
295 switch(ftype)
296 {
297 case force_COAL:
298 if(doLongName)
299 {
300 pname += uistr::theta + " for ";
301 pname += GetCrossPartitionName(index);
302 }
303 else
304 {
305 pname += "Theta";
306 pname += indexToKey(index);
307 }
308 break;
309 case force_DIVERGENCE:
310 // MDEBUG should use uistr:: variables here
311 if(doLongName)
312 {
313 pname += uistr::divergenceEpochBoundaryTime + " for ";
314 pname += ToString(index);
315 }
316 else
317 {
318
319 pname += "Epoch " + ToString(index);
320 }
321 break;
322 case force_DISEASE:
323 nstates = GetNPartitionsByForceType(ftype);
324 toIndex = index / nstates;
325 fromIndex = index % nstates;
326 if(doLongName)
327 {
328 pname += uistr::muRate + " from ";
329 pname += GetForcePartitionName(ftype,fromIndex);
330 pname += " to ";
331 pname += GetForcePartitionName(ftype,toIndex);
332 }
333 else
334 {
335 pname += "D";
336 pname += indexToKey(fromIndex);
337 pname += indexToKey(toIndex);
338 }
339 break;
340 case force_EXPGROWSTICK:
341 case force_GROW:
342 if(doLongName)
343 {
344 pname += uistr::growthRate + " for ";
345 pname += GetCrossPartitionName(index);
346 }
347 else
348 {
349 pname += "Growth";
350 pname += indexToKey(index);
351 }
352 break;
353 case force_MIG:
354 case force_DIVMIG:
355 nstates = GetNPartitionsByForceType(ftype);
356 toIndex = index / nstates;
357 fromIndex = index % nstates;
358 if(doLongName)
359 {
360 pname += uistr::migrationByID;
361 pname += GetForcePartitionName(ftype,toIndex);
362 pname += uistr::migrationByID2;
363 pname += GetForcePartitionName(ftype,fromIndex);
364 }
365 else
366 {
367 pname += "M";
368 pname += indexToKey(fromIndex);
369 pname += indexToKey(toIndex);
370 }
371 break;
372 case force_REC:
373 if(doLongName)
374 {
375 pname += uistr::recRate;
376 }
377 else
378 {
379 pname += "Rec";
380 }
381 break;
382 case force_REGION_GAMMA:
383 if(doLongName)
384 {
385 pname += uistr::regGammaShape;
386 }
387 else
388 {
389 pname += "ShapeParam";
390 }
391 break;
392 case force_LOGSELECTSTICK:
393 case force_LOGISTICSELECTION:
394 if(doLongName)
395 {
396 pname += uistr::logisticSelectionCoefficient;
397 }
398 else
399 {
400 pname += "Sel. Coeff.";
401 }
402 break;
403 case force_NONE:
404 assert(false);
405 pname += "No force";
406 break;
407 }
408 return pname;
409 }
410
411 string
GetParamNameOfForce(force_type ftype) const412 UIVarsDataPackPlus::GetParamNameOfForce(force_type ftype) const
413 {
414 switch(ftype)
415 {
416 case force_COAL:
417 return "Theta";
418 break;
419 case force_DISEASE:
420 return "Disease Mutation Rate";
421 break;
422 case force_GROW:
423 return "Growth Rate";
424 break;
425 case force_DIVERGENCE:
426 return "Epoch Boundary Time";
427 break;
428 case force_DIVMIG:
429 case force_MIG:
430 return "Migration Rate";
431 break;
432 case force_REC:
433 return "Recombination Rate";
434 break;
435 case force_REGION_GAMMA:
436 return "Gamma Over Regions";
437 break;
438 case force_EXPGROWSTICK:
439 return "Exponential Growth via stick";
440 break;
441 case force_LOGISTICSELECTION:
442 return "Logistic Selection Coefficient";
443 break;
444 case force_LOGSELECTSTICK:
445 return "Logistic Selection via stick";
446 break;
447 case force_NONE:
448 assert(false);
449 throw implementation_error("UIVarsDataPackPlus::GetParamNameOfForce for force_NONE!");
450 break;
451 };
452 assert(false);
453 throw implementation_error("UIVarsDataPackPlus::GetParamNameOfForce missing switch case");
454 }
455
456 data_type
GetDataType(long regionId,long locusId) const457 UIVarsDataPackPlus::GetDataType(long regionId, long locusId) const
458 {
459 const Region & thisRegion = datapack.GetRegion(regionId);
460 const Locus & thisLocus = thisRegion.GetLocus(locusId);
461 return thisLocus.GetDataType();
462 }
463
IsMovable(long regionId,long locusId) const464 bool UIVarsDataPackPlus::IsMovable(long regionId, long locusId) const
465 {
466 const Region & thisRegion = datapack.GetRegion(regionId);
467 const Locus & thisLocus = thisRegion.GetLocus(locusId);
468 return thisLocus.IsMovable();
469 }
470
GetName(long regionId,long locusId) const471 string UIVarsDataPackPlus::GetName(long regionId, long locusId) const
472 {
473 const Region & thisRegion = datapack.GetRegion(regionId);
474 const Locus & thisLocus = thisRegion.GetLocus(locusId);
475 return thisLocus.GetName();
476 }
477
GetRange(long regionId,long locusId) const478 rangeset UIVarsDataPackPlus::GetRange(long regionId, long locusId) const
479 {
480 const Region & thisRegion = datapack.GetRegion(regionId);
481 const Locus & thisLocus = thisRegion.GetLocus(locusId);
482 return thisLocus.GetAllowedRange();
483 }
484
GetRegionSiteSpan(long regionId) const485 rangepair UIVarsDataPackPlus::GetRegionSiteSpan(long regionId) const
486 {
487 return datapack.GetRegion(regionId).GetSiteSpan();
488 }
489
GetNumSites(long regionId) const490 long UIVarsDataPackPlus::GetNumSites(long regionId) const
491 {
492 const Region & thisRegion = datapack.GetRegion(regionId);
493 return thisRegion.GetNumSites();
494 }
495
GetNumSites(long regionId,long locusId) const496 long UIVarsDataPackPlus::GetNumSites(long regionId, long locusId) const
497 {
498 const Region & thisRegion = datapack.GetRegion(regionId);
499 const Locus & thisLocus = thisRegion.GetLocus(locusId);
500 return thisLocus.GetNsites();
501 }
502
GetUniqueAlleles(long regionId,long locusId) const503 StringVec2d UIVarsDataPackPlus::GetUniqueAlleles(long regionId,
504 long locusId) const
505 {
506 StringVec2d retVec;
507 const Region& thisRegion = datapack.GetRegion(regionId);
508 const Locus& thisLocus = thisRegion.GetLocus(locusId);
509 vector<TipData> tips = thisLocus.GetTipData();
510 const IndVec individuals = thisRegion.GetIndividuals();
511 for (long marker = 0; marker < thisLocus.GetNmarkers(); marker++)
512 {
513 std::set<string> uniqueAlleles;
514 //First, get any alleles from the unknown haplotypes
515 for (unsigned long ind=0; ind<individuals.size(); ind++)
516 {
517 StringVec1d alleles = individuals[ind].GetAllelesFor(thisLocus.GetName(), marker);
518 for (unsigned long nallele=0; nallele<alleles.size(); nallele++)
519 {
520 if (alleles[nallele] != "?")
521 {
522 uniqueAlleles.insert(alleles[nallele]);
523 }
524 }
525 }
526 //Now get any alleles from the tips
527 for (unsigned long tip = 0; tip < tips.size(); ++tip)
528 {
529 if (!tips[tip].m_nodata)
530 {
531 string allele = tips[tip].data[marker];
532 if (allele != "?")
533 {
534 uniqueAlleles.insert(allele);
535 }
536 }
537 }
538 //Convert the set to a vector (for simplicity for our clients)
539 StringVec1d alleleStrings;
540 for (std::set<string>::iterator unique=uniqueAlleles.begin(); unique != uniqueAlleles.end(); unique++)
541 {
542 alleleStrings.push_back(*unique);
543 }
544 retVec.push_back(alleleStrings);
545 }
546 return retVec;
547
548 }
549
GetPloidies(long region) const550 std::set<long> UIVarsDataPackPlus::GetPloidies(long region) const
551 {
552 return datapack.GetRegion(region).GetPloidies();
553 }
554
GetConstLocusPointer(long region,long locus) const555 const Locus* UIVarsDataPackPlus::GetConstLocusPointer(long region, long locus) const
556 {
557 return &datapack.GetRegion(region).GetLocus(locus);
558 }
559
AnySimulation() const560 bool UIVarsDataPackPlus::AnySimulation() const
561 {
562 for (unsigned long region=0; region<m_simulateData.size(); region++)
563 {
564 for (unsigned long locus=0; locus<m_simulateData[region].size(); locus++)
565 {
566 if (m_simulateData[region][locus]) return true;
567 }
568 }
569 return false;
570 }
571
AnyRelativeHaplotypes() const572 bool UIVarsDataPackPlus::AnyRelativeHaplotypes() const
573 {
574 for (long region=0; region<GetNumRegions(); region++)
575 {
576 const Region& reg = datapack.GetRegion(region);
577 for (long ind=0; ind<reg.GetNIndividuals(); ind++)
578 {
579 const Individual& indiv = reg.GetIndividual(ind);
580 if (indiv.MultipleTraitHaplotypes()) return true;
581 }
582 }
583 return false;
584 }
585
AnySNPDataWithDefaultLocations() const586 bool UIVarsDataPackPlus::AnySNPDataWithDefaultLocations() const
587 {
588 for (long region=0; region<GetNumRegions(); region++)
589 {
590 if (datapack.GetRegion(region).AnySNPDataWithDefaultLocations())
591 {
592 return true;
593 }
594 }
595 return false;
596 }
597
GetAncestorName(long index) const598 string UIVarsDataPackPlus::GetAncestorName(long index) const
599 {
600 //const Region & thisRegion = datapack.GetRegion(regionId);
601 //const Locus & thisLocus = thisRegion.GetLocus(locusId);
602 //uiInterface.GetCurrentVars().forces.AddAncestor(ancname);
603
604 //return thisLocus.GetName();
605 //string pname = datapack.forces.UIVarsDivergenceForceGetParent(index).GetName();
606 //datapack.GetRegion(index).GetRegionName();
607 string pname = uistr::divergenceEpochAncestor;
608 pname += ToString(index + 1);
609
610 return pname;
611 }
612
GetDescendentNames(long index) const613 string UIVarsDataPackPlus::GetDescendentNames(long index) const
614 {
615 //const Region & thisRegion = datapack.GetRegion(regionId);
616 //const Locus & thisLocus = thisRegion.GetLocus(locusId);
617 //uiInterface.GetCurrentVars().forces.AddAncestor(ancname);
618
619 //return thisLocus.GetName();
620 //string pname = datapack.forces.GetAncestor(index);
621 string pname = uistr::divergenceEpochDescendent;
622 pname += ToString(index + 1);
623 pname += "-1 ";
624 pname += uistr::divergenceEpochDescendent;
625 pname += ToString(index + 1);
626 pname += "-2";
627
628 return pname;
629 }
630
631 //____________________________________________________________________________________
632