You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

112 line
3.4 KiB

  1. from pysam.libcutils import _pysam_dispatch
  2. class SamtoolsError(Exception):
  3. '''exception raised in case of an error incurred in the samtools
  4. library.'''
  5. def __init__(self, value):
  6. self.value = value
  7. def __str__(self):
  8. return repr(self.value)
  9. class PysamDispatcher(object):
  10. '''The dispatcher emulates the samtools/bctools command line.
  11. Captures stdout and stderr.
  12. Raises a :class:`pysam.SamtoolsError` exception in case samtools
  13. exits with an error code other than 0.
  14. Some command line options are associated with parsers. For
  15. example, the samtools command "pileup -c" creates a tab-separated
  16. table on standard output. In order to associate parsers with
  17. options, an optional list of parsers can be supplied. The list
  18. will be processed in order checking for the presence of each
  19. option.
  20. If no parser is given or no appropriate parser is found, the
  21. stdout output of samtools/bcftools commands will be returned.
  22. '''
  23. dispatch = None
  24. parsers = None
  25. collection = None
  26. def __init__(self, collection, dispatch, parsers):
  27. self.collection = collection
  28. self.dispatch = dispatch
  29. self.parsers = parsers
  30. self.stderr = []
  31. def __call__(self, *args, **kwargs):
  32. '''execute a samtools command.
  33. Keyword arguments:
  34. catch_stdout -- redirect stdout from the samtools command and
  35. return as variable (default True)
  36. save_stdout -- redirect stdout to a filename.
  37. raw -- ignore any parsers associated with this samtools command.
  38. split_lines -- return stdout (if catch_stdout is True and stderr
  39. as a list of strings.
  40. '''
  41. retval, stderr, stdout = _pysam_dispatch(
  42. self.collection,
  43. self.dispatch,
  44. args,
  45. catch_stdout=kwargs.get("catch_stdout", True),
  46. save_stdout=kwargs.get("save_stdout", None))
  47. if kwargs.get("split_lines", False):
  48. stdout = stdout.splitlines()
  49. if stderr:
  50. stderr = stderr.splitlines()
  51. if retval:
  52. raise SamtoolsError(
  53. "%s returned with error %i: "
  54. "stdout=%s, stderr=%s" %
  55. (self.collection,
  56. retval,
  57. stdout,
  58. stderr))
  59. self.stderr = stderr
  60. # call parser for stdout:
  61. if not kwargs.get("raw") and stdout and self.parsers:
  62. for options, parser in self.parsers:
  63. for option in options:
  64. if option not in args:
  65. break
  66. else:
  67. return parser(stdout)
  68. return stdout
  69. def get_messages(self):
  70. return self.stderr
  71. def usage(self):
  72. '''return the samtools usage information for this command'''
  73. retval, stderr, stdout = _pysam_dispatch(
  74. self.collection,
  75. self.dispatch,
  76. is_usage=True,
  77. catch_stdout=True)
  78. # some tools write usage to stderr, such as mpileup
  79. if stderr:
  80. return stderr
  81. else:
  82. return stdout
  83. class unquoted_str(str):
  84. '''Tag a value as an unquoted string. Meta-information in the VCF
  85. header takes the form of key=value pairs. By default, pysam will
  86. enclose the value in quotation marks. Tagging that value with
  87. unquoted_str will prevent this quoting.'''