def free_end_dist(mols, shs):
    filler, filler_cm = {}, []
    matrix = {}
    shell, rdf = [0] * shs, [0] * shs
    box, isomer_hash, mol_list = mols.box, mols.isomer_hash, mols.molecular_list
    molecular_bodies_list = mols.molecular_bodies_list
    mol_type_list = mols.molecular_types_list
    pos = mols.nodes['position']
    masses = mols.masses
    boxmin = min(box.x, box.y, box.z)
    check = boxmin/ 2 / shs
    for key in isomer_hash.keys():
        if MoleCules.is_filler_p(molecular_bodies_list, key) == 1:
            filler[key] = isomer_hash[key]
            continue
        matrix[key] = isomer_hash[key]
    fillerlen = 0
    for molecules in filler.values():
        for molecule in molecules:
            #print(molecule)
            #print(mol_list[molecule])
            fillerlen += len(mol_list[molecule])
            filler_cm.append(cm_no_image(mol_list[molecule], mol_type_list[molecule], pos, masses, box))
    rhom = (mols.natoms - fillerlen) / box.x / box.y / box.z
    m = 0
    for cm in filler_cm:
        for molecules in matrix.values():
            for molecule in iter(molecules):
                m += 2
                mol = mol_list[molecule]
                ends = mol[0]
                ende = mol[-1]
                poss = pos[ends]
                pose = pos[ende]
                diste = pbc_pos(pose - cm, box).mod
                dists = pbc_pos(poss - cm, box).mod
                if diste < boxmin / 2:
                    shell[int(diste/check)] += 1
                if dists < boxmin / 2:
                    shell[int(dists/check)] += 1
                for mdx in mol_list[molecule]:
                    p = pos[mdx]
                    dist = pbc_pos(p - cm, box).mod
                    if dist < boxmin / 2:
                        rdf[int(dist/check)]+=1
    rho = m / box.x / box.y / box.z
    for i in range(shs):
        dv = 4/3 * math.pi * (((i+1)*check)**3 - (i*check)**3)
        shell[i] /= dv * len(filler_cm) * rho
        rdf[i] /= dv * len(filler_cm) * rhom
    return shell, rdf, check
def chaindist(ranges, shs):
    from sys import argv

    analyzed = 0
    for filename in argv[1:]:
        res = {}
        rhodict = {}
        matrix = {}
        filler = {}
        filler_cm = []
        mols = MoleCules(filename, no_graph_tool, analyzed=analyzed)
        if analyzed == 0:
            masses = mols.masses
            mol_list = mols.molecular_list
            mol_type_list = mols.molecular_types_list
            isomer_hash = mols.isomer_hash
            molecular_bodies_list = mols.molecular_bodies_list
        analyzed += 1
        for ran in ranges:
            res["%s" % (ran,)] = [0] * shs
            rhodict["%s" % (ran,)] = 0
        box = mols.box
        boxmin = min(box.x, box.y, box.z)
        check = boxmin / 2 / shs
        pos = mols.nodes['position']
        moldict = {}
        for key in isomer_hash.keys():
            if MoleCules.is_filler_p(molecular_bodies_list, key) == 1:
                filler[key] = isomer_hash[key]
                continue
            matrix[key] = isomer_hash[key]
            moldict[len(mol_list[key])] = [0] * shs
        for molecules in filler.values():
            for molecule in molecules:
                # print(molecule)
                # print(mol_list[molecule])
                filler_cm.append(cm_no_image(mol_list[molecule], mol_type_list[molecule], pos, masses, box))
        for cm in filler_cm:
            for molecules in matrix.values():
                for molecule in iter(molecules):
                    mollen = len(mol_list[molecule])
                    # cmmol = cm_no_image(mol_list[molecule], mol_type_list[molecule], pos, masses, box)
                    for ran in ranges:
                        s = ran[0]
                        e = ran[1]
                        if s <= mollen < e:
                            rhodict["%s" % (ran,)] += mollen
                    for mdx in iter(mol_list[molecule]):
                        dist = pbc_pos(pos[mdx] - cm, box).mod
                        if dist < boxmin / 2:
                            # moldict[mollen][int(dist/check)] += 1
                            idx = int(dist/check)
                            for ran in ranges:
                                s = ran[0]
                                e = ran[1]
                                if s <= mollen < e:
                                    res["%s" % (ran,)][idx] += 1
        for k in rhodict:
            rhodict[k]/=box.x * box.y * box.z
        for i in range(shs):
            dv = 4 / 3 * math.pi * (((i + 1) * check) ** 3 - (i * check) ** 3)
            for k in res:
                res[k][i] /= dv # * rhodict[k]
            # for key in moldict.keys():
            # moldict[key][i] /= dv * rhodict[key]
        o = open(filename + '.chd', 'w')
        p = open(filename + '.rho', 'w')
        # o.write("#r %s\n" % ' '.join([str(key) for key in moldict.keys()]))
        kl = [ str(x) for x in ranges ]
        o.write("#r %s\n" % (' '.join(kl)))
        p.write("#r %s\n" % (' '.join(kl)))
        s = ''
        for k in kl:
            s += ' '+ str(rhodict[k])
        p.write(s+'\n')
        p.close()
        for i in range(shs):
            s = ''
            for k in kl:
                # o.write("%s %s\n" % ((i+0.5)*check, ' '.join([str(moldict[key][i]) for key in moldict.keys()])))
                s += ' '+ str(res[k][i])
            o.write("%s %s\n" % ((i + 0.5) * check, s))
        o.close()