diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 36db24de..746e0f67 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -28,10 +28,10 @@ jobs: with: python-version: ${{ matrix.python-version }} cache: 'pip' - - name: Install boost - run: | - sudo apt-get install libboost-all-dev - ln -s /usr/include/boost/ ./boost_1_70_0 + # - name: Install boost + # run: | + # sudo apt-get install libboost1.74-all-dev + # ln -s /usr/include/boost/ ./boost_1_74_0 - name: Install dependencies run: | python -m pip install --upgrade pip diff --git a/requirements.txt b/requirements.txt index aa094d9f..7a0b215d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ numpy matplotlib +setuptools diff --git a/setup.py b/setup.py index 18090d32..6e59f315 100755 --- a/setup.py +++ b/setup.py @@ -98,8 +98,8 @@ def is_maverick(): # versions are not available, and will most likely work just fine. boost_versions = ['1_35_0', '1_36_0', '1_37_0', '1_38_0', '1_39_0', '1_40_0', '1_42_0', '1_43_0', '1_44_0', '1_45_0', '1_46_0', '1_46_1', '1_47_0', - '1_48_0', '1_70_0'] -invalid_boost_versions = ['1_41_0'] + '1_48_0', '1_62_0', '1_72_0', '1_74_0'] +invalid_boost_versions = ['1_41_0', '1_71_0'] included_version = [x for x in boost_versions if os.path.isdir('boost_' + x)] invalid_version = [x for x in invalid_boost_versions if os.path.isdir('boost_' + x)] @@ -127,23 +127,25 @@ def downloadProgress(count, blockSize, totalSize): import tarfile downloadProgress.counter = 0 try: - BOOST_URL = 'http://downloads.sourceforge.net/project/boost/boost/1.70.0/boost_1_70_0.tar.gz?r=&ts=1440446866&use_mirror=iweb' - sys.stdout.write('Downloading boost C++ library 1.70.0 ') + boost_version = boost_versions[-1] + dot_boost_version = boost_version.replace('_', '.') + BOOST_URL = f'http://downloads.sourceforge.net/project/boost/boost/{dot_boost_version}/boost_{boost_version}.tar.gz?r=&ts=1440446866&use_mirror=iweb' + sys.stdout.write(f'Downloading boost C++ library {dot_boost_version}') sys.stdout.flush() - if not os.path.isfile('boost_1_70_0.tar.gz'): - urlretrieve(BOOST_URL, 'boost_1_70_0.tar.gz', downloadProgress) + if not os.path.isfile(f'boost_{boost_version}.tar.gz'): + urlretrieve(BOOST_URL, f'boost_{boost_version}.tar.gz', downloadProgress) sys.stdout.write('\n') # extract needed files - with tarfile.open('boost_1_70_0.tar.gz', 'r:gz') as tar: - files = [h for h in tar.getmembers() if h.name.startswith('boost_1_70_0/boost') \ - or h.name.startswith('boost_1_70_0/libs/iostreams') \ - or h.name.startswith('boost_1_70_0/libs/serialization') \ - or h.name.startswith('boost_1_70_0/libs/regex') \ - or h.name.startswith('boost_1_70_0/libs/detail') ] + with tarfile.open(f'boost_{boost_version}.tar.gz', 'r:gz') as tar: + files = [h for h in tar.getmembers() if h.name.startswith(f'boost_{boost_version}/boost') \ + or h.name.startswith(f'boost_{boost_version}/libs/iostreams') \ + or h.name.startswith(f'boost_{boost_version}/libs/serialization') \ + or h.name.startswith(f'boost_{boost_version}/libs/regex') \ + or h.name.startswith(f'boost_{boost_version}/libs/detail') ] sys.stdout.write('Extracting %d files\n' % len(files)) tar.extractall(members=files) EMBEDED_BOOST = True - boost_dir = 'boost_1_70_0' + boost_dir = f'boost_{boost_version}' except Exception as e: print(e) print('The boost C++ library version 1.49.0 is not found under the current directory. Will try to use the system libraries.') @@ -766,6 +768,3 @@ def ModuInfo(modu, SIMUPOP_VER, SIMUPOP_REV): cmdclass = {'build_py': build_py}, **setup_params ) - - - diff --git a/src/sampling.py b/src/sampling.py index eb4d8ce2..49ce68c8 100755 --- a/src/sampling.py +++ b/src/sampling.py @@ -92,8 +92,6 @@ MALE, AFFECTED, tagID, getRNG import random -def random_shuffle(x): - random.shuffle(x, getRNG().randUniform) def isSequence(obj): return hasattr(obj, '__iter__') @@ -173,7 +171,7 @@ def drawSamples(self, pop, numOfSamples): ''' if numOfSamples < 0: raise ValueError("Negative number of samples are unacceptable") - # + # return [self.drawSample(pop) for x in range(numOfSamples)] @@ -200,7 +198,7 @@ def drawSample(self, input_pop): size = self.pop.popSize() # randomly choose size individuals values = list(range(self.pop.popSize())) - random_shuffle(values) + random.shuffle(values) indexes = values[:size] else: indexes = [] @@ -210,7 +208,7 @@ def drawSample(self, input_pop): print('Warning: sample size (%d) at subpopulation %d is greater than subpopulation size %d ' \ % (size, sp, self.pop.subPopSize(sp))) values = list(range(self.pop.subPopBegin(sp), self.pop.subPopEnd(sp))) - random_shuffle(values) + random.shuffle(values) indexes.extend(values[:size]) return self.pop.extractIndividuals(indexes = indexes) @@ -308,14 +306,14 @@ def drawSample(self, input_pop): self.prepareSample(input_pop) # if not isSequence(self.cases): - random_shuffle(self.affected) - random_shuffle(self.unaffected) + random.shuffle(self.affected) + random.shuffle(self.unaffected) indexes = self.affected[:self.cases] + self.unaffected[:self.controls] else: indexes = [] for sp in range(self.pop.numSubPop()): - random_shuffle(self.affected[sp]) - random_shuffle(self.unaffected[sp]) + random.shuffle(self.affected[sp]) + random.shuffle(self.unaffected[sp]) indexes.extend(self.affected[sp][:self.cases[sp]]) indexes.extend(self.unaffected[sp][:self.controls[sp]]) return self.pop.extractIndividuals(indexes = indexes) @@ -332,7 +330,7 @@ def drawCaseControlSample(pop, cases, controls, subPops=ALL_AVAIL): specified (virtual) subpopulations. This function returns a population with all extracted individuals. ''' - return CaseControlSampler(cases, controls, subPops).drawSample(pop) + return CaseControlSampler(cases, controls, subPops).drawSample(pop) def drawCaseControlSamples(pop, cases, controls, numOfSamples=1, subPops=ALL_AVAIL): @@ -341,7 +339,7 @@ def drawCaseControlSamples(pop, cases, controls, numOfSamples=1, subPops=ALL_AVA populations. Please refer to function ``drawCaseControlSample`` for a detailed descriptions of parameters. ''' - return CaseControlSampler(cases, controls, subPops).drawSamples(pop, numOfSamples) + return CaseControlSampler(cases, controls, subPops).drawSamples(pop, numOfSamples) class PedigreeSampler(BaseSampler): @@ -399,7 +397,7 @@ def drawSample(self, input_pop): % (self.families, len(self.selectedIDs))) # a tuple might be returned self.selectedIDs = list(self.selectedIDs) - random_shuffle(self.selectedIDs) + random.shuffle(self.selectedIDs) # we select families one by one to exclude overlapping families. IDs = set() cnt = 0 @@ -422,7 +420,7 @@ def drawSample(self, input_pop): # # a tuple might be returned self.selectedIDs[sp] = list(self.selectedIDs[sp]) - random_shuffle(self.selectedIDs[sp]) + random.shuffle(self.selectedIDs[sp]) # we select families one by one to exclude overlapping families. cnt = 0 for id in self.selectedIDs[sp]: @@ -475,7 +473,7 @@ def prepareSample(self, input_pop): subPops=sp)) -def drawAffectedSibpairSample(pop, families, subPops=ALL_AVAIL, +def drawAffectedSibpairSample(pop, families, subPops=ALL_AVAIL, idField='ind_id', fatherField='father_id', motherField='mother_id'): '''Draw affected sibpair samples from a population. If a single ``families`` is given, affected sibpairs and their parents are drawn @@ -488,9 +486,9 @@ def drawAffectedSibpairSample(pop, families, subPops=ALL_AVAIL, ''' return AffectedSibpairSampler(families, subPops, idField, fatherField, motherField).drawSample(pop) - -def drawAffectedSibpairSamples(pop, families, numOfSamples=1, subPops=ALL_AVAIL, + +def drawAffectedSibpairSamples(pop, families, numOfSamples=1, subPops=ALL_AVAIL, idField='ind_id', fatherField='father_id', motherField='mother_id'): '''Draw ``numOfSamples`` affected sibpair samplesa from population ``pop`` and return a list of populations. Please refer to function @@ -625,7 +623,7 @@ def drawNuclearFamilySample(pop, families, numOffspring, affectedParents=0, ''' return NuclearFamilySampler(families, numOffspring, affectedParents, affectedOffspring, subPops, idField, fatherField, motherField).drawSample(pop) - + def drawNuclearFamilySamples(pop, families, numOffspring, affectedParents=0, affectedOffspring=0, numOfSamples=1, subPops=ALL_AVAIL, idField='ind_id', @@ -777,7 +775,7 @@ def drawThreeGenFamilySample(pop, families, numOffspring, pedSize, numOfAffected ''' return ThreeGenFamilySampler(families, numOffspring, pedSize, numOfAffected, subPops, idField, fatherField, motherField).drawSample(pop) - + def drawThreeGenFamilySamples(pop, families, numOffspring, pedSize, numOfAffected=0, numOfSamples=1, subPops=ALL_AVAIL, idField='ind_id', fatherField='father_id', @@ -836,4 +834,3 @@ def drawCombinedSamples(pop, samplers, numOfSamples=1, idField='ind_id'): parameters ``samplers`` and ``idField``. ''' return CombinedSampler(samplers, idField=idField).drawSamples(pop, numOfSamples) -