kim-tools 0.3.0__py3-none-any.whl → 0.3.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
kim_tools/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "0.3.0"
1
+ __version__ = "0.3.2"
2
2
 
3
3
  from .aflow_util import *
4
4
  from .aflow_util import __all__ as aflow_all
@@ -6,6 +6,7 @@ import os
6
6
  import subprocess
7
7
  from curses.ascii import isalpha, isdigit
8
8
  from dataclasses import dataclass
9
+ from itertools import permutations
9
10
  from math import acos, cos, degrees, radians, sqrt
10
11
  from os import PathLike
11
12
  from tempfile import NamedTemporaryFile
@@ -343,6 +344,30 @@ def get_stoich_reduced_list_from_prototype(prototype_label: str) -> List[int]:
343
344
  return stoich_reduced_list
344
345
 
345
346
 
347
+ def build_abstract_formula_from_stoich_reduced_list(
348
+ stoich_reduced_list: List[int],
349
+ ) -> str:
350
+ """
351
+ Get abstract chemical formula from numerical list of stoichiometry
352
+ i.e. [1,3] -> "AB3"
353
+
354
+ Args:
355
+ stoich_reduced_list:
356
+ List of reduced stoichiometric numbers
357
+
358
+ Returns:
359
+ Abstract chemical formula
360
+ """
361
+ formula = ""
362
+ for spec_num, stoich_num in enumerate(stoich_reduced_list):
363
+ assert isinstance(stoich_num, int)
364
+ assert stoich_num > 0
365
+ formula += chr(65 + spec_num)
366
+ if stoich_num > 1:
367
+ formula += str(stoich_num)
368
+ return formula
369
+
370
+
346
371
  def get_wyckoff_lists_from_prototype(prototype_label: str) -> List[str]:
347
372
  """
348
373
  Expand the list of Wyckoff letters in the prototype to account for each individual
@@ -350,7 +375,7 @@ def get_wyckoff_lists_from_prototype(prototype_label: str) -> List[str]:
350
375
  e.g. A2B3C_mC48_15_aef_3f_2e -> ['aef','fff','ee']
351
376
  """
352
377
  expanded_wyckoff_letters = []
353
- prototype_label_split = prototype_label.split("_")
378
+ prototype_label_split = prototype_label.split("-")[0].split("_")
354
379
  for species_wyckoff_string in prototype_label_split[3:]:
355
380
  expanded_wyckoff_letters.append("")
356
381
  curr_wyckoff_count = 0
@@ -371,14 +396,17 @@ def prototype_labels_are_equivalent(
371
396
  prototype_label_1: str,
372
397
  prototype_label_2: str,
373
398
  allow_enantiomorph: bool = False,
374
- allow_species_permutation: bool = False,
399
+ log: bool = True,
375
400
  ) -> bool:
376
401
  """
377
- Checks if two prototype labels are equivalent
402
+ Checks if two prototype labels are equivalent (species permutations not allowed)
403
+
404
+ Args:
405
+ allow_enantiomorph:
406
+ Whether to consider enantiomorphic pairs of space groups to be equivalent
407
+ log:
408
+ Whether to log results
378
409
  """
379
- if allow_species_permutation:
380
- # TODO: Possibly add this (for checking library prototype labels)
381
- raise NotImplementedError("Species permutations not implemented")
382
410
 
383
411
  if prototype_label_1 == prototype_label_2:
384
412
  return True
@@ -389,20 +417,22 @@ def prototype_labels_are_equivalent(
389
417
  if not stoich_reduced_list_1 == get_stoich_reduced_list_from_prototype(
390
418
  prototype_label_2
391
419
  ):
392
- logger.info(
393
- "Found non-matching stoichiometry in labels "
394
- f"{prototype_label_1} and {prototype_label_2}"
395
- )
420
+ if log:
421
+ logger.info(
422
+ "Found non-matching stoichiometry in labels "
423
+ f"{prototype_label_1} and {prototype_label_2}"
424
+ )
396
425
  return False
397
426
 
398
427
  # Check Pearson symbol
399
428
  if not get_pearson_symbol_from_prototype(
400
429
  prototype_label_1
401
430
  ) == get_pearson_symbol_from_prototype(prototype_label_2):
402
- logger.info(
403
- "Found non-matching Pearson symbol in labels "
404
- f"{prototype_label_1} and {prototype_label_2}"
405
- )
431
+ if log:
432
+ logger.info(
433
+ "Found non-matching Pearson symbol in labels "
434
+ f"{prototype_label_1} and {prototype_label_2}"
435
+ )
406
436
  return False
407
437
 
408
438
  # Check space group number
@@ -411,16 +441,18 @@ def prototype_labels_are_equivalent(
411
441
  if allow_enantiomorph and not space_group_numbers_are_enantiomorphic(
412
442
  sg_num_2, sg_num_1
413
443
  ):
414
- logger.info(
415
- "Found non-matching Space group in labels "
416
- f"{prototype_label_1} and {prototype_label_2}"
417
- )
444
+ if log:
445
+ logger.info(
446
+ "Found non-matching Space group in labels "
447
+ f"{prototype_label_1} and {prototype_label_2}"
448
+ )
418
449
  return False
419
450
  elif sg_num_2 != sg_num_1:
420
- logger.info(
421
- "Found non-matching Space group in labels "
422
- f"{prototype_label_1} and {prototype_label_2}"
423
- )
451
+ if log:
452
+ logger.info(
453
+ "Found non-matching Space group in labels "
454
+ f"{prototype_label_1} and {prototype_label_2}"
455
+ )
424
456
  return False
425
457
 
426
458
  # OK, so far everything matches, now check the Wyckoff letters
@@ -462,16 +494,18 @@ def prototype_labels_are_equivalent(
462
494
  wyckoff_lists_match_for_each_species = False
463
495
  break
464
496
  if wyckoff_lists_match_for_each_species:
465
- logger.warning(
466
- f"Labels {prototype_label_1} and {prototype_label_2} were found to "
467
- "be equivalent despite being non-identical. "
468
- "This indicates a failure to find the lowest Wyckoff enumeration."
469
- )
497
+ if log:
498
+ logger.warning(
499
+ f"Labels {prototype_label_1} and {prototype_label_2} were found"
500
+ " to be equivalent despite being non-identical. This indicates "
501
+ "a failure to find the lowest Wyckoff enumeration."
502
+ )
470
503
  return True
471
- logger.info(
472
- f"Labels {prototype_label_1} and {prototype_label_2} were not found to be "
473
- "equivalent under any permutations allowable by the normalizer."
474
- )
504
+ if log:
505
+ logger.info(
506
+ f"Labels {prototype_label_1} and {prototype_label_2} were not found to "
507
+ "be equivalent under any permutations allowable by the normalizer."
508
+ )
475
509
  return False
476
510
  else:
477
511
  for wyckoff_list_1, wyckoff_list_2 in zip(wyckoff_lists_1, wyckoff_lists_2):
@@ -480,20 +514,77 @@ def prototype_labels_are_equivalent(
480
514
  # need to re-sort anything.
481
515
  # This is NOT true for all SGs (e.g. #200, Wyckoff set eh )
482
516
  if not are_in_same_wyckoff_set(letter_1, letter_2, sg_num_1):
483
- logger.info(
484
- f"Labels {prototype_label_1} and {prototype_label_2} have "
485
- f"corresponding letters {letter_1} and {letter_2} that are not "
486
- "in the same Wyckoff set"
487
- )
517
+ if log:
518
+ logger.info(
519
+ f"Labels {prototype_label_1} and {prototype_label_2} have "
520
+ f"corresponding letters {letter_1} and {letter_2} that are "
521
+ "not in the same Wyckoff set"
522
+ )
488
523
  return False
489
- logger.info(
490
- f"Labels {prototype_label_1} and {prototype_label_2} were found to be "
491
- "equivalent despite being non-identical. This is a normal occurrence for "
492
- "triclinic and monoclinic space groups such as this."
493
- )
524
+ if log:
525
+ logger.info(
526
+ f"Labels {prototype_label_1} and {prototype_label_2} were found to be "
527
+ "equivalent despite being non-identical. This is a normal occurrence "
528
+ "for triclinic and monoclinic space groups such as this."
529
+ )
494
530
  return True
495
531
 
496
532
 
533
+ def find_species_permutation_between_prototype_labels(
534
+ prototype_label_1: str,
535
+ prototype_label_2: str,
536
+ allow_enantiomorph: bool = False,
537
+ log: bool = True,
538
+ ) -> Optional[Tuple[int]]:
539
+ """
540
+ Find the permutation of species required to match two prototype labels
541
+
542
+ Args:
543
+ allow_enantiomorph:
544
+ Whether to consider enantiomorphic pairs of space groups to be equivalent
545
+ log:
546
+ Whether to log results
547
+
548
+ Returns:
549
+ The permutation of species of ``prototype_label_1`` required to match
550
+ ``prototype_label_2``, or None if no match is found
551
+ """
552
+ # Disassemble prototype_label_1
553
+ stoich_reduced_list_1 = get_stoich_reduced_list_from_prototype(prototype_label_1)
554
+ pearson_1 = get_pearson_symbol_from_prototype(prototype_label_1)
555
+ space_group_1 = str(get_space_group_number_from_prototype(prototype_label_1))
556
+ species_wyckoff_sections_1 = prototype_label_1.split("-")[0].split("_")[3:]
557
+
558
+ nspecies = len(stoich_reduced_list_1)
559
+ assert nspecies == len(species_wyckoff_sections_1)
560
+
561
+ permutation_candidates = permutations(tuple(range(nspecies)))
562
+ for permutation in permutation_candidates:
563
+ # Permute the species
564
+ stoich_reduced_list_1_permuted = [stoich_reduced_list_1[i] for i in permutation]
565
+ species_wyckoff_sections_1_permuted = [
566
+ species_wyckoff_sections_1[i] for i in permutation
567
+ ]
568
+
569
+ # Reassemble prototype_label_1_permuted
570
+ abstract_formula_1_permuted = build_abstract_formula_from_stoich_reduced_list(
571
+ stoich_reduced_list_1_permuted
572
+ )
573
+ prototype_label_1_permuted_list = [
574
+ abstract_formula_1_permuted,
575
+ pearson_1,
576
+ space_group_1,
577
+ ] + species_wyckoff_sections_1_permuted
578
+ prototype_label_1_permuted = "_".join(prototype_label_1_permuted_list)
579
+ if prototype_labels_are_equivalent(
580
+ prototype_label_1=prototype_label_1_permuted,
581
+ prototype_label_2=prototype_label_2,
582
+ allow_enantiomorph=allow_enantiomorph,
583
+ ):
584
+ return permutation
585
+ return None
586
+
587
+
497
588
  def get_space_group_number_from_prototype(prototype_label: str) -> int:
498
589
  return int(prototype_label.split("_")[2])
499
590
 
@@ -289,8 +289,11 @@ def space_group_numbers_are_enantiomorphic(sg_1: int, sg_2: int) -> bool:
289
289
  }
290
290
  enantiomorph_conversion_2 = {v: k for k, v in enantiomorph_conversion.items()}
291
291
  enantiomorph_conversion.update(enantiomorph_conversion_2)
292
- if enantiomorph_conversion[sg_1] == sg_2:
293
- return True
292
+ if sg_1 in enantiomorph_conversion:
293
+ if enantiomorph_conversion[sg_1] == sg_2:
294
+ return True
295
+ else:
296
+ return False
294
297
  else:
295
298
  return False
296
299
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kim-tools
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: Base classes and helper routines for writing KIM Tests
5
5
  Author-email: ilia Nikiforov <nikif002@umn.edu>, Ellad Tadmor <tadmor@umn.edu>, Claire Waters <bwaters@umn.edu>, "Daniel S. Karls" <karl0100umn@gmail.com>, Matt Bierbaum <matt.bierbaum@gmail.com>, Eric Fuemmeler <efuemmel@umn.edu>, Philipp Hoellmer <ph2484@nyu.edu>, Guanming Zhang <gz2241@nyu.edu>, Tom Egg <tje3676@nyu.edu>
6
6
  Maintainer-email: ilia Nikiforov <nikif002@umn.edu>
@@ -1,7 +1,7 @@
1
- kim_tools/__init__.py,sha256=1_-Nx2m2jdCABSg3wVEK_v139McyduMthh8VNWZSsd0,433
1
+ kim_tools/__init__.py,sha256=AhAW6unNWB_4jaiwxb0_XxUKtCv1rwG3CNqLk4aqqso,433
2
2
  kim_tools/kimunits.py,sha256=jOxBv9gRVhxPE6ygAIUxOzCAfPI6tT6sBaF_FNl9m-M,5387
3
3
  kim_tools/aflow_util/__init__.py,sha256=lJnQ8fZCma80QVRQeKvY4MQ87oCWu-9KATV3dKJfpDc,80
4
- kim_tools/aflow_util/core.py,sha256=1Rv9LSoOgr_9-XFSK4UnHZ2XXQF0MUreMrRh7WWDTQw,72854
4
+ kim_tools/aflow_util/core.py,sha256=CsqN6MNVXE4QFrM0SxWhahTwu_gTeUXITk7ZMXLXfv0,75954
5
5
  kim_tools/aflow_util/aflow_prototype_encyclopedia/data/A108B24C11D24_cP334_222_h4i_i_bf_i-001/info.json,sha256=IsFiO9X2Ko7yoq2QkDurUVP7k1BE4WFgblu7oxl6iZs,2013
6
6
  kim_tools/aflow_util/aflow_prototype_encyclopedia/data/A10B11_tI84_139_dehim_eh2n-001/info.json,sha256=f1EdtouuSL2y9NNw40Rvz2J9ZZcsqQBcyEmlHj6XoW8,1186
7
7
  kim_tools/aflow_util/aflow_prototype_encyclopedia/data/A10B2C_hP39_171_5c_c_a-001/info.json,sha256=vD1xjZKWShL0E6XNsSlmIhilGcGNefl56oQDLQlHO1M,1596
@@ -2004,7 +2004,7 @@ kim_tools/aflow_util/aflow_prototype_encyclopedia/data/A_tP50_134_a2m2n-001/info
2004
2004
  kim_tools/ase/__init__.py,sha256=1i6ko5tNr0VZC3T7hoEzq4fnSU0DdxNpxXcSaWMcJWc,76
2005
2005
  kim_tools/ase/core.py,sha256=d6eOu_HSxVr-ae0TSEbY4HKdePxhNu3yv8NN9VDl-BA,30256
2006
2006
  kim_tools/symmetry_util/__init__.py,sha256=uu-ZSUDUTe2P81rkAS3tXverx31s_uZ3wL4SD_dn5aI,86
2007
- kim_tools/symmetry_util/core.py,sha256=RVvKisrNxHKq36ceIorc06cnX3la3WoWNPVV0hKnptM,30789
2007
+ kim_tools/symmetry_util/core.py,sha256=HfDy1CwNWUZIkb4cs3ebUDgWjtt4jRSkBKgGEnlkjuI,30888
2008
2008
  kim_tools/symmetry_util/data/possible_primitive_shifts.json,sha256=4OVNgn3NnykgGlYiAcecERmVWiIZFrmP2LZI3ml_Sh0,25010
2009
2009
  kim_tools/symmetry_util/data/primitive_GENPOS_ops.json,sha256=FDu4H4PosOpK9yKwOPy3SxbH7xLMOmZfKZ4ItKPMjoQ,224498
2010
2010
  kim_tools/symmetry_util/data/space_groups_for_each_bravais_lattice.json,sha256=wSNu6d5pH72lJ6Zj5MZ64qzwS_6Fn5WOs0ts7E9uPC4,2507
@@ -2015,8 +2015,8 @@ kim_tools/test_driver/__init__.py,sha256=KOiceeZNqkfrgZ66CiRiUdniceDrCmmDXQkOw0w
2015
2015
  kim_tools/test_driver/core.py,sha256=r4hiZcV-PkWcOo0uEqfqeP1-YGGpPepaAjmR4LJog0w,89208
2016
2016
  kim_tools/vc/__init__.py,sha256=zXjhxXCKVMLBMXXWYG3if7VOpBnsFrn_RjVpnohDm5c,74
2017
2017
  kim_tools/vc/core.py,sha256=BIjzEExnQAL2S90a_npptRm3ACqAo4fZBtvTDBMWMdw,13963
2018
- kim_tools-0.3.0.dist-info/licenses/LICENSE.CDDL,sha256=I2luEED_SHjuZ01B4rYG-AF_135amL24JpHvZ1Jhqe8,16373
2019
- kim_tools-0.3.0.dist-info/METADATA,sha256=MAODKb510nvTCelHGq9-IHuosDJSGjTEdl1DPnP19mA,1962
2020
- kim_tools-0.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
2021
- kim_tools-0.3.0.dist-info/top_level.txt,sha256=w_YCpJ5ERigj9te74ln7k64tqj1VumOzM_s9dsalIWY,10
2022
- kim_tools-0.3.0.dist-info/RECORD,,
2018
+ kim_tools-0.3.2.dist-info/licenses/LICENSE.CDDL,sha256=I2luEED_SHjuZ01B4rYG-AF_135amL24JpHvZ1Jhqe8,16373
2019
+ kim_tools-0.3.2.dist-info/METADATA,sha256=EAQFkPk6S0svLhGMBstoSj4Kk9vdzbIDATWefRyb8zE,1962
2020
+ kim_tools-0.3.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
2021
+ kim_tools-0.3.2.dist-info/top_level.txt,sha256=w_YCpJ5ERigj9te74ln7k64tqj1VumOzM_s9dsalIWY,10
2022
+ kim_tools-0.3.2.dist-info/RECORD,,