|
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