Skip to content

Commit 85aeb45

Browse files
committed
restore original simuOpt design
1 parent 75a5550 commit 85aeb45

4 files changed

Lines changed: 272 additions & 292 deletions

File tree

CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,6 @@ install(FILES
555555
src/simuPOP/utils.py
556556
src/simuPOP/demography.py
557557
src/simuPOP/sampling.py
558-
src/simuPOP/simuOpt.py
559558
DESTINATION simuPOP
560559
)
561560

simuOpt.py

Lines changed: 271 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,276 @@
11
#!/usr/bin/env python
2-
"""
3-
Backward compatibility stub for simuOpt module.
42

5-
DEPRECATED: Please use 'from simuPOP.simuOpt import setOptions' instead.
6-
This import path will be removed in a future version.
7-
"""
3+
#
4+
# $File: simuOpt.py $
5+
# $LastChangedDate$
6+
# $Rev$
7+
#
8+
# This file is part of simuPOP, a forward-time population genetics
9+
# simulation environment. Please visit https://github.com/BoPeng/simuPOP
10+
# for details.
11+
#
12+
# Copyright (C) 2004 - 2010 Bo Peng (Bo.Peng@bcm.edu)
13+
#
14+
# This program is free software: you can redistribute it and/or modify
15+
# it under the terms of the GNU General Public License as published by
16+
# the Free Software Foundation, either version 3 of the License, or
17+
# (at your option) any later version.
18+
#
19+
# This program is distributed in the hope that it will be useful,
20+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
21+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22+
# GNU General Public License for more details.
23+
#
24+
# You should have received a copy of the GNU General Public License
25+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
26+
#
827

9-
import warnings
28+
'''
29+
Module ``simuOpt`` provides a function ``simuOpt.setOptions`` to control which
30+
simuPOP module to load, and how it is loaded, and a class ``simuOpt.Params``
31+
that helps users manage simulation parameters.
1032
11-
warnings.warn(
12-
"Importing 'simuOpt' directly is deprecated. "
13-
"Please use 'from simuPOP.simuOpt import setOptions' instead. "
14-
"This import path will be removed in a future version.",
15-
DeprecationWarning,
16-
stacklevel=2
17-
)
33+
When simuPOP is loaded, it checkes a few environmental variables
34+
(``SIMUOPTIMIZED``, ``SIMUALLELETYPE``, and ``SIMUDEBUG``) to determine which
35+
simuPOP module to load, and how to load it. More options can be set using the
36+
``simuOpt.setOptions`` function. For example, you can suppress the banner
37+
message when simuPOP is loaded and require a minimal version of simuPOP for
38+
your script. simuPOP recognize the following commandline arguments
1839
19-
from simuPOP.simuOpt import *
40+
``--optimized``
41+
Load the optimized version of a simuPOP module.
42+
43+
``--gui=None|batch|interactive|True|wxPython|Tkinter``
44+
Whether or not use a graphical toolkit and which one to use.
45+
``--gui=batch`` is usually used to run a script in batch mode (do not start
46+
a parameter input dialog and use all default values unless a parameter is
47+
specified from command line or a configuraiton file. If
48+
``--gui=interactive``, an interactive shell will be used to solicit input
49+
from users. Otherwise, simuPOP will try to use a graphical parameter input
50+
dialog, and falls to an interactive mode when no graphical Toolkit is
51+
available. Please refer to parameter ``gui`` for ``simuOpt.setOptions``
52+
for details.
53+
54+
class ``params.Params`` provides a powerful way to handle commandline
55+
arguments. Briefly speaking, a ``Params`` object can be created from a list
56+
of parameter specification dictionaries. The parameters are then become
57+
attributes of this object. A number of functions are provided to determine
58+
values of these parameters using commandline arguments, a configuration
59+
file, or a parameter input dialog (using ``Tkinter`` or ``wxPython``).
60+
Values of these parameters can be accessed as attributes, or extracted
61+
as a list or a dictionary. Note that the ``Params.getParam`` function
62+
automatically handles the following commandline arguments.
63+
64+
``-h`` or ``--help``
65+
Print usage message.
66+
67+
``--config=configFile``
68+
Read parameters from a configuration file *configFile*.
69+
70+
'''
71+
72+
73+
__all__ = [
74+
'simuOptions',
75+
'setOptions'
76+
]
77+
78+
import os, sys, re, time, textwrap
79+
#
80+
# simuOptions that will be checked when simuPOP is loaded. This structure
81+
# can be changed by function setOptions
82+
#
83+
84+
simuOptions = {
85+
'Optimized': False,
86+
'AlleleType': 'short',
87+
'Debug': [],
88+
'Quiet': False,
89+
'Version': None,
90+
'Revision': None,
91+
'GUI': True,
92+
'Plotter': None,
93+
'NumThreads': 1,
94+
}
95+
96+
# Optimized: command line option --optimized or environmental variable SIMUOPTIMIZED
97+
if '--optimized' in sys.argv or os.getenv('SIMUOPTIMIZED') is not None:
98+
simuOptions['Optimized'] = True
99+
100+
# AlleleType: from environmental variable SIMUALLELETYPE
101+
if os.getenv('SIMUALLELETYPE') in ['short', 'long', 'binary', 'mutant', 'lineage']:
102+
simuOptions['AlleleType'] = os.getenv('SIMUALLELETYPE')
103+
elif os.getenv('SIMUALLELETYPE') is not None:
104+
print('Environmental variable SIMUALLELETYPE can only be short, long, binary, mutant, or lineage.')
105+
106+
# Debug: from environmental variable SIMUDEBUG
107+
if os.getenv('SIMUDEBUG') is not None:
108+
simuOptions['Debug'].extend(os.getenv('SIMUDEBUG').split(','))
109+
110+
# openMP number of threads
111+
if os.getenv('OMP_NUM_THREADS') is not None:
112+
try:
113+
simuOptions['NumThreads'] = int(os.getenv('OMP_NUM_THREADS'))
114+
except:
115+
print('Ignoring invalid value for environmental variable OMP_NUM_THREADS')
116+
117+
# GUI: from environmental variable SIMUGUI
118+
if os.getenv('SIMUGUI') is not None:
119+
_gui = os.getenv('SIMUGUI')
120+
elif '--gui' in sys.argv:
121+
if sys.argv[-1] == '--gui':
122+
raise ValueError('An value is expected for command line option --gui')
123+
_gui = sys.argv[sys.argv.index('--gui') + 1]
124+
elif True in [x.startswith('--gui=') for x in sys.argv]:
125+
_gui = sys.argv[[x.startswith('--gui=') for x in sys.argv].index(True)][len('--gui='):]
126+
else:
127+
_gui = None
128+
129+
if _gui in ['True', 'true', '1']:
130+
simuOptions['GUI'] = True
131+
elif _gui in ['False', 'false', '0']:
132+
simuOptions['GUI'] = False
133+
elif _gui in ['wxPython', 'Tkinter', 'batch', 'interactive']:
134+
simuOptions['GUI'] = _gui
135+
elif _gui is not None:
136+
print("Invalid value '%s' for environmental variable SIMUGUI or commandline option --gui." % _gui)
137+
138+
def setOptions(alleleType=None, optimized=None, gui=None, quiet=None,
139+
debug=None, version=None, revision=None, numThreads=None, plotter=None):
140+
'''Set options before simuPOP is loaded to control which simuPOP module to
141+
load, and how the module should be loaded.
142+
143+
alleleType
144+
Use the standard, binary,long or mutant allele version of the simuPOP
145+
module if ``alleleType`` is set to 'short', 'binary', 'long', 'mutant',
146+
or 'lineage' respectively. If this parameter is not set, this function
147+
will try to get its value from environmental variable ``SIMUALLELETYPE``.
148+
The standard (short) module will be used if the environmental variable
149+
is not defined.
150+
151+
optimized
152+
Load the optimized version of a module if this parameter is set to
153+
``True`` and the standard version if it is set to ``False``. If this
154+
parameter is not set (``None``), the optimized version will be used
155+
if environmental variable ``SIMUOPTIMIZED`` is defined. The standard
156+
version will be used otherwise.
157+
158+
gui
159+
Whether or not use graphical user interfaces, which graphical toolkit
160+
to use and how to process parameters in non-GUI mode. If this parameter
161+
is ``None`` (default), this function will check environmental variable
162+
``SIMUGUI`` or commandline option ``--gui`` for a value, and assume
163+
``True`` if such an option is unavailable. If ``gui=True``, simuPOP
164+
will use ``wxPython``-based dialogs if ``wxPython`` is available, and
165+
use ``Tkinter``-based dialogs if ``Tkinter`` is available and use an
166+
interactive shell if no graphical toolkit is available.
167+
``gui='Tkinter'`` or ``'wxPython'`` can be used to specify the
168+
graphical toolkit to use. If ``gui='interactive'``, a simuPOP script
169+
prompt users to input values of parameters. If ``gui='batch'``,
170+
default values of unspecified parameters will be used. In any case,
171+
commandline arguments and a configuration file specified by parameter
172+
--config will be processed. This option is usually left to ``None`` so
173+
that the same script can be run in both GUI and batch mode using
174+
commandline option ``--gui``.
175+
176+
plotter
177+
(Deprecated)
178+
179+
quiet
180+
If set to ``True``, suppress the banner message when a simuPOP module
181+
is loaded.
182+
183+
debug
184+
A list of debug code (as string) that will be turned on when simuPOP
185+
is loaded. If this parameter is not set, a list of comma separated
186+
debug code specified in environmental variable ``SIMUDEBUG``, if
187+
available, will be used. Note that setting ``debug=[]`` will remove
188+
any debug code that might have been by variable ``SIMUDEBUG``.
189+
190+
version
191+
A version string (e.g. 1.0.0) indicating the required version number
192+
for the simuPOP module to be loaded. simuPOP will fail to load if the
193+
installed version is older than the required version.
194+
195+
revision
196+
Obsolete with the introduction of parameter version.
197+
198+
numThreads
199+
Number of Threads that will be used to execute a simuPOP script. The
200+
values can be a positive number (number of threads) or 0 (all available
201+
cores of the computer, or whatever number set by environmental variable
202+
``OMP_NUM_THREADS``). If this parameter is not set, the number of
203+
threads will be set to 1, or a value set by environmental variable
204+
``OMP_NUM_THREADS``.
205+
'''
206+
# if the module has already been imported, check which module
207+
# was imported
208+
try:
209+
_imported = sys.modules['simuPOP'].moduleInfo()
210+
except Exception as e:
211+
_imported = {}
212+
# Allele type
213+
if alleleType in ['long', 'binary', 'short', 'mutant', 'lineage']:
214+
# if simuPOP has been imported and re-imported with a different module name
215+
# the existing module will be used so moduleInfo() will return a different
216+
# module type from what is specified in simuOptions.
217+
if _imported and _imported['alleleType'] != alleleType:
218+
raise ImportError(('simuPOP has already been imported with allele type %s (%s) and cannot be '
219+
're-imported with allele type %s. Please make sure you import module simuOpt before '
220+
'any simuPOP module is imported.') % (
221+
_imported['alleleType'], ('optimized' if _imported['optimized'] else 'standard'),
222+
alleleType))
223+
simuOptions['AlleleType'] = alleleType
224+
elif alleleType is not None:
225+
raise TypeError('Parameter alleleType can be either short, long, binary, mutant or lineage.')
226+
# Optimized
227+
if optimized in [True, False]:
228+
# if simuPOP has been imported and re-imported with a different module name
229+
# the existing module will be used so moduleInfo() will return a different
230+
# module type from what is specified in simuOptions.
231+
if _imported and _imported['optimized'] != optimized:
232+
raise ImportError(('simuPOP has already been imported with allele type %s (%s) and cannot be '
233+
're-imported in %s mode. Please make sure you import module simuOpt before '
234+
'any simuPOP module is imported.') % (
235+
_imported['alleleType'], ('optimized' if _imported['optimized'] else 'standard'),
236+
'optimized' if optimized else 'standard'))
237+
simuOptions['Optimized'] = optimized
238+
elif optimized is not None:
239+
raise TypeError('Parameter optimized can be either True or False.')
240+
# Graphical toolkit
241+
if gui in [True, False, 'wxPython', 'Tkinter', 'batch']:
242+
simuOptions['GUI'] = gui
243+
elif gui is not None:
244+
raise TypeError('Parameter gui can be True/False, wxPython or Tkinter.')
245+
# Quiet
246+
if quiet in [True, False]:
247+
simuOptions['Quiet'] = quiet
248+
elif quiet is not None:
249+
raise TypeError('Parameter quiet can be either True or False.')
250+
# Debug
251+
if debug is not None:
252+
if type(debug) == str:
253+
simuOptions['Debug'] = [debug]
254+
else:
255+
simuOptions['Debug'] = debug
256+
# Version
257+
if type(version) == str:
258+
try:
259+
major, minor, release = [int(x) for x in re.sub('\D', ' ', version).split()]
260+
except:
261+
print('Invalid version string %s' % simuOptions['Version'])
262+
simuOptions['Version'] = version
263+
elif version is not None:
264+
raise TypeError('A version string is expected for parameter version.')
265+
# Revision
266+
if type(revision) == int:
267+
simuOptions['Revision'] = revision
268+
elif revision is not None:
269+
raise TypeError('A revision number is expected for parameter revision.')
270+
# NumThreads
271+
if type(numThreads) == int:
272+
simuOptions['NumThreads'] = numThreads
273+
elif numThreads is not None:
274+
raise TypeError('An integer number is expected for parameter numThreads.')
275+
if plotter is not None:
276+
sys.stderr.write('WARNING: plotter option is deprecated because of the removal of rpy/rpy2 support\n')

src/simuPOP/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@
308308
]
309309

310310
# get options
311-
from .simuOpt import simuOptions
311+
from simuOpt import simuOptions
312312
import os, sys, re
313313

314314
if simuOptions['Optimized']:

0 commit comments

Comments
 (0)