1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 """PdfFit class for fitting pdf data to a model."""
17
18
19 import types
20
21
22
23
24
25 from diffpy.pdffit2 import pdffit2
26 from diffpy.pdffit2 import output
27
28
29
45
46
65
66
68 """Convert an object to the result of its call when callable.
69
70 var -- string or callable object that returns string
71
72 Return var or var().
73 """
74 if callable(var):
75 rv = var()
76 else:
77 rv = var
78 return rv
79
80
81
82
83 __intro_message__ = """
84 ******************************************************************************
85 * P D F F I T Version %(version)s *
86 * %(date)s *
87 * -------------------------------------------------------------------------- *
88 * (c) 1998-2007 Trustees of the Michigan State University. *
89 * (c) 2008-2016 Trustees of the Columbia University *
90 * in the city of New York. *
91 * *
92 * Authors: *
93 * Thomas Proffen - Email: tproffen@lanl.gov *
94 * Jacques Bloch - Email: bloch@pa.msu.edu *
95 * Christopher Farrow - Email: clf2121@columbia.edu *
96 * Pavol Juhas - Email: pjuhas@bnl.gov
97 * Simon Billinge - Email: sb2896@columbia.edu *
98 ******************************************************************************
99 """
100
101
102
103
104
106 """Create PdfFit object."""
107
108
109
110 selalias = { 'ALL' : -1 }
111
112 FCON = { 'USER' : 0, 'IDENT' : 1, 'FCOMP' : 2, 'FSQR' : 3 }
113
114 Sctp = { 'X' : 0, 'N' : 1 }
115
117 """ _exportAll(self, namespace) --> Export all 'public' class methods
118 into namespace.
119
120 This function allows for a module-level PdfFit object which doesn't have
121 to be referenced when calling a method. This function makes old (python)
122 scripts compatible with this class. At the top of the script, create a
123 pdffit object, and then call this method. Usually, namespace = locals().
124 """
125
126 for a in self.selalias.keys() + self.FCON.keys() + self.Sctp.keys():
127 exec("%s = %r" % (a, a), namespace)
128 public = [ a for a in dir(self) if "__" not in a and a not in
129 ["_handle", "_exportAll", "selalias", "FCON", "Sctp" ] ]
130 for funcname in public:
131 namespace[funcname] = getattr(self, funcname)
132 return
133
135 """Show introductory message.
136 """
137 import re
138 from diffpy.pdffit2 import __version__, __date__
139 date = __date__[:10]
140 d = {'version' : __version__, 'date' : date}
141 msg = __intro_message__ % d
142 filler = lambda mx : (mx.group(0).rstrip(' *').ljust(77) + '*')
143 msg_ljust = re.sub('(?m)^(.{1,77}|.{79}.*)$', filler, msg)
144 print >> output.stdout, msg_ljust
145 return
146 intro = staticmethod(intro)
147
148
150 """add_structure(stru) --> Add new structure to PdfFit instance.
151
152 stru -- instance of Structure class from diffpy.Structure.
153
154 No return value.
155 Raises pdffit2.structureError when stru contains unknown
156 atom species.
157 """
158 s = stru.writeStr('pdffit')
159 self.read_struct_string(s)
160 return
161
162
164 """read_struct(struct) --> Read structure from file into memory.
165
166 struct -- name of file from which to read structure
167
168 Raises:
169 pdffit2.calculationError when a lattice cannot be created from the
170 given structure
171 pdffit2.structureError when a structure file is malformed
172 IOError when the file cannot be read from the disk
173 """
174 pdffit2.read_struct(self._handle, struct)
175 self.stru_files.append(struct)
176 return
177
178
180 """read_struct_string(struct, name = "") --> Read structure from
181 a string into memory.
182
183 struct -- string containing the contents of the structure file
184 name -- tag with which to label structure
185
186 Raises:
187 pdffit2.calculationError when a lattice cannot be created from the
188 given structure
189 pdffit2.structureError when a structure file is malformed
190 """
191 pdffit2.read_struct_string(self._handle, struct)
192 self.stru_files.append(name)
193 return
194
195
196 - def read_data(self, data, stype, qmax, qdamp):
197 """read_data(data, stype, qmax, qdamp) --> Read pdf data from file into
198 memory.
199
200 data -- name of file from which to read data
201 stype -- 'X' (xray) or 'N' (neutron)
202 qmax -- Q-value cutoff used in PDF calculation.
203 Use qmax=0 to neglect termination ripples.
204 qdamp -- instrumental Q-resolution factor
205
206 Raises: IOError when the file cannot be read from disk
207 """
208 pdffit2.read_data(self._handle, data, stype, qmax, qdamp)
209 self.data_files.append(data)
210 return
211
212
214 """read_data_string(data, stype, qmax, qdamp, name = "") --> Read
215 pdf data from a string into memory.
216
217 data -- string containing the contents of the data file
218 stype -- 'X' (xray) or 'N' (neutron)
219 qmax -- Q-value cutoff used in PDF calculation.
220 Use qmax=0 to neglect termination ripples.
221 qdamp -- instrumental Q-resolution factor
222 name -- tag with which to label data
223 """
224 pdffit2.read_data_string(self._handle, data, stype, qmax,
225 qdamp, name)
226 name = data
227 self.data_files.append(name)
228 return
229
230
231 - def read_data_lists(self, stype, qmax, qdamp, r_data, Gr_data,
232 dGr_data = None, name = "list"):
233 """read_data_lists(stype, qmax, qdamp, r_data, Gr_data, dGr_data =
234 None, name = "list") --> Read pdf data into memory from lists.
235
236 All lists must be of the same length.
237 stype -- 'X' (xray) or 'N' (neutron)
238 qmax -- Q-value cutoff used in PDF calculation.
239 Use qmax=0 to neglect termination ripples.
240 qdamp -- instrumental Q-resolution factor
241 r_data -- list of r-values
242 Gr_data -- list of G(r) values
243 dGr_data -- list of G(r) uncertainty values
244 name -- tag with which to label data
245
246 Raises: ValueError when the data lists are of different length
247 """
248 pdffit2.read_data_arrays(self._handle, stype, qmax, qdamp,
249 r_data, Gr_data, dGr_data, name)
250 self.data_files.append(name)
251 return
252
253
255 """pdfrange(iset, rmin, rmax) --> Set the range of the fit.
256
257 iset -- data set to consider
258 rmin -- minimum r-value of fit
259 rmax -- maximum r-value of fit
260
261 Raises: ValueError for bad input values
262 """
263 pdffit2.pdfrange(self._handle, iset, rmin, rmax)
264 return
265
266
268 """reset() --> Clear all stored fit, structure, and parameter data."""
269 self.stru_files = []
270 self.data_files = []
271 pdffit2.reset(self._handle);
272 return
273
274
275 - def alloc(self, stype, qmax, qdamp, rmin, rmax, bin):
276 """alloc(stype, qmax, qdamp, rmin, rmax, bin) --> Allocate space
277 for a PDF calculation.
278
279 The structure from which to calculate the PDF must first be imported
280 with the read_struct() or read_struct_string() method.
281 stype -- 'X' (xray) or 'N' (neutron)
282 qmax -- Q-value cutoff used in PDF calculation.
283 Use qmax=0 to neglect termination ripples.
284 qdamp -- instrumental Q-resolution factor
285 rmin -- minimum r-value of calculation
286 rmax -- maximum r-value of calculation
287 bin -- number of data points in calculation
288
289 Raises:
290 ValueError for bad input values
291 pdffit.unassignedError when no structure has been loaded
292 """
293 pdffit2.alloc(self._handle, stype, qmax, qdamp, rmin,
294 rmax, bin)
295 return
296
297
299 """calc() --> Calculate the PDF of the imported structure.
300
301 Space for the calculation must first be allocated with the alloc()
302 method.
303
304 Raises:
305 pdffit2.calculationError when allocated space cannot
306 accomodate calculation
307 pdffit.unassignedError when space for calculation has not been
308 allocated
309 """
310 pdffit2.calc(self._handle)
311 return
312
313
314 - def refine(self, toler=0.00000001):
315 """refine(toler = 0.00000001) --> Fit the theory to the imported data.
316
317 toler -- tolerance of the fit
318
319 Raises:
320 pdffit2.calculationError when the model pdf cannot be calculated
321 pdffit2.constraintError when refinement fails due to bad
322 constraint
323 pdffit2.unassigedError when a constraint used but never initialized
324 using setpar()
325 """
326 step = 0
327 finished = 0
328 while not finished:
329 finished = pdffit2.refine_step(self._handle, toler)
330 step += 1
331 return
332
333
335 """refine_step(toler = 0.00000001) --> Run a single step of the fit.
336
337 toler -- tolerance of the fit
338
339 Raises:
340 pdffit2.calculationError when the model pdf cannot be calculated
341 pdffit2.constraintError when refinement fails due to bad
342 constraint
343 pdffit2.unassigedError when a constraint used but never initialized
344 using setpar()
345
346 Returns: 1 (0) if refinement is (is not) finished
347 """
348 self.finished = pdffit2.refine_step(self._handle, toler)
349 return self.finished
350
351
353 """save_pdf(iset, fname) --> Save calculated or fitted PDF to file.
354
355 iset -- data set to save
356
357 Raises:
358 IOError if file cannot be saved
359 pdffit2.unassignedError if the data set is undefined
360 """
361 pdffit2.save_pdf(self._handle, iset, fname)
362 return
363
364
366 """save_pdf_string(iset) --> Save calculated or fitted PDF to string.
367
368 iset -- data set to save
369
370 Raises:
371 pdffit2.unassignedError if the data set is undefined
372
373 Returns: string containing contents of save file
374 """
375 pdffilestring = pdffit2.save_pdf(self._handle, iset, "")
376 return pdffilestring
377
378
380 """save_dif(iset, fname) --> Save data and fitted PDF difference to
381 file.
382
383 iset -- data set to save
384
385 Raises:
386 IOError if file cannot be saved
387 pdffit2.unassignedError if the data set is undefined
388 """
389 pdffit2.save_dif(self._handle, iset, fname)
390 return
391
392
394 """save_dif_string(iset) --> Save data and fitted PDF difference to
395 string.
396
397 iset -- data set to save
398
399 Raises:
400 pdffit2.unassignedError if the data set is undefined
401
402 Returns: string containing contents of save file
403 """
404 diffilestring = pdffit2.save_dif(self._handle, iset, "")
405 return diffilestring
406
407
409 """save_res(fname) --> Save fit-specific data to file.
410
411 Raises:
412 IOError if file cannot be saved
413 pdffit2.unassignedError if there is no refinement data to save
414 """
415 pdffit2.save_res(self._handle, fname)
416 return
417
418
420 """save_res_string() --> Save fit-specific data to a string.
421
422 Raises:
423 pdffit2.unassignedError if there is no refinement data to save
424
425 Returns: string containing contents of save file
426 """
427 resfilestring = pdffit2.save_res(self._handle, "")
428 return resfilestring
429
430
432 """get_structure(ip) --> Get a copy of specified phase data.
433
434 ip -- index of existing PdfFit phase starting from 1
435
436 Return Structure object from diffpy.Structure.
437 Raise pdffit2.unassignedError if phase ip is undefined.
438 """
439 from diffpy.Structure import PDFFitStructure
440 s = self.save_struct_string(ip)
441 stru = PDFFitStructure()
442 stru.readStr(s, 'pdffit')
443 return stru
444
445
447 """save_struct(ip, fname) --> Save structure resulting from fit
448 to file.
449
450 ip -- phase to save
451
452 Raises:
453 IOError if file cannot be saved
454 pdffit2.unassignedError if the data set is undefined
455 """
456 pdffit2.save_struct(self._handle, ip, fname)
457 return
458
459
461 """save_struct(ip) --> Save structure resulting from fit to string.
462
463 ip -- phase to save
464
465 Raises:
466 pdffit2.unassignedError if phase ip is undefined.
467
468 Returns: string containing contents of save file
469 """
470 structfilestring = pdffit2.save_struct(self._handle, ip, "")
471 return structfilestring
472
473
475 """show_struct(ip) --> Print structure resulting from fit.
476
477 ip -- phase to display
478
479 Raises: pdffit2.unassignedError if the phase is undefined
480 """
481 pdffit2.show_struct(self._handle, ip)
482 return
483
484
486 """constrain(var, par[, fcon]) --> Constrain a variable to a parameter.
487
488 A variable can be constrained to a number or equation string.
489 var -- variable to constrain, such as x(1)
490 par -- parameter which to constrain the variable. This can be
491 an integer or an equation string containing a reference
492 to another parameter. Equation strings use standard c++
493 syntax. The value of a constrained parameter is accessed
494 as @p in an equation string, where p is the parameter.
495 e.g.
496 >>> constrain(x(1), 1)
497 >>> constrain(x(2), "0.5+@1")
498 fcon -- 'USER', 'IDENT', 'FCOMP', or 'FSQR'
499 this is an optional parameter, and I don't know how it is
500 used!
501
502 Raises:
503 pdffit2.constraintError if a constraint is bad
504 pdffit2.unassignedError if variable does not yet exist
505 ValueError if variable index does not exist (e.g. lat(7))
506 """
507 var_ref = self.__getRef(var)
508 varnc = _convertCallable(var)
509 if fcon:
510 fc = self.FCON[fcon]
511 pdffit2.constrain_int(self._handle, var_ref, varnc, par, fc)
512 elif type(par) == types.StringType:
513 pdffit2.constrain_str(self._handle, var_ref, varnc, par)
514 else:
515 pdffit2.constrain_int(self._handle, var_ref, varnc, par)
516 return
517
518
520 """setpar(par, val) --> Set value of constrained parameter.
521
522 val -- Either a numerical value or a reference to a variable
523
524 Raises:
525 pdffit2.unassignedError when variable is yet to be assigned
526 """
527
528
529 val = _convertCallable(val)
530 try:
531 val = float(val)
532 pdffit2.setpar_dbl(self._handle, par, val)
533 except ValueError:
534 var_ref = self.__getRef(val)
535 pdffit2.setpar_RV(self._handle, par, var_ref)
536 return
537
538
540 """setvar(var, val) --> Set the value of a variable.
541
542 Raises:
543 pdffit2.unassignedError if variable does not yet exist
544 ValueError if variable index does not exist (e.g. lat(7))
545 """
546 var_ref = self.__getRef(var)
547 pdffit2.setvar(self._handle, var_ref, val)
548 return
549
550
552 """getvar(var) --> Get stored value of a variable.
553
554 Raises:
555 pdffit2.unassignedError if variable does not yet exist
556 ValueError if variable index does not exist (e.g. lat(7))
557 """
558 var_ref = self.__getRef(var)
559 retval = pdffit2.getvar(self._handle, var_ref)
560 return retval
561
562
564 """getrw() --> Get normalized total error of the fit rw.
565
566 getrw calculates total fit error summed for all datasets in the fit.
567
568 Return float.
569 """
570 rw = pdffit2.getrw(self._handle)
571 return rw
572
573
575 """getcrw() --> Get cumulative Rw for the current dataset.
576
577 Cumulative Rw is a list of Rw partial sums cost values evaluated against
578 observed PDF data in the error sums evaluated against
579 the r-points in the fit.
580
581 Raises: pdffit2.unassignedError if no data exists
582
583 Returns: List of crw points, equidistant in r or empty list
584 if the refine function has not been called yet.
585 """
586 crw = pdffit2.getcrw(self._handle)
587 return crw
588
589
591 """getR() --> Get r-points used in the fit.
592
593 This function should only be called after data has been loaded or
594 calculated. Before a refinement, the list of r-points will reflect the
595 data. Afterwords, they will reflect the fit range.
596
597 Raises: pdffit2.unassignedError if no data exists
598
599 Returns: List of equidistance r-points used in fit.
600 """
601 R = pdffit2.getR(self._handle)
602 return R
603
604
606 """getpdf_fit() --> Get fitted PDF.
607
608 This function should only be called after a refinement or refinement
609 step has been done.
610
611 Raises: pdffit2.unassignedError if no data exists
612
613 Returns: List of fitted points, equidistant in r.
614 """
615 pdfdata = pdffit2.getpdf_fit(self._handle)
616 return pdfdata
617
618
620 """getpdf_obs() --> Get observed PDF.
621
622 This function should only be called after data has been loaded or
623 calculated. Before a refinement, the list of r-points will reflect the
624 data. Afterwords, they will reflect the fit range.
625
626 Raises: pdffit2.unassignedError if no data exists
627
628 Returns: List of data points, equidistant in r.
629 """
630 pdfdata = pdffit2.getpdf_obs(self._handle)
631 return pdfdata
632
633
635 """Obtain difference between observed and fitted PDF.
636
637 This function should only be called after data has been loaded or
638 calculated. Before a refinement, the list of r-points will reflect the
639 data. Afterwords, they will reflect the fit range.
640
641 Raises: pdffit2.unassignedError if no data exists
642
643 Returns: List of data points, equidistant in r.
644 """
645 Gdiff = pdffit2.getpdf_diff(self._handle)
646 return Gdiff
647
648
650 """get_atoms() --> Get element symbols of all atoms in the structure.
651
652 ip -- index of phase to get the elements from (starting from 1)
653 when ip is not given, use current phase
654
655 This function should only be called after a structure has been loaded.
656
657 Raises: pdffit2.unassignedError if no structure exists
658
659 Returns: List of atom names in structure.
660 """
661 if ip is None: rv = pdffit2.get_atoms(self._handle)
662 else: rv = pdffit2.get_atoms(self._handle, ip)
663 return rv
664
665
667 """get_atom_types() --> Ordered unique element symbols in the structure.
668
669 ip -- index of phase to get the elements from (starting from 1)
670 when ip is not given, use current phase
671
672 This function should only be called after a structure has been loaded.
673
674 Raises:
675 pdffit2.unassignedError if no structure exists
676
677 Returns: List of unique atom symbols as they occur in structure.
678 """
679 if ip is None: rv = pdffit2.get_atom_types(self._handle)
680 else: rv = pdffit2.get_atom_types(self._handle, ip)
681 return rv
682
683
685 """getpar(par) --> Get value of parameter.
686
687 Raises: ValueError if parameter does not exists
688 """
689 return pdffit2.getpar(self._handle, par)
690
691
693 """fixpar(par) --> Fix a parameter.
694
695 Fixed parameters are not fitted in a refinement. Passed parameter
696 can be 'ALL', in which case all parameters are fixed.
697
698 Raises: pdffit.unassignedError when parameter has not been assigned
699 """
700 if type(par) in types.StringTypes and par.upper() in self.selalias:
701 par = self.selalias[par.upper()]
702 pdffit2.fixpar(self._handle, par)
703 return
704
705
707 """freepar(par) --> Free a parameter.
708
709 Freed parameters are fitted in a refinement. Passed parameter
710 can be 'ALL', in which case all parameters are freed.
711
712 Raises: pdffit.unassignedError when parameter has not been assigned
713 """
714 if type(par) in types.StringTypes and par.upper() in self.selalias:
715 par = self.selalias[par.upper()]
716 pdffit2.freepar(self._handle, par)
717 return
718
719
721 """setphase(ip) --> Switch to phase ip.
722
723 ip -- index of the phase starting at 1.
724
725 All parameters assigned after this method is called refer only to the
726 current phase.
727
728 Raises: pdffit.unassignedError when phase does not exist
729 """
730 pdffit2.setphase(self._handle, ip)
731 return
732
733
735 """setdata(iset) --> Set the data set in focus.
736
737 iset -- integer index of data set starting at 1.
738
739 Raises: pdffit.unassignedError when data set does not exist
740 """
741 pdffit2.setdata(self._handle, iset)
742 return
743
744
745 - def psel(self, ip):
746 """psel(ip) --> Include phase ip in calculation of total PDF
747
748 psel('ALL') selects all phases for PDF calculation.
749
750 Raises: pdffit2.unassignedError if selected phase does not exist
751 """
752 if type(ip) in types.StringTypes and ip.upper() in self.selalias:
753 ip = self.selalias[ip.upper()]
754 pdffit2.psel(self._handle, ip)
755 return
756
757
759 """pdesel(ip) --> Exclude phase ip from calculation of total PDF.
760
761 pdesel('ALL') excludes all phases from PDF calculation.
762
763 Raises: pdffit2.unassignedError if selected phase does not exist
764 """
765 if type(ip) in types.StringTypes and ip.upper() in self.selalias:
766 ip = self.selalias[ip.upper()]
767 pdffit2.pdesel(self._handle, ip)
768 return
769
770
772 """Configure partial PDF - mark the specified atom type in phase ip
773 as included or excluded as a first or second in pair for distance
774 evaluation.
775
776 ip -- phase index starting at 1
777 ijchar -- 'i' or 'j' for first or second in pair
778 symbol -- element symbol
779 flag -- bool flag, True for selection, False for exclusion
780
781 Raises:
782 pdffit2.unassignedError if selected phase does not exist
783 ValueError for invalid value of ijchar
784 """
785 pdffit2.selectAtomType(self._handle, ip, ijchar, symbol, flag)
786 return
787
788
790 """Configure partial PDF - mark the atom of given index in phase ip
791 as included or excluded as a first or second in pair for distance
792 evaluation.
793
794 ip -- phase index starting at 1
795 ijchar -- 'i' or 'j' for first or second in pair
796 aidx -- integer index of atom starting at 1
797 flag -- bool flag, True for selection, False for exclusion
798
799 Raises:
800 pdffit2.unassignedError if selected phase does not exist
801 ValueError if atom index or ijchar are invalid
802 """
803 pdffit2.selectAtomIndex(self._handle, ip, ijchar, aidx, flag)
804 return
805
806
808 """Configure partial PDF - include all atoms of phase ip as first or
809 second element in pair for distance evaluation.
810
811 ip -- phase index starting at 1
812 ijchar -- 'i' or 'j' for first or second in pair
813
814 Raises:
815 pdffit2.unassignedError if selected phase does not exist
816 ValueError if ijchar is invalid
817 """
818 pdffit2.selectAll(self._handle, ip, ijchar)
819 return
820
821
823 """Configure partial PDF - exclude all atoms of phase ip from first
824 or second element of pair distance evaluation.
825
826 ip -- phase index starting at 1
827 ijchar -- 'i' or 'j' for first or second in pair
828
829 Raises:
830 pdffit2.unassignedError if selected phase does not exist
831 ValueError if ijchar is invalid
832 """
833 pdffit2.selectNone(self._handle, ip, ijchar)
834 return
835
836
837 - def bang(self, i, j, k):
838 """bang(i, j, k) --> Show bond angle defined by atoms i, j, k.
839
840 No return value. Use bond_angle() to get the result.
841
842 Raises: ValueError if selected atom(s) does not exist
843 pdffit.unassignedError when no structure has been loaded
844 """
845 angle, stdev = pdffit2.bond_angle(self._handle, i, j, k)
846
847 atom_symbols = self.get_atoms()
848 leader = " %s (#%i) - %s (#%i) - %s (#%i) = " % \
849 (atom_symbols[i-1], i, atom_symbols[j-1], j,
850 atom_symbols[k-1], k)
851 s = leader + _format_value_std(angle, stdev) + " degrees"
852 print >> output.stdout, s
853 return
854
855
857 """bond_angle(i, j, k) --> bond angle defined by atoms i, j, k.
858 Angle is calculated using the shortest ji and jk lengths with
859 respect to periodic boundary conditions.
860
861 i, j, k -- atom indices starting at 1
862
863 Return a tuple of (angle, angle_error), both values are in degrees.
864
865 Raises: ValueError if selected atom(s) does not exist
866 pdffit.unassignedError when no structure has been loaded
867 """
868 rv = pdffit2.bond_angle(self._handle, i, j, k)
869 return rv
870
871
872 - def blen(self, *args):
873 """blen(i, j) --> Show bond length defined by atoms i and j.
874
875 i -- index of the first atom starting at 1
876 j -- index of the second atom starting at 1
877
878 No return value. Use bond_length_atoms() to retrieve result.
879
880 Second form:
881
882 blen(a1, a2, lb, ub) --> Show sorted lengths of all a1-a2 bonds.
883
884 a1 -- symbol of the first element in pair or "ALL"
885 a2 -- symbol of the second element in pair or "ALL"
886 lb -- lower bond length boundary
887 ub -- upper bond length boundary
888
889 No return value. Use bond_length_types() to retrieve results.
890
891 Raises: ValueError if selected atom(s) does not exist
892 pdffit.unassignedError when no structure has been loaded
893 """
894
895 if len(args)==2:
896 dij, ddij = self.bond_length_atoms(*args[0:2])
897 atom_symbols = self.get_atoms()
898 ij = (args[0], args[1])
899
900 if min(ij) - 1 < 0 or max(ij) - 1 >= len(atom_symbols):
901 emsg = "Incorrect atom number(s): %i, %j" % ij
902 raise ValueError, emsg
903 symij = ( atom_symbols[ij[0] - 1].upper(),
904 atom_symbols[ij[1] - 1].upper() )
905 print >> output.stdout, _format_bond_length(dij, ddij, ij, symij)
906
907 elif len(args)==4:
908 a1, a2, lb, ub = args
909 try:
910 atom_types = self.get_atom_types()
911 if type(a1) is types.IntType: a1 = atom_types[a1 - 1]
912 if type(a2) is types.IntType: a2 = atom_types[a2 - 1]
913 except IndexError:
914
915 return
916
917 bld = pdffit2.bond_length_types(self._handle, a1, a2, lb, ub)
918 s = "(%s,%s) bond lengths in [%gA,%gA] for current phase :" % \
919 (a1, a2, lb, ub)
920 print >> output.stdout, s
921 atom_symbols = self.get_atoms()
922 npts = len(bld['dij'])
923 for idx in range(npts):
924 dij = bld['dij'][idx]
925 ddij = bld['ddij'][idx]
926 ij0 = bld['ij0'][idx]
927 ij1 = bld['ij1'][idx]
928 symij = (atom_symbols[ij0[0]], atom_symbols[ij0[1]])
929 s = _format_bond_length(dij, ddij, ij1, symij)
930 print >> output.stdout, s
931 print >> output.stdout
932 if not bld['dij']:
933 print >> output.stdout, " *** No pairs found ***"
934 else:
935 emsg = "blen() takes 2 or 4 arguments (%i given)" % len(args)
936 raise TypeError, emsg
937
938 return
939
940
942 """bond_length_atoms(i, j) --> shortest distance between atoms i, j.
943 Periodic boundary conditions are applied to find the shortest bond.
944
945 i -- index of the first atom starting at 1
946 j -- index of the second atom starting at 1
947
948 Return a tuple of (distance, distance_error).
949
950 Raises: ValueError if selected atom(s) does not exist
951 pdffit.unassignedError when no structure has been loaded.
952 """
953 rv = pdffit2.bond_length_atoms(self._handle, i, j)
954 return rv
955
956
958 """bond_length_types(a1, a2, lb, ub) --> get all a1-a2 distances.
959
960 a1 -- symbol of the first element in pair or "ALL"
961 a2 -- symbol of the second element in pair or "ALL"
962 lb -- lower bond length boundary
963 ub -- upper bond length boundary
964
965 Return a dictionary of distance data containing
966
967 dij : list of bond lenghts within given bounds
968 ddij : list of bond legnth standard deviations
969 ij0 : pairs of atom indices starting from 0
970 ij1 : pairs of atom indices starting from 1
971
972 Raises: ValueError if selected atom(s) does not exist
973 pdffit.unassignedError when no structure has been loaded.
974 """
975 rv = pdffit2.bond_length_types(self._handle, a1, a2, lb, ub)
976 return rv
977
978
980 """show_scat(stype) --> Print scattering length for all atoms in
981 the current phase.
982
983 stype -- 'X' (xray) or 'N' (neutron).
984
985 Raises: pdffit2.unassignedError if no phase exists
986 """
987 print >> output.stdout, self.get_scat_string(stype)
988 return
989
990
992 """get_scat_string(stype) --> Get string with scattering factors
993 of all atoms in the current phase.
994
995 stype -- 'X' (xray) or 'N' (neutron).
996
997 Raises:
998 pdffit2.unassignedError if no phase exists
999
1000 Returns: string with all scattering factors.
1001 """
1002 return pdffit2.get_scat_string(self._handle, stype)
1003
1004
1006 """get_scat(stype, element) --> Get active scattering factor for
1007 given element. If scattering factor has been changed using
1008 set_scat the result may depend on the active phase. When no
1009 phase has been loaded, return the standard value.
1010
1011 stype -- 'X' (xray) or 'N' (neutron).
1012 element -- case-insensitive element symbol such as "Na" or "CL"
1013
1014 Return float.
1015
1016 Raises:
1017 ValueError if element is not known.
1018 """
1019 rv = pdffit2.get_scat(self._handle, stype, element)
1020 return rv
1021
1022
1023 - def set_scat(self, stype, element, value):
1024 """set_scat(stype, element, value) --> Set custom scattering factor
1025 for given element. The new scattering factor applies only for the
1026 current phase, in other phases it keeps its default value.
1027
1028 stype -- 'X' (xray) or 'N' (neutron).
1029 element -- case-insensitive element symbol such as "Na" or "CL"
1030 value -- new value of scattering factor
1031
1032 No return value.
1033
1034 Raises:
1035 pdffit2.unassignedError if no phase exists.
1036 ValueError if element is not known.
1037
1038 See also reset_scat, get_scat.
1039 """
1040 pdffit2.set_scat(self._handle, stype, element, value)
1041 return
1042
1043
1045 """reset_scat(stype, element) --> Reset scattering factors for
1046 given element to their standard values. The reset_scat applies
1047 only for the current phase.
1048
1049 element -- case-insensitive element symbol such as "Na" or "CL"
1050 Raises:
1051 pdffit2.unassignedError if no phase exists
1052 ValueError if element is not known.
1053 """
1054 pdffit2.reset_scat(self._handle, element)
1055 return
1056
1057
1059 """num_atoms() --> Get number of atoms in current phase.
1060
1061 Raises: pdffit2.unassignedError if no atoms exist
1062 """
1063 return pdffit2.num_atoms(self._handle)
1064
1065
1067 """num_phases() --> Number of phases loaded in PdfFit instance.
1068
1069 Use setphase to bring a specific phase in focus.
1070
1071 Return integer.
1072 """
1073 n = pdffit2.num_phases(self._handle)
1074 return n
1075
1076
1078 """num_datasets() --> Number of datasets loaded in PdfFit instance.
1079
1080 Use setdata to bring a specific dataset in focus.
1081
1082 Return integer.
1083 """
1084 n = pdffit2.num_datasets(self._handle)
1085 return n
1086
1087
1089 """phase_fractions() --> relative phase fractions for current dataset.
1090 Convert phase scale factors to relative phase fractions given the
1091 scattering type of current dataset.
1092
1093 Return a dictionary of phase fractions with following keys:
1094
1095 "atom" -- list of fractions normalized to atom count
1096 "stdatom" -- errors of atom count fractions
1097 "cell" -- list of fractions normalized to unit cell count
1098 "stdcell" -- errors of unit cell count fractions
1099 "mass" -- list of relative weight fractions
1100 "stdmass" -- errors of relative weight fractions
1101
1102 Raises: pdffit2.unassignedError if no dataset exists.
1103 """
1104 return pdffit2.phase_fractions(self._handle)
1105
1106
1107
1109 """lat(n) --> Get reference to lattice variable n.
1110
1111 n can be an integer or a string representing the lattice variable.
1112 1 <==> 'a'
1113 2 <==> 'b'
1114 3 <==> 'c'
1115 4 <==> 'alpha'
1116 5 <==> 'beta'
1117 6 <==> 'gamma'
1118 """
1119 LatParams = { 'a':1, 'b':2, 'c':3, 'alpha':4, 'beta':5, 'gamma':6 }
1120 if type(n) is types.StringType:
1121 n = LatParams[n]
1122 return "lat(%i)" % n
1123 lat = staticmethod(lat)
1124
1125
1127 """x(i) --> Get reference to x-value of atom i."""
1128 return "x(%i)" % i
1129 x = staticmethod(x)
1130
1131
1133 """y(i) --> Get reference to y-value of atom i."""
1134 return "y(%i)" % i
1135 y = staticmethod(y)
1136
1137
1139 """z(i) --> Get reference to z-value of atom i."""
1140 return "z(%i)" % i
1141 z = staticmethod(z)
1142
1143
1145 """u11(i) --> Get reference to U(1,1) for atom i.
1146
1147 U is the anisotropic thermal factor tensor.
1148 """
1149 return "u11(%i)" % i
1150 u11 = staticmethod(u11)
1151
1152
1154 """u22(i) --> Get reference to U(2,2) for atom i.
1155
1156 U is the anisotropic thermal factor tensor.
1157 """
1158 return "u22(%i)" % i
1159 u22 = staticmethod(u22)
1160
1161
1163 """u33(i) --> Get reference to U(3,3) for atom i.
1164
1165 U is the anisotropic thermal factor tensor.
1166 """
1167 return "u33(%i)" % i
1168 u33 = staticmethod(u33)
1169
1170
1172 """u12(i) --> Get reference to U(1,2) for atom i.
1173
1174 U is the anisotropic thermal factor tensor.
1175 """
1176 return "u12(%i)" % i
1177 u12 = staticmethod(u12)
1178
1179
1181 """u13(i) --> Get reference to U(1,3) for atom i.
1182
1183 U is the anisotropic thermal factor tensor.
1184 """
1185 return "u13(%i)" % i
1186 u13 = staticmethod(u13)
1187
1188
1190 """u23(i) --> Get reference to U(2,3) for atom i.
1191
1192 U is the anisotropic thermal factor tensor.
1193 """
1194 return "u23(%i)" % i
1195 u23 = staticmethod(u23)
1196
1197
1199 """occ(i) --> Get reference to occupancy of atom i."""
1200 return "occ(%i)" % i
1201 occ = staticmethod(occ)
1202
1203
1205 """pscale() --> Get reference to pscale.
1206
1207 pscale is the fraction of the total structure that the current phase
1208 represents.
1209 """
1210 return "pscale"
1211 pscale = staticmethod(pscale)
1212
1213
1215 """sratio() --> Get reference to sigma ratio.
1216
1217 The sigma ratio determines the reduction in the Debye-Waller factor for
1218 distances below rcut.
1219 """
1220 return "sratio"
1221 sratio = staticmethod(sratio)
1222
1223
1225 """delta1() --> Get reference to 1/R peak sharpening factor.
1226 """
1227 return "delta1"
1228 delta1 = staticmethod(delta1)
1229
1230
1232 """delta2() --> Reference to (1/R^2) sharpening factor.
1233 The phenomenological correlation constant in the Debye-Waller factor.
1234 The (1/R^2) peak sharpening factor.
1235 """
1236 return "delta2"
1237 delta2 = staticmethod(delta2)
1238
1239
1241 """dscale() --> Get reference to dscale.
1242
1243 The data scale factor.
1244 """
1245 return "dscale"
1246 dscale = staticmethod(dscale)
1247
1248
1250 """qdamp() --> Get reference to qdamp.
1251
1252 Qdamp controls PDF damping due to instrument Q-resolution.
1253 """
1254 return "qdamp"
1255 qdamp = staticmethod(qdamp)
1256
1257
1259 """qbroad() --> Get reference to qbroad.
1260
1261 Quadratic peak broadening factor.
1262 """
1263 return "qbroad"
1264 qbroad = staticmethod(qbroad)
1265
1266
1268 """spdiameter() --> Get reference to spdiameter (phase property).
1269
1270 Diameter value for the spherical particle PDF correction.
1271 Spherical envelope is not applied when spdiameter equals 0.
1272 """
1273 return "spdiameter"
1274 spdiameter = staticmethod(spdiameter)
1275
1276
1278 """stepcut() --> Get reference to stepcut (phase property).
1279
1280 stepcut is cutoff radius for empirical step-function PDF envelope.
1281 stepcut can be used to approximate loss of pair correlations
1282 in amorphous phase. stepcut cannot be refined.
1283
1284 Step cutoff is not applied when stepcut equals 0.
1285 """
1286 return "stepcut"
1287 stepcut = staticmethod(stepcut)
1288
1289
1291 """rcut() --> Get reference to rcut.
1292
1293 rcut is the value of r below which peak sharpening, defined by
1294 the sigma ratio (sratio), applies. rcut cannot be refined.
1295 """
1296 return "rcut"
1297 rcut = staticmethod(rcut)
1298
1299
1300
1301
1303
1304 self.stru_files = []
1305 self.data_files = []
1306
1307 self._handle = pdffit2.create()
1308 self.intro()
1309 return
1310
1311
1313 """Return the actual reference to the variable in the var_string.
1314
1315 This function must be called before trying to actually reference an
1316 internal variable. See the constrain method for an example.
1317
1318 Raises:
1319 pdffit2.unassignedError if variable is not yet assigned
1320 ValueError if variable index does not exist (e.g. lat(7))
1321 """
1322 var_string = _convertCallable(var_string)
1323 arg_int = None
1324 try:
1325 method_string, arg_string = var_string.split("(")
1326 method_string = method_string.strip()
1327 arg_int = int(arg_string.strip(")").strip())
1328 except ValueError:
1329 method_string = var_string.strip()
1330
1331 f = getattr(pdffit2, method_string)
1332 if arg_int is None:
1333 retval = f(self._handle)
1334 else:
1335 retval = f(self._handle, arg_int)
1336 return retval
1337
1338
1339
1340
1341
1342
1343