/* Initialise KISS generator using /dev/urandom */ void jkiss_init(jkiss *j) { j->x = devrand(); while (!(j->y = devrand())); /* y must not be zero! */ j->z = devrand(); /* We don’t really need to set c as well but let's anyway… */ /* NOTE: offset c by 1 to avoid z=c=0 */ j->c = devrand() % 698769068 + 1; /* Should be less than 698769069 */ }
void getParameters(int argc,const char **argv){ int args; int i,j; double migR; int selCheck,nChangeCheck; if( argc < 3){ usage(); } sampleSize = atoi(argv[1]); if(sampleSize > 254){ #ifndef BIG printf("Error: sampleSize > 254. recompile discoal and set the -DBIG flag\n"); exit(666); #endif } sampleNumber = atoi(argv[2]); nSites = atoi(argv[3]); if(nSites>MAXSITES){ printf("Error: number of sites set higher than current compilation limit. Please reduce the number of sites or change the MAXSITES define and recompile\n"); exit(666); } args = 4; npops = 1; popnSizes[0]=sampleSize; popnSizes[1]=0; sampleSizes[0]=sampleSize; sampleSizes[1]=0; leftRho = 0.0; rho = 0.0; my_gamma = 0.0; gcMean = 0; theta = 0.0; alpha = 0.0; lambda = 0.0; tau = 0; ancestralSizeRatio = 1.0; f0=0.0; uA=0.0; seed1 = (long) (devrand() % 2147483399); seed2 = (long) (devrand() % 2147483399); EFFECTIVE_POPN_SIZE = 1000000; sweepSite = 0.5; tDiv=666; gammaCoRatioMode = 0; priorTheta=priorRho=priorAlpha=priorTau=priorX=priorF0=priorUA=priorC=0; eventFlag = 1; effectiveSampleSize = sampleSize; finiteOutputFlag = 0; outputStyle = 'h'; mask = 0; migFlag = 0; deltaTMod = 40; recurSweepMode = 0; treeOutputMode= 0; partialSweepMode = 0; softSweepMode = 0; ancSampleFlag = 0; ancSampleSize = 0; hidePartialSNP = 0; //set up first bogus event eventNumber = 0; events[eventNumber].time = 0.0; events[eventNumber].popID = 0; events[eventNumber].popnSize = 1.0; events[eventNumber].type = 'n'; eventNumber++; currentSize = malloc(sizeof(double) * MAXPOPS); condRecMode= 0; while(args < argc){ switch(argv[args][1]){ case 'S' : runMode = 'S'; fileName = argv[++args]; break; case 's' : segSites = atoi(argv[++args]); break; case 't' : theta = atof(argv[++args]); break; case 'i' : deltaTMod = atof(argv[++args]); break; case 'r' : rho = atof (argv[++args]); break; case 'g' : if (argv[args][2] == 'r') { gammaCoRatio = atof (argv[++args]); gcMean = atoi (argv[++args]); gammaCoRatioMode = 1; } else { my_gamma = atof (argv[++args]); gcMean = atoi (argv[++args]); } break; case 'a' : alpha = atof(argv[++args]); break; case 'x' : sweepSite = atof(argv[++args]); break; case 'M' : if(npops==1){ fprintf(stderr,"Error: attempting to set migration but only one population! Be sure that 'm' flags are specified after 'p' flag\n"); exit(1); } migR = atof(argv[++args]); for(i=0;i<npops;i++){ for(j=0;j<npops;j++){ if(i!=j){ migMatConst[i][j]=migR; } else{ migMatConst[i][j]= 0.0; } } } migFlag = 1; break; case 'm' : if(npops==1){ fprintf(stderr,"Error: attempting to set migration but only one population! Be sure that 'm' flags are specified after 'p' flag\n"); exit(1); } i = atoi(argv[++args]); j = atoi(argv[++args]); migR = atof(argv[++args]); migMatConst[i][j]=migR; migFlag = 1; break; case 'p' : npops = atoi(argv[++args]); if(npops > MAXPOPS){ fprintf(stderr,"Error: too many populations defined. Current maximum number = %d. Change MAXPOPS define in discoal.h and recompile... if you dare\n",MAXPOPS); exit(1); } for(i=0;i<npops;i++){ sampleSizes[i]=atoi(argv[++args]); currentSize[i] = 1.0; } break; case 'e' : switch(argv[args][2]){ case 'n': events[eventNumber].time = atof(argv[++args]) * 2.0; events[eventNumber].popID = atoi(argv[++args]); events[eventNumber].popnSize = atof(argv[++args]); events[eventNumber].type = 'n'; //size change eventNumber++; break; case 'd' : tDiv = atof(argv[++args]); events[eventNumber].time = tDiv * 2.0; events[eventNumber].popID = atoi(argv[++args]); events[eventNumber].popID2 = atoi(argv[++args]); events[eventNumber].type = 'p'; //pop split eventNumber++; break; case 'a' : events[eventNumber].time = atof(argv[++args]) * 2.0; events[eventNumber].popID = atoi(argv[++args]); events[eventNumber].popID2 = atoi(argv[++args]); events[eventNumber].popID3 = atoi(argv[++args]); events[eventNumber].admixProp = atof(argv[++args]); events[eventNumber].type = 'a'; //admix split eventNumber++; break; } break; case 'w': switch(argv[args][2]){ case 'd': sweepMode = 'd'; break; case 's': sweepMode = 's'; break; case 'n': sweepMode = 'N'; break; } tau = atof(argv[++args]) * 2.0; events[eventNumber].time = tau; events[eventNumber].type = 's'; //sweep event eventNumber++; break; case 'l': switch(argv[args][2]){ case 'd': sweepMode = 'd'; break; case 's': sweepMode = 's'; break; case 'n': sweepMode = 'N'; break; } sweepSite = -1.0; tau = atof(argv[++args]) * 2.0; leftRho = atof(argv[++args]) * 2.0; leftRhoFlag=1; events[eventNumber].time = tau; events[eventNumber].type = 's'; //sweep event eventNumber++; break; case 'f': f0 = atof(argv[++args]); softSweepMode = 1; break; case 'u': uA = atof(argv[++args]); break; case 'P' : switch(argv[args][2]){ case 't': priorTheta = 1; pThetaLow=atof(argv[++args]); pThetaUp=atof(argv[++args]); break; case 'c': priorC = 1; partialSweepMode = 1; pCLow=atof(argv[++args]); pCUp=atof(argv[++args]); break; case 'r': if (strlen(argv[args]) == 4 && argv[args][3] == 'e'){ priorRho = 2; pRhoMean=atof(argv[++args]); pRhoUp=atof(argv[++args]); } else{ priorRho = 1; pRhoLow=atof(argv[++args]); pRhoUp=atof(argv[++args]); } break; case 'a': priorAlpha = 1; pAlphaLow=atof(argv[++args]); pAlphaUp=atof(argv[++args]); break; case 'u': if (strlen(argv[args]) == 4 && argv[args][3] == 'A'){ priorUA = 1; pUALow=atof(argv[++args]); pUAUp=atof(argv[++args]); } else{ priorTau = 1; pTauLow=atof(argv[++args]) * 2.0; pTauUp=atof(argv[++args]) * 2.0; } break; case 'x': priorX = 1; pXLow=atof(argv[++args]); pXUp=atof(argv[++args]); break; case 'f': priorF0 = 1; pF0Low=atof(argv[++args]); pF0Up=atof(argv[++args]); break; case 'e': switch(argv[args][3]){ case '1': priorE1 = 1; pE1TLow=atof(argv[++args])*2.0; pE1THigh=atof(argv[++args])*2.0; pE1SLow=atof(argv[++args]); pE1SHigh=atof(argv[++args]); events[eventNumber].type = 'n'; eventNumber++; break; case '2': priorE2 = 1; pE2TLow=atof(argv[++args])*2.0; pE2THigh=atof(argv[++args])*2.0; pE2SLow=atof(argv[++args]); pE2SHigh=atof(argv[++args]); events[eventNumber].type = 'n'; eventNumber++; break; } break; } break; case 'U' : untilMode= 1; uTime=atof(argv[++args])*2.0; break; case 'd' : seed1=atoi(argv[++args]); seed2=atoi(argv[++args]); break; case 'N' : EFFECTIVE_POPN_SIZE=atoi(argv[++args]); break; case 'T' : treeOutputMode= 1; break; case 'C' : condRecMode= 1; condRecMet = 0; lSpot=atoi(argv[++args]); rSpot=atoi(argv[++args]); break; case 'R' : recurSweepMode = 1; sweepMode = 's'; recurSweepRate = atof(argv[++args]); break; case 'L' : recurSweepMode = 1; sweepMode = 's'; sweepSite = -1.0; recurSweepRate = atof(argv[++args]); if (recurSweepRate <= 0) { fprintf(stderr,"recurSweepRate must be > 0\n"); exit(0); } break; case 'c' : partialSweepMode = 1; sweepMode = 's'; partialSweepFinalFreq = atof(argv[++args]); if (partialSweepFinalFreq <= 0.0 || partialSweepFinalFreq >= 1.0) { fprintf(stderr,"partialSweepFinalFreq must be > 0 and < 1.0\n"); exit(1); } break; case 'h' : hidePartialSNP = 1; break; case 'A' : events[eventNumber].lineageNumber = atoi(argv[++args]); events[eventNumber].popID = atoi(argv[++args]); events[eventNumber].time = atof(argv[++args]) * 2.0; ancSampleSize += events[eventNumber].lineageNumber; events[eventNumber].type = 'A'; //ancient sample ancSampleFlag = 1; eventNumber++; assert(events[eventNumber].lineageNumber < sampleSize); break; } args++; } sortEventArray(events,eventNumber); //make sure events are kosher selCheck = 0; nChangeCheck=0; for(i=0;i<eventNumber;i++){ //printf("event %d: type is %c\n", i, events[i].type); if(events[i].type == 's'){ selCheck = 1; } if(events[i].type == 'n'){ nChangeCheck = 1; } } if(selCheck == 1){ if(recurSweepMode == 1){ printf("Error with event specification: a single sweep event has been found but recurrentSweep mode has been specified\n"); exit(666); } if(nChangeCheck==1 && sweepMode=='d'){ printf("Error with event specification: you chose 1 or more population size changes with a determinstic sweep. Please us -ws flag instead\n"); exit(666); } if(softSweepMode == 1 && partialSweepMode == 1){ if(f0 >= partialSweepFinalFreq){ printf("Error with event specification: you specified a partial soft sweep but final frequency of partial sweep <= f_0\n"); exit(666); } } } if(leftRhoFlag && sweepSite >= 0.0){ printf("Error with event specification: you chose leftRho mode but the sweep site is within the locus\n"); exit(666); } if(softSweepMode == 1 && recurSweepMode == 1){ printf("Error with event specification: currently recurrent soft sweeps are not implemented. this will be a future addition\n"); exit(666); } }