Merge intervals in a bed file when the intervals have the same name.
    Intervals with the same name must be adjacent in the bed file.
497204
def merge_bed_by_name(bt):
    
    name_lines = dict()
    for r in bt:
        name = r.name
        name_lines[name] = name_lines.get(name, []) + [[r.chrom, r.start, 
                                                         r.end, r.name,
                                                         r.strand]]
    new_lines = []
    for name in name_lines.keys():
        new_lines += _merge_interval_list(name_lines[name])
    new_lines = ['\t'.join(map(str, x)) for x in new_lines]
    return pbt.BedTool('\n'.join(new_lines) + '\n', from_string=True)
1038772
def merge(a, b):
    
    _check_steps(a, b)
    return range(min(a.start, b.start), max(a.stop, b.stop))
821201
def merge(intervals):
        
        out = []
        for i in sorted(intervals, key=lambda i: i.start):
            if out and i.start <= out[-1].end:
                out[-1].end = max(out[-1].end, i.end)
            else:
                out += i,
        return out
180606
def do_interval( sources, index, out, ref_src, start, end, seq_db, missing_data, strand ):
    
    ref_src_size = None
    # Make sure the reference component is also the first in the source list
    assert sources[0].split('.')[0] == ref_src.split('.')[0], "%s != %s" \
        % ( sources[0].split('.')[0], ref_src.split('.')[0] )
    # Determine the overall length of the interval
    base_len = end - start
    # Counter for the last reference species base we have processed
    last_stop = start
    # Rows in maf blocks come in in arbitrary order, we'll convert things
    # to the destred order of the tiled block
    source_to_index = dict( ( name, i ) for ( i, name ) in enumerate( sources ) )
    # This gets all the maf blocks overlapping our interval of interest
    # NOTE: Unlike maf_tile we're expecting 
    # things to be single coverage in the reference species, so we won't 
    # sort by score and lay down.
    blocks = index.get( ref_src, start, end )
    # The last component seen for each species onto which we are tiling
    last_components = [ None ] * len( sources )
    last_status = [ None ] * len( sources )
    cols_needing_fill = [ 0 ] * len( sources )
    # The list of strings in which we build up the tiled alignment
    tiled_rows = [ "" for i in range( len( sources ) ) ]
    # Enumerate the (ordered) list of blocks
    for i, block in enumerate( blocks ):
        # Check for overlap in reference species
        ref = block.get_component_by_src_start( ref_src )
        if ref.start < last_stop:
            if ref.end < last_stop: 
                continue
            block = block.slice_by_component( ref, last_stop, min( end, ref.end ) )
            ref = block.get_component_by_src_start( ref_src )
        block = block.slice_by_component( ref, max( start, ref.start ), min( end, ref.end ) )
        ref = block.get_component_by_src_start( ref_src )
        # print block
        assert last_components[0] is None or ref.start >= last_components[0].end, \
            "MAF must be sorted and single coverage in reference species!"
        assert ref.strand == "+", \
            "MAF must have all reference species blocks on the plus strand"
        # Store the size of the reference sequence for building fake block   
        if ref_src_size is None:
            ref_src_size = ref.src_size
        # Handle the reference component seperately, it has no synteny status
        # but we will try to fill in missing sequence
        if ref.start > last_stop:
            # Need to fill in some reference sequence
            chunk_len = ref.start - last_stop
            text = bx.seq.nib.NibFile( open( seq_db[ ref_src ] ) ).get( last_stop, chunk_len ) 
            tiled_rows[0] += text
            for source in sources[1:]:
                cols_needing_fill[ source_to_index[ source ] ] += chunk_len
        # Do reference component
        chunk_len = len( ref.text )
        tiled_rows[0] += ref.text
        # Do each other component
        for source in sources[1:]:
            source_index = source_to_index[ source ]
            comp = block.get_component_by_src_start( source )
            if comp:
                if comp.synteny_left is None:
                    left_status, left_length = None, -1
                else:
                    left_status, left_length = comp.synteny_left
                if comp.synteny_right is None:
                    right_status, right_length = None, -1
                else:
                    right_status, right_length = comp.synteny_right
                # We have a component, do we need to do some filling?
                cols_to_fill = cols_needing_fill[ source_index ]
                if cols_to_fill > 0:
                    # Adjacent components should have matching status
                    ## assert last_status[ source_index ] is None or last_status[ source_index ] == left_status, \
                    ##     "left status (%s) does not match right status (%s) of last component for %s" \
                    ##         % ( left_status, last_status[ source_index ], source )
                    if left_status is None:
                        fill_char = guess_fill_char( last_components[source_index], comp )
                    else:
                        fill_char = get_fill_char( left_status )
                    tiled_rows[ source_index ] += ( fill_char * cols_to_fill )
                    cols_needing_fill[ source_index ] = 0
                # Okay, filled up to current position, now append the text
                tiled_rows[ source_index ] += comp.text
                assert len( tiled_rows[ source_index ] ) == len( tiled_rows[ 0 ] ), \
                    "length of tiled row should match reference row"
                last_components[ source_index ] = comp
                last_status[ source_index ] = right_status
            else:
                # No component, we'll have to fill this region when we know
                # the status
                cols_needing_fill[ source_index ] += chunk_len
        last_stop = ref.end
    # No more components, clean up the ends
    if last_stop < end:
        # Need to fill in some reference sequence
        chunk_len = end - last_stop
        tiled_rows[0] += bx.seq.nib.NibFile( open( seq_db[ ref_src ] ) ).get( last_stop, chunk_len ) 
        for source in sources[1:]:
            cols_needing_fill[ source_to_index[ source ] ] += chunk_len
    # Any final filling that needs to be done?
    for source in sources[1:]:
        source_index = source_to_index[ source ]
        fill_needed = cols_needing_fill[ source_index ]
        if fill_needed > 0:
            if last_components[ source_index ] is None:
                # print >>sys.stderr, "Never saw any components for %s, filling with @" % source
                fill_char = '@'
            else:
                if last_status[ source_index ] is None:
                    fill_char = '*'
                else:
                    fill_char = get_fill_char( last_status[ source_index ] )
            tiled_rows[ source_index ] += fill_char * fill_needed
        assert len( tiled_rows[ source_index ] ) == len( tiled_rows[ 0 ] ), \
            "length of tiled row should match reference row"
    # Okay, now make up the fake alignment from the tiled rows.
    tiled_rows = remove_all_gap_columns( tiled_rows )
    a = align.Alignment()
    for i, name in enumerate( sources ):
        text = "".join( tiled_rows[i] )
        size = len( text ) - text.count( "-" )
        if i == 0:
            if ref_src_size is None: ref_src_size = bx.seq.nib.NibFile( open( seq_db[ ref_src ] ) ).length
            c = align.Component( ref_src, start, end-start, "+", ref_src_size, text )
        else:
            c = align.Component( name + ".fake", 0, size, "?", size, text )
        a.add_component( c )
    if strand == '-':
        a = a.reverse_complement()
    out.write( a )
1074823
@Override
    public void merge(ROC other) {
        if (this.thresholdSteps != other.thresholdSteps) {
            throw new UnsupportedOperationException(
                    "Cannot merge ROC instances with different numbers of threshold steps ("
                            + this.thresholdSteps + " vs. " + other.thresholdSteps + ")");
        }
        this.countActualPositive += other.countActualPositive;
        this.countActualNegative += other.countActualNegative;
        this.auc = null;
        this.auprc = null;
        this.rocCurve = null;
        this.prCurve = null;


        if (isExact) {
            if (other.exampleCount == 0) {
                return;
            }

            if (this.exampleCount == 0) {
                this.exampleCount = other.exampleCount;
                this.probAndLabel = other.probAndLabel;
                return;
            }

            if (this.exampleCount + other.exampleCount > this.probAndLabel.size(0)) {
                //Allocate new array
                val newSize = this.probAndLabel.size(0) + Math.max(other.probAndLabel.size(0), exactAllocBlockSize);
                INDArray newProbAndLabel = Nd4j.create(DataType.DOUBLE, newSize, 2);
                newProbAndLabel.put(new INDArrayIndex[]{interval(0, exampleCount), all()}, probAndLabel.get(interval(0, exampleCount), all()));
                probAndLabel = newProbAndLabel;
            }

            INDArray toPut = other.probAndLabel.get(interval(0, other.exampleCount), all());
            probAndLabel.put(new INDArrayIndex[]{
                            interval(exampleCount, exampleCount + other.exampleCount), all()},
                    toPut);
        } else {
            for (Double d : this.counts.keySet()) {
                CountsForThreshold cft = this.counts.get(d);
                CountsForThreshold otherCft = other.counts.get(d);
                cft.countTruePositive += otherCft.countTruePositive;
                cft.countFalsePositive += otherCft.countFalsePositive;
            }
        }

        this.exampleCount += other.exampleCount;
    }
810306
def bed_to_bedpe(bedfile, bedpefile, pairsbedfile=None, matesfile=None, ca=False, strand=False):
    
    fp = must_open(bedfile)
    fw = must_open(bedpefile, "w")
    if pairsbedfile:
        fwpairs = must_open(pairsbedfile, "w")

    clones = defaultdict(list)
    for row in fp:
        b = BedLine(row)
        name = b.accn
        clonename = clone_name(name, ca=ca)
        clones[clonename].append(b)

    if matesfile:
        fp = open(matesfile)
        libraryline = next(fp)
        # 'library bes     37896   126916'
        lib, name, smin, smax = libraryline.split()
        assert lib == "library"
        smin, smax = int(smin), int(smax)
        logging.debug("Happy mates for lib {0} fall between {1} - {2}".\
                      format(name, smin, smax))

    nbedpe = 0
    nspan = 0
    for clonename, blines in clones.items():
        nlines = len(blines)
        if nlines == 2:
            a, b = blines
            aseqid, astart, aend = a.seqid, a.start, a.end
            bseqid, bstart, bend = b.seqid, b.start, b.end
            outcols = [aseqid, astart - 1, aend, bseqid, bstart - 1, bend, clonename]
            if strand:
                outcols.extend([0, a.strand, b.strand])
            print("\t".join(str(x) for x in outcols), file=fw)
            nbedpe += 1
        elif nlines == 1:
            a, = blines
            aseqid, astart, aend = a.seqid, a.start, a.end
            bseqid, bstart, bend = 0, 0, 0
        else:  # More than two lines per pair
            pass

        if pairsbedfile:
            start = min(astart, bstart) if bstart > 0 else astart
            end = max(aend, bend) if bend > 0 else aend
            if aseqid != bseqid:
                continue

            span = end - start + 1
            if (not matesfile) or (smin <= span <= smax):
                print("\t".join(str(x) for x in \
                        (aseqid, start - 1, end, clonename)), file=fwpairs)
                nspan += 1

    fw.close()
    logging.debug("A total of {0} bedpe written to `{1}`.".\
                  format(nbedpe, bedpefile))
    if pairsbedfile:
        fwpairs.close()
        logging.debug("A total of {0} spans written to `{1}`.".\
                      format(nspan, pairsbedfile))
1066258
def _merge_fields(a, b):
    

    a_names = set(x[0] for x in a)
    b_names = set(x[0] for x in b)
    a_keep = a_names - b_names

    fields = []

    for name, field in a:
        if name in a_keep:
            fields.append((name, field))

    fields.extend(b)

    return fields
653373
def add(self, interval, offset):
        
        start, stop = self.get_start_stop(interval)

        if len(self.starts) > 0:
            if start < self.starts[-1] or offset <= self.offsets[-1][1]:
                raise ValueError('intervals and offsets must be added in-order')
            self.offsets[-1][1] = offset
            self.offsets[-1][2] += 1
        else:
            self.starts.append(start)
            self.stops.append(stop)
            self.offsets.append([offset, offset, 1])
302728
def sort_merge(in_file, data, out_dir=None):
    
    out_file = "%s-sortmerge.bed" % os.path.splitext(in_file)[0]
    bedtools = config_utils.get_program("bedtools", data, default="bedtools")
    if out_dir:
        out_file = os.path.join(out_dir, os.path.basename(out_file))
    if not utils.file_uptodate(out_file, in_file):
        column_opt = ""
        with utils.open_gzipsafe(in_file) as in_handle:
            for line in in_handle:
                if not line.startswith(("#", "track", "browser", "@")):
                    parts = line.split()
                    if len(parts) >= 4:
                        column_opt = "-c 4 -o distinct"
        with file_transaction(data, out_file) as tx_out_file:
            cat_cmd = "zcat" if in_file.endswith(".gz") else "cat"
            sort_cmd = get_sort_cmd(os.path.dirname(tx_out_file))
            cmd = ("{cat_cmd} {in_file} | {sort_cmd} -k1,1 -k2,2n | "
                   "{bedtools} merge -i - {column_opt} > {tx_out_file}")
            do.run(cmd.format(**locals()), "Sort and merge BED file", data)
    return out_file
1325237
static TimingInterval merge(Iterable<TimingInterval> intervals, int maxSamples, long start)
    {
        ThreadLocalRandom rnd = ThreadLocalRandom.current();
        long operationCount = 0, partitionCount = 0, rowCount = 0, errorCount = 0;
        long maxLatency = 0, totalLatency = 0;
        List<SampleOfLongs> latencies = new ArrayList<>();
        long end = 0;
        long pauseStart = 0, pauseEnd = Long.MAX_VALUE;
        for (TimingInterval interval : intervals)
        {
            if (interval != null)
            {
                end = Math.max(end, interval.end);
                operationCount += interval.operationCount;
                maxLatency = Math.max(interval.maxLatency, maxLatency);
                totalLatency += interval.totalLatency;
                partitionCount += interval.partitionCount;
                rowCount += interval.rowCount;
                errorCount += interval.errorCount;
                latencies.addAll(Arrays.asList(interval.sample));
                if (interval.pauseLength > 0)
                {
                    pauseStart = Math.max(pauseStart, interval.pauseStart);
                    pauseEnd = Math.min(pauseEnd, interval.pauseStart + interval.pauseLength);
                }
            }
        }

        if (pauseEnd < pauseStart || pauseStart <= 0)
        {
            pauseEnd = pauseStart = 0;
        }

        return new TimingInterval(start, end, maxLatency, pauseStart, pauseEnd - pauseStart, partitionCount, rowCount,
                                  totalLatency, operationCount, errorCount, SampleOfLongs.merge(rnd, latencies, maxSamples));

    }
178483
def add(self, interval: Interval) -> None:
        
        if interval is None:
            return
        if not isinstance(interval, Interval):
            raise TypeError(
                "Attempt to insert non-Interval into IntervalList")
        self.intervals.append(interval)
        self._tidy()
1099944
def _merge_outfile_fname(out_file, bam_files, work_dir, batch):
    
    if out_file is None:
        out_file = os.path.join(work_dir, os.path.basename(sorted(bam_files)[0]))
    if batch is not None:
        base, ext = os.path.splitext(out_file)
        out_file = "%s-b%s%s" % (base, batch, ext)
    return out_file
533998
def intersect_two(f1, f2, work_dir, data):
    
    bedtools = config_utils.get_program("bedtools", data, default="bedtools")
    f1_exists = f1 and utils.file_exists(f1)
    f2_exists = f2 and utils.file_exists(f2)
    if not f1_exists and not f2_exists:
        return None
    elif f1_exists and not f2_exists:
        return f1
    elif f2_exists and not f1_exists:
        return f2
    else:
        out_file = os.path.join(work_dir, "%s-merged.bed" % (utils.splitext_plus(os.path.basename(f1))[0]))
        if not utils.file_exists(out_file):
            with file_transaction(data, out_file) as tx_out_file:
                cmd = "{bedtools} intersect -a {f1} -b {f2} > {tx_out_file}"
                do.run(cmd.format(**locals()), "Intersect BED files", data)
        return out_file
160249
def fill(args):
    
    p = OptionParser(fill.__doc__)
    p.add_option("--extend", default=2000, type="int",
                 help="Extend seq flanking the gaps [default: %default]")
    opts, args = p.parse_args(args)

    if len(args) != 2:
        sys.exit(not p.print_help())

    gapsbed, badfasta = args
    Ext = opts.extend

    gapdist = 2 * Ext + 1  # This is to prevent to replacement ranges intersect
    gapsbed = mergeBed(gapsbed, d=gapdist, nms=True)

    bed = Bed(gapsbed)
    sizes = Sizes(badfasta).mapping
    pf = gapsbed.rsplit(".", 1)[0]
    extbed = pf + ".ext.bed"
    fw = open(extbed, "w")
    for b in bed:
        gapname = b.accn
        start, end = max(0, b.start - Ext - 1), b.start - 1
        print("\t".join(str(x) for x in \
                             (b.seqid, start, end, gapname + "L")), file=fw)
        start, end = b.end, min(sizes[b.seqid], b.end + Ext)
        print("\t".join(str(x) for x in \
                             (b.seqid, start, end, gapname + "R")), file=fw)
    fw.close()

    fastaFromBed(extbed, badfasta, name=True)
861446
def merge(args):
    
    from jcvi.apps.grid import MakeManager

    p = OptionParser(merge.__doc__)
    p.set_sep(sep="_", help="Separator to group per prefix")
    opts, args = p.parse_args(args)

    if len(args) < 2:
        sys.exit(not p.print_help())

    merged_bams = args[0]
    bamdirs = args[1:]

    mkdir(merged_bams)
    bams = []
    for x in bamdirs:
        bams += glob(op.join(x, "*.bam"))
    bams = [x for x in bams if "nsorted" not in x]

    logging.debug("Found a total of {0} BAM files.".format(len(bams)))

    sep = opts.sep
    key = lambda x: op.basename(x).split(sep)[0]
    bams.sort(key=key)
    mm = MakeManager()
    for prefix, files in groupby(bams, key=key):
        files = sorted(list(files))
        nfiles = len(files)
        source = " ".join(files)
        target = op.join(merged_bams, op.basename(files[0]))
        if nfiles == 1:
            source = get_abs_path(source)
            cmd = "ln -s {0} {1}".format(source, target)
            mm.add("", target, cmd)
        else:
            cmd = "samtools merge -@ 8 {0} {1}".format(target, source)
            mm.add(files, target, cmd, remove=True)
    mm.write()
637510
def subset_bed_by_chrom(in_file, chrom, data, out_dir=None):
    
    if out_dir is None:
        out_dir = os.path.dirname(in_file)
    base, ext = os.path.splitext(os.path.basename(in_file))
    out_file = os.path.join(out_dir, "%s-%s%s" % (base, chrom, ext))
    if not utils.file_uptodate(out_file, in_file):
        with file_transaction(data, out_file) as tx_out_file:
            _rewrite_bed_with_chrom(in_file, tx_out_file, chrom)
    return out_file
288961
def merge_from(self, other):
        """"""
        if other.national_number_pattern is not None:
            self.national_number_pattern = other.national_number_pattern
        if other.example_number is not None:
            self.example_number = other.example_number