|  | 
| 20 | 20 | from diffpy.srreal.pdfcalculator import PDFCalculator | 
| 21 | 21 | from diffpy.structure import Structure | 
| 22 | 22 | 
 | 
| 23 |  | -mydir = os.path.dirname(os.path.abspath(__file__)) | 
| 24 |  | -mentholcif = os.path.join(mydir, "datafiles", "menthol.cif") | 
| 25 |  | -Uisodefault = 0.005 | 
| 26 |  | - | 
| 27 |  | -# configure options parsing | 
| 28 |  | -parser = optparse.OptionParser("%prog [options]\n" + __doc__) | 
| 29 |  | -parser.add_option( | 
| 30 |  | -    "--pyobjcryst", | 
| 31 |  | -    action="store_true", | 
| 32 |  | -    help="Use pyobjcryst to load the CIF file.", | 
| 33 |  | -) | 
| 34 |  | -parser.allow_interspersed_args = True | 
| 35 |  | -opts, args = parser.parse_args(sys.argv[1:]) | 
| 36 | 23 | 
 | 
| 37 | 24 | # load menthol structure and make sure Uiso values are non-zero | 
| 38 |  | -if opts.pyobjcryst: | 
| 39 |  | -    # use pyobjcryst if requested by the user | 
| 40 |  | -    from numpy import pi | 
| 41 |  | -    from pyobjcryst.crystal import create_crystal_from_cif | 
| 42 |  | - | 
| 43 |  | -    menthol = create_crystal_from_cif(mentholcif) | 
| 44 |  | -    for sc in menthol.GetScatteringComponentList(): | 
| 45 |  | -        sp = sc.mpScattPow | 
| 46 |  | -        sp.Biso = sp.Biso or 8 * pi**2 * Uisodefault | 
| 47 |  | -else: | 
| 48 |  | -    # or use diffpy.structure by default | 
| 49 |  | -    menthol = Structure(filename=mentholcif) | 
| 50 |  | -    for a in menthol: | 
| 51 |  | -        a.Uisoequiv = a.Uisoequiv or Uisodefault | 
| 52 |  | - | 
| 53 |  | -# configuration of a PDF calculator | 
| 54 |  | -cfg = { | 
| 55 |  | -    "qmax": 25, | 
| 56 |  | -    "rmin": 0, | 
| 57 |  | -    "rmax": 30, | 
| 58 |  | -} | 
| 59 |  | - | 
| 60 |  | -# number of CPUs for parallel calculation | 
| 61 |  | -ncpu = multiprocessing.cpu_count() | 
| 62 |  | - | 
| 63 |  | -# calculate PDF on a single core | 
| 64 |  | -t0 = time.time() | 
| 65 |  | -pc0 = PDFCalculator(**cfg) | 
| 66 |  | -r0, g0 = pc0(menthol) | 
| 67 |  | -t0 = time.time() - t0 | 
| 68 |  | -print("Calculation time on 1 CPU: %g" % t0) | 
| 69 |  | - | 
| 70 |  | -# create a pool of workers | 
| 71 |  | -pool = multiprocessing.Pool(processes=ncpu) | 
| 72 |  | - | 
| 73 |  | -t1 = time.time() | 
| 74 |  | -# create a proxy parallel calculator to PDFCalculator pc0, | 
| 75 |  | -# that uses ncpu parallel jobs submitted via pool.imap_unordered | 
| 76 |  | -pc1 = createParallelCalculator(pc0, ncpu, pool.imap_unordered) | 
| 77 |  | -r1, g1 = pc1(menthol) | 
| 78 |  | -t1 = time.time() - t1 | 
| 79 |  | -print("Calculation time on %i CPUs: %g" % (ncpu, t1)) | 
| 80 |  | -print("Time ratio: %g" % (t0 / t1)) | 
| 81 |  | - | 
| 82 |  | -# plot both results and the difference curve | 
| 83 |  | - | 
| 84 |  | -clf() | 
| 85 |  | -gd = g0 - g1 | 
| 86 |  | -plot(r0, g0, r1, g1, r0, gd - 3) | 
| 87 |  | -show() | 
|  | 25 | +def load_structure(opts, mentholcif, Uisodefault): | 
|  | 26 | +    if opts.pyobjcryst: | 
|  | 27 | +        # use pyobjcryst if requested by the user | 
|  | 28 | +        from numpy import pi | 
|  | 29 | +        from pyobjcryst.crystal import create_crystal_from_cif | 
|  | 30 | + | 
|  | 31 | +        menthol = create_crystal_from_cif(mentholcif) | 
|  | 32 | +        for sc in menthol.GetScatteringComponentList(): | 
|  | 33 | +            sp = sc.mpScattPow | 
|  | 34 | +            sp.Biso = sp.Biso or 8 * pi**2 * Uisodefault | 
|  | 35 | +    else: | 
|  | 36 | +        # or use diffpy.structure by default | 
|  | 37 | +        menthol = Structure(filename=mentholcif) | 
|  | 38 | +        for a in menthol: | 
|  | 39 | +            a.Uisoequiv = a.Uisoequiv or Uisodefault | 
|  | 40 | +    return menthol | 
|  | 41 | + | 
|  | 42 | + | 
|  | 43 | +def calculate_pdf(menthol, cfg, ncpu): | 
|  | 44 | +    # calculate PDF on a single core | 
|  | 45 | +    t0 = time.time() | 
|  | 46 | +    pc0 = PDFCalculator(**cfg) | 
|  | 47 | +    r0, g0 = pc0(menthol) | 
|  | 48 | +    t0 = time.time() - t0 | 
|  | 49 | +    print(f"Calculation time on 1 CPU: {t0:g}") | 
|  | 50 | + | 
|  | 51 | +    # create a pool of workers | 
|  | 52 | +    pool = multiprocessing.Pool(processes=ncpu) | 
|  | 53 | + | 
|  | 54 | +    t1 = time.time() | 
|  | 55 | +    # create a proxy parallel calculator to PDFCalculator pc0, | 
|  | 56 | +    # that uses ncpu parallel jobs submitted via pool.imap_unordered | 
|  | 57 | +    pc1 = createParallelCalculator(pc0, ncpu, pool.imap_unordered) | 
|  | 58 | +    r1, g1 = pc1(menthol) | 
|  | 59 | +    t1 = time.time() - t1 | 
|  | 60 | +    pool.close() | 
|  | 61 | +    pool.join() | 
|  | 62 | + | 
|  | 63 | +    print(f"Calculation time on {ncpu} CPUs: {t1:g}") | 
|  | 64 | +    print(f"Time ratio: {t0 / t1:g}") | 
|  | 65 | + | 
|  | 66 | +    # plot both results and the difference curve | 
|  | 67 | + | 
|  | 68 | +    clf() | 
|  | 69 | +    gd = g0 - g1 | 
|  | 70 | +    plot(r0, g0, label="1 CPU") | 
|  | 71 | +    plot(r1, g1, label=f"{ncpu} CPUs") | 
|  | 72 | +    plot(r0, gd - 3, label="Difference − 3") | 
|  | 73 | +    show() | 
|  | 74 | + | 
|  | 75 | + | 
|  | 76 | +def main(): | 
|  | 77 | +    mydir = os.path.dirname(os.path.abspath(__file__)) | 
|  | 78 | +    mentholcif = os.path.join(mydir, "datafiles", "menthol.cif") | 
|  | 79 | +    Uisodefault = 0.005 | 
|  | 80 | + | 
|  | 81 | +    # configure options parsing | 
|  | 82 | +    parser = optparse.OptionParser("%prog [options]\n" + __doc__) | 
|  | 83 | +    parser.add_option( | 
|  | 84 | +        "--pyobjcryst", | 
|  | 85 | +        action="store_true", | 
|  | 86 | +        help="Use pyobjcryst to load the CIF file.", | 
|  | 87 | +    ) | 
|  | 88 | +    parser.allow_interspersed_args = True | 
|  | 89 | +    opts, args = parser.parse_args(sys.argv[1:]) | 
|  | 90 | + | 
|  | 91 | +    # load the structure | 
|  | 92 | +    menthol = load_structure(opts, mentholcif, Uisodefault) | 
|  | 93 | + | 
|  | 94 | +    # configuration of a PDF calculator | 
|  | 95 | +    cfg = {"qmax": 25, "rmin": 0, "rmax": 30} | 
|  | 96 | + | 
|  | 97 | +    # number of CPUs for parallel calculation | 
|  | 98 | +    ncpu = multiprocessing.cpu_count() | 
|  | 99 | +    calculate_pdf(menthol, cfg, ncpu) | 
|  | 100 | + | 
|  | 101 | + | 
|  | 102 | +if __name__ == "__main__": | 
|  | 103 | +    multiprocessing.freeze_support() | 
|  | 104 | +    main() | 
0 commit comments