Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Klinische Genetica
prinia
Commits
a02c84e1
Commit
a02c84e1
authored
Sep 24, 2018
by
Sander Bollen
Browse files
Generate settings dict from supplied json, with defaults from schema
parent
646885c5
Changes
7
Hide whitespace changes
Inline
Side-by-side
prinia/primer3.py
View file @
a02c84e1
"""
prinia.primer3
~~~~~~~~~~~~~~
:copyright: (c) 2017-2018 Sander Bollen
:copyright: (c) 2017-2018 Leiden University Medical Center
:license: MIT
"""
from
pathlib
import
Path
from
tempfile
import
NamedTemporaryFile
from
subprocess
import
check_call
from
typing
import
Optional
import
os
import
json
import
re
from
jsonschema
import
validate
from
.models
import
Primer
SETTINGS_SCHEMA
=
(
Path
(
__file__
).
parent
/
Path
(
"static"
)
/
Path
(
"primer3_settings_schema.json"
))
def
parse_settings
(
settings_file
:
Optional
[
Path
]
=
None
)
->
dict
:
"""
Parse settings file to settings dictionary.
Parameters not specified in settings_file will be taken from default values
in schema. If settings_file is None, all values will be the default values
in schema
:param settings_file: Optional path to settings file
:return: dict with settings
:raises: ValidationError if settings_file does not conform to schema
"""
with
SETTINGS_SCHEMA
.
open
(
"r"
)
as
schema_handle
:
schema_dict
=
json
.
load
(
schema_handle
)
defaults
=
{
k
:
v
[
'default'
]
for
k
,
v
in
schema_dict
[
'properties'
].
items
()}
if
settings_file
is
None
:
return
defaults
with
settings_file
.
open
(
"r"
)
as
settings_handle
:
settings_dict
=
json
.
load
(
settings_handle
)
validate
(
settings_dict
,
schema_dict
)
# raises ValidationError if failure
default_keys
=
defaults
.
keys
()
-
settings_dict
.
keys
()
default_dict
=
{
k
:
defaults
[
k
]
for
k
in
default_keys
}
generated_dict
=
{
**
settings_dict
,
**
default_dict
}
# if range is set, but optimum size is not, calculate opt size
if
(
'primer_product_opt_size'
in
default_dict
and
"primer_product_size_range"
in
settings_dict
):
product_range
=
settings_dict
[
'primer_product_size_range'
]
min_size
,
max_size
=
product_range
.
split
(
"-"
)
opt_size
=
int
((
int
(
min_size
)
+
(
int
(
max_size
)
-
int
(
min_size
)))
//
2
)
generated_dict
[
'primer_product_opt_size'
]
=
opt_size
return
generated_dict
class
Primer3
(
object
):
def
__init__
(
self
,
primer3_exe
,
template
,
target
,
excluded_region
,
...
...
prinia/static/primer3_conf.j2
0 → 100644
View file @
a02c84e1
SEQUENCE_ID=prinia_template
SEQUENCE_TEMPLATE={{ seq }}
SEQUENCE_TARGET={{ target }}
SEQUENCE_EXCLUDED_REGION={{ excluded_region }}
PRIMER_TASK=pick_detection_primers
PRIMER_PICK_LEFT_PRIMER=1
PRIMER_PICK_INTERNAL_OLIGO=0
PRIMER_PICK_RIGHT_PRIMER=1
PRIMER_MIN_GC={{ settings.primer_min_gc }}
PRIMER_INTERNAL_MIN_GC={{ settings.primer_internal_min_gc }}
PRIMER_OPT_GC_PERCENT={{ settings.primer_opt_gc_percent }}
PRIMER_MAX_GC={{ settings.primer_max_gc }}
PRIMER_INTERNAL_MAX_GC={{ settings.primer_internal_max_gc }}
PRIMER_WT_GC_PERCENT_LT={{ settings.primer_wt_gc_percent_lt }}
PRIMER_INTERNAL_WT_GC_PERCENT_LT={{ settings.primer_internal_wt_gc_percent_lt }}
PRIMER_WT_GC_PERCENT_GT={{ settings.primer_wt_gc_percent_gt }}
PRIMER_INTERNAL_WT_GC_PERCENT_GT={{ settings.primer_internal_wc_gc_percent_gt }}
PRIMER_GC_CLAMP={{ settings.primer_gc_clamp }}
PRIMER_MAX_END_GC={{ settings.primer_max_end_gc }}
PRIMER_OPT_SIZE={{ settings.primer_opt_size }}
PRIMER_MIN_SIZE={{ settings.primer_min_size }}
PRIMER_MAX_SIZE={{ settings.primer_max_size }}
PRIMER_MAX_NS_ACCEPTED={{ settings.primer_max_ns_accepted }}
PRIMER_PRODUCT_SIZE_RANGE={{ settings.primer_product_size_range }}
PRIMER_PRODUCT_OPT_SIZE={{ settings.primer_product_opt_size }}
PRIMER_PAIR_WT_PRODUCT_SIZE_GT={{ settings.primer_pair_wt_product_size_gt }}
PRIMER_PAIR_WT_PRODUCT_SIZE_LT={{ settings.primer_pair_wt_product_size_gt }}
P3_FILE_FLAG=1
SEQUENCE_INTERNAL_EXCLUDED_REGION=37,21
PRIMER_EXPLAIN_FLAG=1
PRIMER_MIN_TM={{ settings.primer_min_tm }}
PRIMER_MAX_TM={{ settings.primer_max_tm }}
PRIMER_NUM_RETURN={{ settings.primer_num_return }}
\ No newline at end of file
prinia/static/primer3_settings_schema.json
View file @
a02c84e1
...
...
@@ -95,7 +95,7 @@
"primer_max_ns_accepted"
:
{
"description"
:
"Maximum number of unknown bases (N) accepted in a primer"
,
"type"
:
"integer"
,
"default
:
"
:
0
,
"default"
:
0
,
"minimum"
:
0
},
"primer_product_size_range"
:
{
...
...
tests/data/valid_partial_settings.json
0 → 100644
View file @
a02c84e1
{
"primer_gc_clamp"
:
1
,
"primer_max_end_gc"
:
0
,
"primer_opt_size"
:
21
,
"primer_min_size"
:
19
,
"primer_max_size"
:
29
,
"primer_max_ns_accepted"
:
1
,
"primer_product_size_range"
:
"300-500"
,
"primer_pair_wt_product_size_gt"
:
0.12
,
"primer_pair_wt_product_size_lt"
:
0.12
,
"primer_min_tm"
:
55
,
"primer_max_tm"
:
75
,
"primer_num_return"
:
100
}
\ No newline at end of file
tests/test_primer3.py
0 → 100644
View file @
a02c84e1
"""
test_primer3.py
~~~~~~~~~~~~~~~
:copyright: (c) 2018 Sander Bollen
:copyright: (c) 2018 Leiden University Medical Center
:license: MIT
"""
from
pathlib
import
Path
from
pytest
import
fixture
from
prinia.primer3
import
parse_settings
data_dir
=
Path
(
__file__
).
parent
/
Path
(
"data"
)
@
fixture
def
valid_settings
():
return
data_dir
/
Path
(
"valid_settings.json"
)
@
fixture
def
valid_partial_settings
():
return
data_dir
/
Path
(
"valid_partial_settings.json"
)
def
test_none_settings
():
parsed
=
parse_settings
()
assert
parsed
==
{
"primer_min_gc"
:
20
,
"primer_internal_min_gc"
:
20
,
"primer_opt_gc_percent"
:
50
,
"primer_max_gc"
:
80
,
"primer_internal_max_gc"
:
80
,
"primer_wt_gc_percent_lt"
:
0
,
"primer_internal_wt_gc_percent_lt"
:
0
,
"primer_wt_gc_percent_gt"
:
0
,
"primer_internal_wt_gc_percent_gt"
:
0
,
"primer_gc_clamp"
:
0
,
"primer_max_end_gc"
:
5
,
"primer_opt_size"
:
25
,
"primer_min_size"
:
20
,
"primer_max_size"
:
30
,
"primer_max_ns_accepted"
:
0
,
"primer_product_size_range"
:
"200-450"
,
"primer_product_opt_size"
:
325
,
"primer_pair_wt_product_size_gt"
:
0.1
,
"primer_pair_wt_product_size_lt"
:
0.1
,
"primer_min_tm"
:
58
,
"primer_max_tm"
:
62
,
"primer_num_return"
:
200
}
def
test_complete_settings
(
valid_settings
):
parsed
=
parse_settings
(
valid_settings
)
# TODO: work out
def
test_partial_settings
(
valid_partial_settings
):
parsed
=
parse_settings
(
valid_partial_settings
)
# TODO: work out
tests/test_schemas.py
View file @
a02c84e1
...
...
@@ -25,6 +25,7 @@ data_dir = Path(__file__).parent / Path("data")
setting_jsons_data
=
[
(
data_dir
/
Path
(
"valid_settings.json"
),
True
),
(
data_dir
/
Path
(
"valid_partial_settings.json"
),
True
),
(
data_dir
/
Path
(
"settings_wrong_types.json"
),
False
),
(
data_dir
/
Path
(
"settings_invalid_values.json"
),
False
)
]
...
...
tox.ini
View file @
a02c84e1
[tox]
envlist
=
py
27, py34
envlist
=
py
35
[testenv]
usedevelop
=
True
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment