def analyze(arg):
    bin_size, results = arg
    
    found=False
    trials=0
    while len(results) < COMPARISONS:
        r1, r2 = random.sample(routes, 2)
        while not bin_size <= distance(r1, r2) <= bin_size + BIN_SIZE and trials < 10000:
            r1, r2 = random.sample(routes, 2)
            if not found: trials += 1

        if trials >= 10000: return (bin_size, [])
        else: found=True
            
        lat_range = min((r1[0], r2[0])), max((r1[0], r2[0]))
        lon_range = min((r1[1], r2[1])), max((r1[1], r2[1]))
        
        species_pool = []
        for route in (r1,r2):
            for sp, count in routes[route].iteritems():
                species_pool += [sp] * count

        try:
            result = metrics.process(routes[r1], routes[r2], tree, species_pool)
            if not result: continue
        except IndexError:
            # this means a species wasn't found in our tree
            continue
        
        print bin_size, result
        results.append(result)
    
    return (bin_size, results)
def analyze(arg):
    grid, routes = arg
    species_pool = []
    for route in routes.values():
        for sp, count in route.iteritems(): 
            species_pool += [sp] * count

    n = len(routes)
    
    # compare all combinations of routes if n choose 2 < COMPARISONS,
    # otherwise compare random combinations until you reach COMBINATIONS
    # total comparisons
    comparisons = n*(n-1) / 2
    if comparisons < COMPARISONS:
        to_compare = ((r1, r2) for r1 in routes for r2 in routes if not r1 == r2)
    else:
        def random_comparison():
            while True:
                yield tuple(sorted(random.sample(routes.keys(), 2)))
        to_compare = random_comparison()
    
    # compare pairs of communities
    comms = []
    while len(comms) < min(COMPARISONS, comparisons):
        try: r1, r2 = next(to_compare)
        except StopIteration: break
    
        if len(routes[r1]) < 2 or len(routes[r2]) < 2: continue
    
        try:
            result = metrics.process(routes[r1], routes[r2], tree, species_pool)
            if not result: continue
            comms.append(result)
        except IndexError:
            # this means a species wasn't found in our tree
            pass
    
    print '**', grid, time.strftime('%D %T')
    results = {}
    for result in sorted(set(comms)):
        percent = 100*len([c for c in comms if c == result]) / float(len(comms))
        print '%s: %s%%' % (result, percent)
        results[result] = percent
    
    return grid, results