14
|
1 '''Classes and functions for working with variant callers.
|
|
2
|
|
3 Created on 22 Sep 2015
|
|
4
|
|
5 @author: alex
|
|
6 '''
|
|
7 import glob
|
|
8 import inspect
|
|
9 import logging
|
|
10 import os
|
|
11 import sys
|
|
12
|
|
13 from phe.variant import VariantCaller
|
|
14
|
|
15 def dynamic_caller_loader():
|
|
16 """Fancy way of dynamically importing existing variant callers.
|
|
17
|
|
18 Returns
|
|
19 -------
|
|
20 dict:
|
|
21 Available variant callers dictionary. Keys are parameters that
|
|
22 can be used to call variants.
|
|
23 """
|
|
24
|
|
25 # We assume the caller are in the same directory as THIS file.
|
|
26 variants_dir = os.path.dirname(__file__)
|
|
27 variants_dir = os.path.abspath(variants_dir)
|
|
28
|
|
29 # This is populated when the module is first imported.
|
|
30 avail_callers = {}
|
|
31
|
|
32 # Add this directory to the syspath.
|
|
33 sys.path.insert(0, variants_dir)
|
|
34
|
|
35 # Find all "py" files.
|
|
36 for caller_mod in glob.glob(os.path.join(variants_dir, "*.py")):
|
|
37
|
|
38 # Derive name of the module where caller is.
|
|
39 caller_mod_file = os.path.basename(caller_mod)
|
|
40
|
|
41 # Ignore __init__ file, only base class is there.
|
|
42 if caller_mod_file.startswith("__init__"):
|
|
43 continue
|
|
44
|
|
45 # Import the module with a caller.
|
|
46 mod = __import__(caller_mod_file.replace(".pyc", "").replace(".py", ""))
|
|
47
|
|
48 # Find all the classes contained in this module.
|
|
49 classes = inspect.getmembers(mod, inspect.isclass)
|
|
50 for cls_name, cls in classes:
|
|
51 # For each class, if it is a sublass of VariantCaller, add it.
|
|
52 if cls_name != "VariantCaller" and issubclass(cls, VariantCaller):
|
|
53 # The name is inherited and defined within each caller.
|
|
54 avail_callers[cls.name] = cls
|
|
55
|
|
56 sys.path.remove(variants_dir)
|
|
57
|
|
58 return avail_callers
|
|
59
|
|
60 _avail_variant_callers = dynamic_caller_loader()
|
|
61
|
|
62 def available_callers():
|
|
63 """Return list of available variant callers."""
|
|
64 return _avail_variant_callers.keys()
|
|
65
|
|
66 def factory(variant=None, custom_options=None):
|
|
67 """Make an instance of a variant class.
|
|
68
|
|
69 Parameters:
|
|
70 -----------
|
|
71 variant: str, optional
|
|
72 Name of the variant class to instantiate.
|
|
73 custom_options: str, optional
|
|
74 Custom options to be passed directly to the implementing class.
|
|
75
|
|
76 Returns:
|
|
77 --------
|
|
78 :py:class:`phe.variant.VariantCaller`:
|
|
79 Instance of the :py:class:`phe.variant.VariantCaller` for given
|
|
80 variant name, or None if one couldn't be found.
|
|
81 """
|
|
82 if variant is not None and isinstance(variant, str):
|
|
83
|
|
84 variant = variant.lower()
|
|
85 if variant in _avail_variant_callers:
|
|
86 return _avail_variant_callers[variant](cmd_options=custom_options)
|
|
87 else:
|
|
88 logging.error("No implementation for %s mapper.")
|
|
89 return None
|
|
90
|
|
91 logging.warn("Unknown parameters. Mapper could not be initialised.")
|
|
92 return None
|