Package diffpy :: Package pdffit2 :: Module pdffit
[hide private]
[frames] | no frames]

Source Code for Module diffpy.pdffit2.pdffit

   1  #!/usr/bin/env python 
   2  ############################################################################## 
   3  # 
   4  # pdffit2           by DANSE Diffraction group 
   5  #                   Simon J. L. Billinge 
   6  #                   (c) 2006 trustees of the Michigan State University. 
   7  #                   All rights reserved. 
   8  # 
   9  # File coded by:    Chris Farros, Pavol Juhas 
  10  # 
  11  # See AUTHORS.txt for a list of people who contributed. 
  12  # See LICENSE.txt for license information. 
  13  # 
  14  ############################################################################## 
  15   
  16  """PdfFit class for fitting pdf data to a model.""" 
  17   
  18   
  19  import types 
  20   
  21  # Load pdffit2 and output modules to the current namespace. 
  22  # Note that "import diffpy.pdffit2.output as output" would 
  23  # crash with AttributeError when executed during imports of 
  24  # parent packages. 
  25  from diffpy.pdffit2 import pdffit2 
  26  from diffpy.pdffit2 import output 
  27   
  28  # helper routines 
  29   
30 -def _format_value_std(value, stdev):
31 """Convert value to a string with standard deviation in brackets. 32 33 value -- a number 34 stdev -- standard deviation. Ignored when small compared to value. 35 36 Return string. 37 """ 38 if stdev > abs(value)*1e-8: 39 s = "%g (%g)" % (value, stdev) 40 elif str(stdev) == 'nan': 41 s = "%g (NaN)" % value 42 else: 43 s = "%g" % value 44 return s
45 46
47 -def _format_bond_length(dij, ddij, ij1, symij):
48 """Return string with formatted bond length info for a pair of atoms. 49 50 dij -- distance between atoms i and j 51 ddij -- standard deviation of dij. Ignored when small relative to dij. 52 ij1 -- tuple of atom indices starting at 1 53 symij -- tuple of atom symbols 54 55 Return formatted string. 56 """ 57 w_smbidx = 10 58 w_equals = 30 59 s0 = "%s (#%i)" % (symij[0], ij1[0]) 60 s1 = "%s (#%i)" % (symij[1], ij1[1]) 61 leader0 = " " + s0.ljust(w_smbidx) + " - " + s1 + " " 62 leader1 = leader0.ljust(w_equals) + '= ' 63 s = leader1 + _format_value_std(dij, ddij) + " A" 64 return s
65 66
67 -def _convertCallable(var):
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 # constants 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
105 -class PdfFit(object):
106 """Create PdfFit object.""" 107 108 # constants and enumerators from pdffit.h: 109 # selection of all atoms 110 selalias = { 'ALL' : -1 } 111 # constraint type identifiers 112 FCON = { 'USER' : 0, 'IDENT' : 1, 'FCOMP' : 2, 'FSQR' : 3 } 113 # scattering type identifiers 114 Sctp = { 'X' : 0, 'N' : 1 } 115
116 - def _exportAll(self, namespace):
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 # string aliases (var = "var") 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
134 - def intro():
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
149 - def add_structure(self, stru):
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
163 - def read_struct(self, struct):
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
179 - def read_struct_string(self, struct, name=""):
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
213 - def read_data_string(self, data, stype, qmax, qdamp, name=""):
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
254 - def pdfrange(self, iset, rmin, rmax):
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
267 - def reset(self):
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
298 - def calc(self):
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
334 - def refine_step(self, toler=0.00000001):
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
352 - def save_pdf(self, iset, fname):
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
365 - def save_pdf_string(self, iset):
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
379 - def save_dif(self, iset, fname):
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
393 - def save_dif_string(self, iset):
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
408 - def save_res(self, fname):
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
419 - def save_res_string(self):
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
431 - def get_structure(self, ip):
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
446 - def save_struct(self, ip, fname):
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
460 - def save_struct_string(self, ip):
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
474 - def show_struct(self, ip):
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
485 - def constrain(self, var, par, fcon=None):
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
519 - def setpar(self, par, val):
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 # people do not use parenthesis, e.g., "setpar(3, qdamp)" 528 # in such case val is a reference to PdfFit method 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
539 - def setvar(self, var, val):
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
551 - def getvar(self, var):
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
563 - def getrw(self):
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
574 - def getcrw(self):
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
590 - def getR(self):
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
605 - def getpdf_fit(self):
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
619 - def getpdf_obs(self):
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
634 - def getpdf_diff(self):
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
649 - def get_atoms(self, ip=None):
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
666 - def get_atom_types(self, ip=None):
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
684 - def getpar(self, par):
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
692 - def fixpar(self, par):
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
706 - def freepar(self, par):
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
720 - def setphase(self, ip):
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
734 - def setdata(self, iset):
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
758 - def pdesel(self, ip):
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
771 - def selectAtomType(self, ip, ijchar, symbol, flag):
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
789 - def selectAtomIndex(self, ip, ijchar, aidx, flag):
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
807 - def selectAll(self, ip, ijchar):
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
822 - def selectNone(self, ip, ijchar):
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 # indices should be already checked here by bond_angle 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
856 - def bond_angle(self, i, j, k):
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 # first form 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 # check ij 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 # second form 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 # index of non-existant atom type 915 return 916 # arguments are OK here, get bond length dictionary 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 # done 938 return
939 940
941 - def bond_length_atoms(self, i, j):
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
957 - def bond_length_types(self, a1, a2, lb, ub):
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
979 - def show_scat(self, stype):
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
991 - def get_scat_string(self, stype):
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
1005 - def get_scat(self, stype, element):
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
1044 - def reset_scat(self, element):
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
1058 - def num_atoms(self):
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
1066 - def num_phases(self):
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
1077 - def num_datasets(self):
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
1088 - def phase_fractions(self):
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 # Begin refinable variables. 1107
1108 - def lat(n):
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
1126 - def x(i):
1127 """x(i) --> Get reference to x-value of atom i.""" 1128 return "x(%i)" % i
1129 x = staticmethod(x) 1130 1131
1132 - def y(i):
1133 """y(i) --> Get reference to y-value of atom i.""" 1134 return "y(%i)" % i
1135 y = staticmethod(y) 1136 1137
1138 - def z(i):
1139 """z(i) --> Get reference to z-value of atom i.""" 1140 return "z(%i)" % i
1141 z = staticmethod(z) 1142 1143
1144 - def u11(i):
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
1153 - def u22(i):
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
1162 - def u33(i):
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
1171 - def u12(i):
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
1180 - def u13(i):
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
1189 - def u23(i):
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
1198 - def occ(i):
1199 """occ(i) --> Get reference to occupancy of atom i.""" 1200 return "occ(%i)" % i
1201 occ = staticmethod(occ) 1202 1203
1204 - def pscale():
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
1214 - def sratio():
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
1224 - def delta1():
1225 """delta1() --> Get reference to 1/R peak sharpening factor. 1226 """ 1227 return "delta1"
1228 delta1 = staticmethod(delta1) 1229 1230
1231 - def delta2():
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
1240 - def dscale():
1241 """dscale() --> Get reference to dscale. 1242 1243 The data scale factor. 1244 """ 1245 return "dscale"
1246 dscale = staticmethod(dscale) 1247 1248
1249 - def qdamp():
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
1258 - def qbroad():
1259 """qbroad() --> Get reference to qbroad. 1260 1261 Quadratic peak broadening factor. 1262 """ 1263 return "qbroad"
1264 qbroad = staticmethod(qbroad) 1265 1266
1267 - def spdiameter():
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
1277 - def stepcut():
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
1290 - def rcut():
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 # End refinable variables. 1301
1302 - def __init__(self):
1303 1304 self.stru_files = [] 1305 self.data_files = [] 1306 1307 self._handle = pdffit2.create() 1308 self.intro() 1309 return
1310 1311
1312 - def __getRef(self, var_string):
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: #There is no arg_string 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 # End of class PdfFit 1340 1341 1342 # End of file 1343