nodes: 0, module; 1, function_definition; 2, function_name:tsses; 3, parameters; 4, block; 5, identifier:db; 6, default_parameter; 7, default_parameter; 8, default_parameter; 9, default_parameter; 10, default_parameter; 11, default_parameter; 12, expression_statement; 13, expression_statement; 14, if_statement; 15, if_statement; 16, if_statement; 17, function_definition; 18, comment:# GFF/GTF format; 19, expression_statement; 20, comment:# Figure out default attrs to use, depending on the original format.; 21, if_statement; 22, if_statement; 23, if_statement; 24, return_statement; 25, identifier:merge_overlapping; 26, False; 27, identifier:attrs; 28, None; 29, identifier:attrs_sep; 30, string:":"; 31, identifier:merge_kwargs; 32, None; 33, identifier:as_bed6; 34, False; 35, identifier:bedtools_227_or_later; 36, True; 37, comment:"""
      Create 1-bp transcription start sites for all transcripts in the database
      and return as a sorted pybedtools.BedTool object pointing to a temporary
      file.
  
      To save the file to a known location, use the `.moveto()` method on the
      resulting `pybedtools.BedTool` object.
  
      To extend regions upstream/downstream, see the `.slop()` method on the
      resulting `pybedtools.BedTool object`.
  
      Requires pybedtools.
  
      Parameters
      ----------
      db : gffutils.FeatureDB
          The database to use
  
      as_bed6 : bool
          If True, output file is in BED6 format; otherwise it remains in the
          GFF/GTF format and dialect of the file used to create the database.
  
          Note that the merge options below necessarily force `as_bed6=True`.
  
      merge_overlapping : bool
          If True, output will be in BED format. Overlapping TSSes will be merged
          into a single feature, and their names will be collapsed using
          `merge_sep` and placed in the new name field.
  
      merge_kwargs : dict
          If `merge_overlapping=True`, these keyword arguments are passed to
          pybedtools.BedTool.merge(), which are in turn sent to `bedtools merge`.
          The merge operates on a BED6 file which will have had the name field
          constructed as specified by other arguments here.  See the available
          options for your installed version of BEDTools; the defaults used here
          are `merge_kwargs=dict(o='distinct', c=4, s=True)`.
  
          Any provided `merge_kwargs` are used to *update* the default. It is
          recommended to not override `c=4` and `s=True`, otherwise the
          post-merge fixing may not work correctly. Good candidates for tweaking
          are `d` (merge distance), `o` (operation), `delim` (delimiter to use
          for collapse operations).
  
      attrs : str or list
          Only has an effect when `as_bed6=True` or `merge_overlapping=True`.
  
          Determines what goes in the name field of an output BED file. By
          default, "gene_id" for GTF databases and "ID" for GFF. If a list of
          attributes is supplied, e.g. ["gene_id", "transcript_id"], then these
          will be joined by `attr_join_sep` and then placed in the name field.
  
      attrs_sep: str
          If `as_bed6=True` or `merge_overlapping=True`, then use this character
          to separate attributes in the name field of the output BED. If also
          using `merge_overlapping=True`, you'll probably want this to be
          different than `merge_sep` in order to parse things out later.
  
      bedtools_227_or_later : bool
          In version 2.27, BEDTools changed the output for merge. By default,
          this function expects BEDTools version 2.27 or later, but set this to
          False to assume the older behavior.
  
          For testing purposes, the environment variable
          GFFUTILS_USES_BEDTOOLS_227_OR_LATER is set to either "true" or "false"
          and is used to override this argument.
  
      Examples
      --------
  
      >>> import gffutils
      >>> db = gffutils.create_db(
      ...    gffutils.example_filename('FBgn0031208.gtf'),
      ...    ":memory:",
      ...    keep_order=True,
      ...    verbose=False)
  
      Default settings -- no merging, and report a separate TSS on each line even
      if they overlap (as in the first two):
  
  
      >>> print(tsses(db))                        # doctest: +NORMALIZE_WHITESPACE
      chr2L	gffutils_derived	transcript_TSS	7529	7529	.	+	.	gene_id "FBgn0031208"; transcript_id "FBtr0300689";
      chr2L	gffutils_derived	transcript_TSS	7529	7529	.	+	.	gene_id "FBgn0031208"; transcript_id "FBtr0300690";
      chr2L	gffutils_derived	transcript_TSS	11000	11000	.	-	.	gene_id "Fk_gene_1"; transcript_id "transcript_Fk_gene_1";
      chr2L	gffutils_derived	transcript_TSS	12500	12500	.	-	.	gene_id "Fk_gene_2"; transcript_id "transcript_Fk_gene_2";
      <BLANKLINE>
  
  
      Default merging, showing the first two TSSes merged and reported as
      a single unique TSS for the gene. Note the conversion to BED:
  
      >>> x = tsses(db, merge_overlapping=True)
      >>> print(x)  # doctest: +NORMALIZE_WHITESPACE
      chr2L	7528	7529	FBgn0031208	.	+
      chr2L	10999	11000	Fk_gene_1	.	-
      chr2L	12499	12500	Fk_gene_2	.	-
      <BLANKLINE>
  
      Report both gene ID and transcript ID in the name. In some cases this can
      be easier to parse than the original GTF or GFF file. With no merging
      specified, we must add `as_bed6=True` to see the names in BED format.
  
      >>> x = tsses(db, attrs=['gene_id', 'transcript_id'], as_bed6=True)
      >>> print(x)  # doctest: +NORMALIZE_WHITESPACE
      chr2L	7528	7529	FBgn0031208:FBtr0300689	.	+
      chr2L	7528	7529	FBgn0031208:FBtr0300690	.	+
      chr2L	10999	11000	Fk_gene_1:transcript_Fk_gene_1	.	-
      chr2L	12499	12500	Fk_gene_2:transcript_Fk_gene_2	.	-
      <BLANKLINE>
  
      Use a 3kb merge distance so the last 2 features are merged together:
  
      >>> x = tsses(db, merge_overlapping=True, merge_kwargs=dict(d=3000))
      >>> print(x)  # doctest: +NORMALIZE_WHITESPACE
      chr2L	7528	7529	FBgn0031208	.	+
      chr2L	10999	12500	Fk_gene_1,Fk_gene_2	.	-
      <BLANKLINE>
  
  
      The set of unique TSSes for each gene, +1kb upstream and 500bp downstream:
  
      >>> x = tsses(db, merge_overlapping=True)
      >>> x = x.slop(l=1000, r=500, s=True, genome='dm3')
      >>> print(x)  # doctest: +NORMALIZE_WHITESPACE
      chr2L	6528	8029	FBgn0031208	.	+
      chr2L	10499	12000	Fk_gene_1	.	-
      chr2L	11999	13500	Fk_gene_2	.	-
      <BLANKLINE>
  
  
      """; 38, assignment; 39, comparison_operator:_override is not None; 40, block; 41, identifier:bedtools_227_or_later; 42, block; 43, else_clause; 44, comparison_operator:merge_kwargs is not None; 45, block; 46, function_name:gen; 47, parameters; 48, block; 49, assignment; 50, comparison_operator:attrs is None; 51, block; 52, boolean_operator; 53, block; 54, identifier:merge_overlapping; 55, block; 56, identifier:x; 57, identifier:_override; 58, call; 59, identifier:_override; 60, None; 61, if_statement; 62, expression_statement; 63, block; 64, identifier:merge_kwargs; 65, None; 66, expression_statement; 67, expression_statement; 68, for_statement; 69, identifier:x; 70, call; 71, identifier:attrs; 72, None; 73, if_statement; 74, identifier:merge_overlapping; 75, identifier:as_bed6; 76, if_statement; 77, function_definition; 78, expression_statement; 79, if_statement; 80, attribute; 81, argument_list; 82, comparison_operator:_override == 'true'; 83, block; 84, elif_clause; 85, else_clause; 86, assignment; 87, expression_statement; 88, call; 89, comment:"""
          Generator of pybedtools.Intervals representing TSSes.
          """; 90, identifier:gene; 91, call; 92, block; 93, attribute; 94, argument_list; 95, comparison_operator:db.dialect['fmt'] == 'gtf'; 96, block; 97, else_clause; 98, call; 99, block; 100, function_name:to_bed; 101, parameters; 102, block; 103, assignment; 104, identifier:bedtools_227_or_later; 105, block; 106, else_clause; 107, attribute; 108, identifier:get; 109, string; 110, None; 111, identifier:_override; 112, string; 113, expression_statement; 114, comparison_operator:_override == 'false'; 115, block; 116, block; 117, identifier:_merge_kwargs; 118, call; 119, assignment; 120, attribute; 121, argument_list; 122, attribute; 123, argument_list; 124, for_statement; 125, call; 126, identifier:sort; 127, subscript; 128, string; 129, expression_statement; 130, block; 131, identifier:isinstance; 132, argument_list; 133, expression_statement; 134, identifier:f; 135, expression_statement; 136, expression_statement; 137, return_statement; 138, identifier:x; 139, call; 140, expression_statement; 141, block; 142, identifier:os; 143, identifier:environ; 144, string_content:GFFUTILS_USES_BEDTOOLS_227_OR_LATER; 145, string_content:true; 146, assignment; 147, identifier:_override; 148, string; 149, expression_statement; 150, raise_statement; 151, identifier:dict; 152, argument_list; 153, identifier:_merge_kwargs; 154, call; 155, identifier:_merge_kwargs; 156, identifier:update; 157, identifier:merge_kwargs; 158, identifier:db; 159, identifier:features_of_type; 160, string; 161, identifier:transcript; 162, call; 163, block; 164, attribute; 165, argument_list; 166, attribute; 167, string; 168, string_content:gtf; 169, assignment; 170, expression_statement; 171, identifier:attrs; 172, attribute; 173, assignment; 174, comment:"""
              Given a pybedtools.Interval, return a new Interval with the name
              set according to the kwargs provided above.
              """; 175, assignment; 176, call; 177, attribute; 178, argument_list; 179, assignment; 180, function_definition; 181, expression_statement; 182, identifier:bedtools_227_or_later; 183, True; 184, string_content:false; 185, assignment; 186, call; 187, keyword_argument; 188, keyword_argument; 189, keyword_argument; 190, identifier:dict; 191, argument_list; 192, string_content:gene; 193, attribute; 194, argument_list; 195, if_statement; 196, expression_statement; 197, expression_statement; 198, identifier:pybedtools; 199, identifier:BedTool; 200, call; 201, identifier:db; 202, identifier:dialect; 203, string_content:fmt; 204, identifier:attrs; 205, string; 206, assignment; 207, identifier:six; 208, identifier:string_types; 209, identifier:attrs; 210, list; 211, identifier:name; 212, call; 213, attribute; 214, argument_list; 215, call; 216, identifier:saveas; 217, identifier:x; 218, call; 219, function_name:fix_merge; 220, parameters; 221, block; 222, assignment; 223, identifier:bedtools_227_or_later; 224, False; 225, identifier:ValueError; 226, argument_list; 227, identifier:o; 228, string; 229, identifier:s; 230, True; 231, identifier:c; 232, string; 233, keyword_argument; 234, keyword_argument; 235, keyword_argument; 236, identifier:db; 237, identifier:children; 238, identifier:gene; 239, keyword_argument; 240, comparison_operator:transcript.strand == '-'; 241, block; 242, else_clause; 243, assignment; 244, yield; 245, identifier:gen; 246, argument_list; 247, string_content:gene_id; 248, identifier:attrs; 249, string; 250, identifier:attrs; 251, attribute; 252, argument_list; 253, identifier:pybedtools; 254, identifier:Interval; 255, attribute; 256, attribute; 257, attribute; 258, identifier:name; 259, call; 260, attribute; 261, attribute; 262, argument_list; 263, attribute; 264, argument_list; 265, identifier:f; 266, expression_statement; 267, return_statement; 268, identifier:x; 269, call; 270, call; 271, string_content:distinct; 272, string_content:4,5,6; 273, identifier:o; 274, string; 275, identifier:s; 276, True; 277, identifier:c; 278, string; 279, identifier:level; 280, integer:1; 281, attribute; 282, string; 283, expression_statement; 284, block; 285, attribute; 286, binary_operator:transcript.featuretype + '_TSS'; 287, call; 288, string_content:ID; 289, identifier:attrs_sep; 290, identifier:join; 291, list_comprehension; 292, identifier:f; 293, identifier:chrom; 294, identifier:f; 295, identifier:start; 296, identifier:f; 297, identifier:stop; 298, identifier:str; 299, argument_list; 300, identifier:f; 301, identifier:strand; 302, identifier:x; 303, identifier:each; 304, identifier:to_bed; 305, identifier:x; 306, identifier:merge; 307, dictionary_splat; 308, assignment; 309, call; 310, attribute; 311, argument_list; 312, attribute; 313, argument_list; 314, string_content:distinct; 315, string_content:4; 316, identifier:transcript; 317, identifier:strand; 318, string_content:-; 319, assignment; 320, expression_statement; 321, identifier:transcript; 322, identifier:featuretype; 323, attribute; 324, string; 325, attribute; 326, argument_list; 327, subscript; 328, for_in_clause; 329, attribute; 330, identifier:_merge_kwargs; 331, identifier:f; 332, call; 333, attribute; 334, argument_list; 335, call; 336, identifier:saveas; 337, concatenated_string; 338, identifier:format; 339, identifier:_override; 340, attribute; 341, attribute; 342, assignment; 343, identifier:transcript; 344, identifier:featuretype; 345, string_content:_TSS; 346, identifier:helpers; 347, identifier:asinterval; 348, identifier:transcript; 349, attribute; 350, identifier:i; 351, identifier:i; 352, identifier:attrs; 353, identifier:f; 354, identifier:score; 355, attribute; 356, argument_list; 357, identifier:pybedtools; 358, identifier:Interval; 359, attribute; 360, attribute; 361, attribute; 362, subscript; 363, string; 364, subscript; 365, attribute; 366, argument_list; 367, string:"Unknown value for GFFUTILS_USES_BEDTOOLS_227_OR_LATER "; 368, string:"environment variable: {0}"; 369, identifier:transcript; 370, identifier:start; 371, identifier:transcript; 372, identifier:stop; 373, attribute; 374, attribute; 375, identifier:f; 376, identifier:attrs; 377, identifier:featurefuncs; 378, identifier:extend_fields; 379, identifier:f; 380, integer:6; 381, identifier:f; 382, identifier:chrom; 383, identifier:f; 384, identifier:start; 385, identifier:f; 386, identifier:stop; 387, identifier:f; 388, integer:4; 389, string_content:.; 390, identifier:f; 391, integer:3; 392, call; 393, identifier:each; 394, identifier:fix_merge; 395, identifier:transcript; 396, identifier:stop; 397, identifier:transcript; 398, identifier:start; 399, attribute; 400, argument_list; 401, call; 402, identifier:saveas; 403, attribute; 404, argument_list; 405, identifier:x; 406, identifier:merge; 407, dictionary_splat; 408, identifier:_merge_kwargs
code: def tsses(db, merge_overlapping=False, attrs=None, attrs_sep=":",
            merge_kwargs=None, as_bed6=False, bedtools_227_or_later=True):
      """
      Create 1-bp transcription start sites for all transcripts in the database
      and return as a sorted pybedtools.BedTool object pointing to a temporary
      file.
  
      To save the file to a known location, use the `.moveto()` method on the
      resulting `pybedtools.BedTool` object.
  
      To extend regions upstream/downstream, see the `.slop()` method on the
      resulting `pybedtools.BedTool object`.
  
      Requires pybedtools.
  
      Parameters
      ----------
      db : gffutils.FeatureDB
          The database to use
  
      as_bed6 : bool
          If True, output file is in BED6 format; otherwise it remains in the
          GFF/GTF format and dialect of the file used to create the database.
  
          Note that the merge options below necessarily force `as_bed6=True`.
  
      merge_overlapping : bool
          If True, output will be in BED format. Overlapping TSSes will be merged
          into a single feature, and their names will be collapsed using
          `merge_sep` and placed in the new name field.
  
      merge_kwargs : dict
          If `merge_overlapping=True`, these keyword arguments are passed to
          pybedtools.BedTool.merge(), which are in turn sent to `bedtools merge`.
          The merge operates on a BED6 file which will have had the name field
          constructed as specified by other arguments here.  See the available
          options for your installed version of BEDTools; the defaults used here
          are `merge_kwargs=dict(o='distinct', c=4, s=True)`.
  
          Any provided `merge_kwargs` are used to *update* the default. It is
          recommended to not override `c=4` and `s=True`, otherwise the
          post-merge fixing may not work correctly. Good candidates for tweaking
          are `d` (merge distance), `o` (operation), `delim` (delimiter to use
          for collapse operations).
  
      attrs : str or list
          Only has an effect when `as_bed6=True` or `merge_overlapping=True`.
  
          Determines what goes in the name field of an output BED file. By
          default, "gene_id" for GTF databases and "ID" for GFF. If a list of
          attributes is supplied, e.g. ["gene_id", "transcript_id"], then these
          will be joined by `attr_join_sep` and then placed in the name field.
  
      attrs_sep: str
          If `as_bed6=True` or `merge_overlapping=True`, then use this character
          to separate attributes in the name field of the output BED. If also
          using `merge_overlapping=True`, you'll probably want this to be
          different than `merge_sep` in order to parse things out later.
  
      bedtools_227_or_later : bool
          In version 2.27, BEDTools changed the output for merge. By default,
          this function expects BEDTools version 2.27 or later, but set this to
          False to assume the older behavior.
  
          For testing purposes, the environment variable
          GFFUTILS_USES_BEDTOOLS_227_OR_LATER is set to either "true" or "false"
          and is used to override this argument.
  
      Examples
      --------
  
      >>> import gffutils
      >>> db = gffutils.create_db(
      ...    gffutils.example_filename('FBgn0031208.gtf'),
      ...    ":memory:",
      ...    keep_order=True,
      ...    verbose=False)
  
      Default settings -- no merging, and report a separate TSS on each line even
      if they overlap (as in the first two):
  
  
      >>> print(tsses(db))                        # doctest: +NORMALIZE_WHITESPACE
      chr2L	gffutils_derived	transcript_TSS	7529	7529	.	+	.	gene_id "FBgn0031208"; transcript_id "FBtr0300689";
      chr2L	gffutils_derived	transcript_TSS	7529	7529	.	+	.	gene_id "FBgn0031208"; transcript_id "FBtr0300690";
      chr2L	gffutils_derived	transcript_TSS	11000	11000	.	-	.	gene_id "Fk_gene_1"; transcript_id "transcript_Fk_gene_1";
      chr2L	gffutils_derived	transcript_TSS	12500	12500	.	-	.	gene_id "Fk_gene_2"; transcript_id "transcript_Fk_gene_2";
      <BLANKLINE>
  
  
      Default merging, showing the first two TSSes merged and reported as
      a single unique TSS for the gene. Note the conversion to BED:
  
      >>> x = tsses(db, merge_overlapping=True)
      >>> print(x)  # doctest: +NORMALIZE_WHITESPACE
      chr2L	7528	7529	FBgn0031208	.	+
      chr2L	10999	11000	Fk_gene_1	.	-
      chr2L	12499	12500	Fk_gene_2	.	-
      <BLANKLINE>
  
      Report both gene ID and transcript ID in the name. In some cases this can
      be easier to parse than the original GTF or GFF file. With no merging
      specified, we must add `as_bed6=True` to see the names in BED format.
  
      >>> x = tsses(db, attrs=['gene_id', 'transcript_id'], as_bed6=True)
      >>> print(x)  # doctest: +NORMALIZE_WHITESPACE
      chr2L	7528	7529	FBgn0031208:FBtr0300689	.	+
      chr2L	7528	7529	FBgn0031208:FBtr0300690	.	+
      chr2L	10999	11000	Fk_gene_1:transcript_Fk_gene_1	.	-
      chr2L	12499	12500	Fk_gene_2:transcript_Fk_gene_2	.	-
      <BLANKLINE>
  
      Use a 3kb merge distance so the last 2 features are merged together:
  
      >>> x = tsses(db, merge_overlapping=True, merge_kwargs=dict(d=3000))
      >>> print(x)  # doctest: +NORMALIZE_WHITESPACE
      chr2L	7528	7529	FBgn0031208	.	+
      chr2L	10999	12500	Fk_gene_1,Fk_gene_2	.	-
      <BLANKLINE>
  
  
      The set of unique TSSes for each gene, +1kb upstream and 500bp downstream:
  
      >>> x = tsses(db, merge_overlapping=True)
      >>> x = x.slop(l=1000, r=500, s=True, genome='dm3')
      >>> print(x)  # doctest: +NORMALIZE_WHITESPACE
      chr2L	6528	8029	FBgn0031208	.	+
      chr2L	10499	12000	Fk_gene_1	.	-
      chr2L	11999	13500	Fk_gene_2	.	-
      <BLANKLINE>
  
  
      """
      _override = os.environ.get('GFFUTILS_USES_BEDTOOLS_227_OR_LATER', None)
      if _override is not None:
          if _override == 'true':
              bedtools_227_or_later = True
          elif _override == 'false':
              bedtools_227_or_later = False
          else:
              raise ValueError(
                  "Unknown value for GFFUTILS_USES_BEDTOOLS_227_OR_LATER "
                  "environment variable: {0}".format(_override))
  
      if bedtools_227_or_later:
          _merge_kwargs = dict(o='distinct', s=True, c='4,5,6')
      else:
          _merge_kwargs = dict(o='distinct', s=True, c='4')
  
      if merge_kwargs is not None:
          _merge_kwargs.update(merge_kwargs)
  
      def gen():
          """
          Generator of pybedtools.Intervals representing TSSes.
          """
          for gene in db.features_of_type('gene'):
              for transcript in db.children(gene, level=1):
                  if transcript.strand == '-':
                      transcript.start = transcript.stop
                  else:
                      transcript.stop = transcript.start
                  transcript.featuretype = transcript.featuretype + '_TSS'
                  yield helpers.asinterval(transcript)
  
      # GFF/GTF format
      x = pybedtools.BedTool(gen()).sort()
  
      # Figure out default attrs to use, depending on the original format.
      if attrs is None:
          if db.dialect['fmt'] == 'gtf':
              attrs = 'gene_id'
          else:
              attrs = 'ID'
  
      if merge_overlapping or as_bed6:
  
          if isinstance(attrs, six.string_types):
              attrs = [attrs]
  
          def to_bed(f):
              """
              Given a pybedtools.Interval, return a new Interval with the name
              set according to the kwargs provided above.
              """
              name = attrs_sep.join([f.attrs[i] for i in attrs])
              return pybedtools.Interval(
                  f.chrom,
                  f.start,
                  f.stop,
                  name,
                  str(f.score),
                  f.strand)
  
          x = x.each(to_bed).saveas()
  
      if merge_overlapping:
          if bedtools_227_or_later:
              x = x.merge(**_merge_kwargs)
          else:
              def fix_merge(f):
                  f = featurefuncs.extend_fields(f, 6)
                  return pybedtools.Interval(
                      f.chrom,
                      f.start,
                      f.stop,
                      f[4],
                      '.',
                      f[3])
              x = x.merge(**_merge_kwargs).saveas().each(fix_merge).saveas()
  
      return x