{"id":17843975,"url":"https://github.com/dkratzert/shelxfile","last_synced_at":"2025-03-20T05:31:44.502Z","repository":{"id":43957187,"uuid":"135573780","full_name":"dkratzert/ShelXFile","owner":"dkratzert","description":"A parser and editor for SHELXL files.","archived":false,"fork":false,"pushed_at":"2024-10-19T10:50:32.000Z","size":1669,"stargazers_count":12,"open_issues_count":1,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-10-19T16:46:12.672Z","etag":null,"topics":["atom","crystallography","editor","molecule","parser","shelxl"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dkratzert.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-05-31T11:18:41.000Z","updated_at":"2024-10-19T10:50:36.000Z","dependencies_parsed_at":"2024-02-16T23:02:10.844Z","dependency_job_id":"d714d67d-fc02-4cb9-841d-9d8887bd9551","html_url":"https://github.com/dkratzert/ShelXFile","commit_stats":{"total_commits":413,"total_committers":1,"mean_commits":413.0,"dds":0.0,"last_synced_commit":"373472f71b2e8420d434d681e199adc8fb29a023"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkratzert%2FShelXFile","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkratzert%2FShelXFile/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkratzert%2FShelXFile/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkratzert%2FShelXFile/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dkratzert","download_url":"https://codeload.github.com/dkratzert/ShelXFile/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221735064,"owners_count":16872223,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["atom","crystallography","editor","molecule","parser","shelxl"],"created_at":"2024-10-27T21:27:33.585Z","updated_at":"2024-10-27T21:27:34.204Z","avatar_url":"https://github.com/dkratzert.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Shelxfile\n\u003ca href=\"https://repology.org/project/python:shelxfile/versions\"\u003e\n    \u003cimg src=\"https://repology.org/badge/vertical-allrepos/python:shelxfile.svg\" alt=\"Packaging status\" align=\"right\"\u003e\n\u003c/a\u003e\n\n[![Unit tests](https://github.com/dkratzert/ShelXFile/actions/workflows/unit-tests.yml/badge.svg)](https://github.com/dkratzert/ShelXFile/actions/workflows/unit-tests.yml)\n![Contributions](https://img.shields.io/badge/contributions-welcome-blue)\n\nThis is a full implementation of the SHELXL[[1](https://github.com/dkratzert/Shelxfile/blob/master/README.md#references)] file syntax. Additionally it is able to edit SHELX properties using Python.\nThe implementation is Python3-only and supports SHELXL after 2017 (You should not use old versions anyway).\nShelxfile may eventually become a new heart of DSR[[2](https://github.com/dkratzert/Shelxfile/blob/master/README.md#references)] and is already used as file parser in StructureFinder[[3](https://github.com/dkratzert/Shelxfile/blob/master/README.md#references)].\n\nShelxfile always keeps the file order intact. Every SHELX instruction like DFIX or an atom is stored as an class object in the list Shelxfile.\\_reslist. When writing the Shelxfile content to disk, it wites the \\_reslist content to disk.\n\nShelxfile tries to detect all possible syntax errors that SHELXL would not like either. If Shelxfile.DEBUG is True, more output about syntax and other errors are printed out. Otherwise, the parser is quiet except for really severe errors like a missing unit cell.\n\nNot every part of Shelxfile is complete, for example it will not recognize if you add restraints with atom names that are not in the SHELX file. Please help me improving it!\n\n**Source Code**\n\n[You can find the ShelXfile source code at GitHub](https://github.com/dkratzert/ShelXFile).\n\nExamples:\n\n\n```python\npip install shelxfile\n\n\u003e\u003e\u003e from shelxfile import Shelxfile\n\u003e\u003e\u003e shx = Shelxfile(verbose=True) # or debug=True, debug will halt on errors.\n\u003e\u003e\u003e shx.read_file('src/tests/resources/p21c.res')  # or .read_string() \n\u003e\u003e\u003e shx.cell\nCELL 0.71073 10.5086 20.9035 20.5072 90 94.13 90\n\n\u003e\u003e\u003e list(shx.cell)\n[10.5086, 20.9035, 20.5072, 90.0, 94.13, 90.0]\n\n\u003e\u003e\u003e shx.cell.volume\n4493.047384590458\n\n\u003e\u003e\u003e shx.cell.a\n10.5086\n\n\u003e\u003e\u003e shx.to_cif('test.cif')  \n# Writes a CIF file from the content of p21c.res\n\n# You can overwrite any parameter in a shelx file:\n\u003e\u003e\u003e shx.plan\nPLAN 20\n\n\u003e\u003e\u003e shx.plan.npeaks\n20\n\n\u003e\u003e\u003e shx.plan.set('PLAN 30')\n\u003e\u003e\u003e shx.plan\nPLAN 30\n\n\u003e\u003e\u003e shx.atoms\nO1     3    0.074835    0.238436    0.402457   -31.00000    0.01579    0.03095      0.01852   -0.00468   -0.00210    0.01153\nC1     1    0.028576    0.234542    0.337234   -31.00000    0.02311    0.03617      0.01096   -0.01000    0.00201    0.00356\nC2     1    0.121540    0.194460    0.298291   -31.00000    0.02960    0.04586      0.01555   -0.00485   -0.00023    0.01102\nF\n...\n\n\u003e\u003e\u003e shx.atoms.hydrogen_atoms\n[Atom ID: 81, Atom ID: 88, Atom ID: 95, ... ]\n\n\u003e\u003e\u003e shx.atoms.hydrogen_atoms[1].name\n'H32'\n\n\u003e\u003e\u003e shx.atoms.n_hydrogen_atoms\n24\n\n# Atoms with a riding model e.g. hydrogen atom riding on a carbon atom:\n\u003e\u003e\u003e shx.atoms.riding_atoms\n[Atom ID: 81, Atom ID: 88, Atom ID: 95, ... ]\n\n\u003e\u003e\u003e a = shx.atoms.get_atom_by_name('F1_2')  # Atom F1 in residue 2\n\u003e\u003e\u003e a\nAtom ID: 258  # \u003c- The Atom ID is the index number in the Shelxfile._reslist list\n\n\u003e\u003e\u003e str(a)\n'F1    4    0.245205    0.192674    0.649231   -21.00000    0.05143    0.03826    0.03193   -0.00579   -0.01865   -0.00485'\n\n\u003e\u003e\u003e a.to_isotropic()\n\u003e\u003e\u003e str(a)\n'F1    4    0.245205    0.192674   0.649231  -21.00000    0.04000'\n\n\u003e\u003e\u003e a.position  # position in the SHELX .res file\n273\n\n\u003e\u003e\u003e str(shx._reslist[273])  # In regular code, do not access shx._reslist directly!\n'F1    4    0.245205    0.192674   0.649231  -21.00000    0.04000'\n\n\u003e\u003e\u003e a.name\n'F1'\n\n\u003e\u003e\u003e a.element\n'F'\n\n# Introduce a new element\n\u003e\u003e\u003e a.element = 'Na'\n\u003e\u003e\u003e shx.sfac_table\nSFAC C  H  O  F  Al  Ga  Na\n\n\u003e\u003e\u003e a.resinum\n2\n\n\u003e\u003e\u003e a.part\n2\n\n\u003e\u003e\u003e shx.sfac2elem(4)\n'F'\n\n\u003e\u003e\u003e shx.elem2sfac('F')\n4\n\n\u003e\u003e\u003e a.find_atoms_around(dist=2.0, only_part=1)\n[Atom ID: 254, Atom ID: 256, Atom ID: 260]  # Found some atoms \n\n\u003e\u003e\u003e [str(x) for x in a.find_atoms_around(dist=2.2, only_part=2)]\n['C2     1    0.192984    0.140449    0.621265   -21.00000    0.04315    0.02747      0.02385    0.00686   -0.00757    0.00126', \n'F2     4    0.264027    0.090306    0.642441   -21.00000    0.06073    0.04450      0.03972    0.01630   -0.01260    0.01460', \n'F3     4    0.078582    0.131920    0.643529   -21.00000    0.05691    0.04955      0.03374    0.01040    0.01881    0.00375']\n\n\u003e\u003e\u003e a.cart_coords\n[1.617897551082389, 4.027560959000001, 13.279336538026433]\n\n\u003e\u003e\u003e a.frac_coords\n[0.245205, 0.192674, 0.649231]\n\n\u003e\u003e\u003e a.occupancy\n1.0\n\n\u003e\u003e\u003e a.sfac_num\n4\n\n\u003e\u003e\u003e[x for x in a.find_atoms_around(dist=2.5, only_part=2)]\n[Atom ID: 254, Atom ID: 256, Atom ID: 260, Atom ID: 262]\n\n\u003e\u003e\u003e for x in a.find_atoms_around(dist=2.5, only_part=2):\n...    x.delete()\n\n\u003e\u003e\u003e [x for x in a.find_atoms_around(dist=2.5, only_part=2)]\n[]  # Atoms are now deleted from shx._reslist.\n\n\u003e\u003e\u003e shx.restraints\nSADI_CCF3 0.02 C1 C2 C1 C3 C1 C4\nSADI_CCF3 0.02 F1 C2 F2 C2 F3 C2 F4 C3 F5 C3 F6 C3 F7 C4 F8 C4 F9 C4\nSADI_CCF3 0.04 C2 C3 C3 C4 C2 C4\nSADI_CCF3 0.04 O1 C2 O1 C3 O1 C4\nSADI_CCF3 0.04 F1 F2 F2 F3 F3 F1 F4 F5 F5 F6 F6 F4 F7 F8 F8 F9 F9 F7\n...\n\n\u003e\u003e\u003e shx.restraints[1]\nSADI_CCF3 0.02 C1 C2 C1 C3 C1 C4\n\nstr(shx.restraints[1])\n'SADI_CCF3 0.02 C1 C2 C1 C3 C1 C4'\n\nshx.restraints[1].residue_class\n'CCF3'\n\n# The residue class 'CCF3' has three residues with these numbers: \n\u003e\u003e\u003e shx.restraints[1].residue_number\n[4, 1, 2]\n\n# The esd of the SADI restraint:\nshx.restraints[1].s\n0.02\n\n```\n\nWrites current shx object to test.ins\nAll lines in Shelxfile._reslist get wrapped after 79 characters with \" =\\n \" as\nspecified by SHELXL during the file writing.\n\n```python\n\u003e\u003e\u003e shx.write_shelx_file('test.ins')\n```\nNo matter if you loaded a .res or .ins file with refine(), SHELXL refines the structure of the Shelxfile() object:\n\n```python\n\u003e\u003e\u003e shx.insert_anis()\n\u003e\u003e\u003e shx.refine(2)\n\n Running SHELXL with \"/usr/local/bin/shelxl -b3000 /Users/daniel/GitHub/Shelxfile/tests/p21c\" and \"L.S. 2\"\n wR2 =  0.1143 before cycle   1 for   10786 data and    945 /    945 parameters\n wR2 =  0.1025 before cycle   2 for   10786 data and    945 /    945 parameters\n wR2 =  0.1006 before cycle   3 for   10786 data and      0 /    945 parameters\n SHELXL Version 2018/3\n```\n```python\n# Symmcards that are implied by lattice symmetry are generated on-the-fly:\n\u003e\u003e\u003e shx.symmcards\n| 1  0  0|   | 0.0|\n| 0  1  0| + | 0.0|\n| 0  0  1|   | 0.0|\n\n|-1  0  0|   | 0.0|\n| 0 -1  0| + | 0.0|\n| 0  0 -1|   | 0.0|\n\n|-1  0  0|   | 0.0|\n| 0  1  0| + | 0.5|\n| 0  0 -1|   | 0.5|\n\n| 1  0  0|   | 0.0|\n| 0 -1  0| + |-0.5|\n| 0  0  1|   |-0.5|\n\n# Complete or \"grow\" structures with higher symmetry: \n\u003e\u003e\u003e shx = Shelxfile('./tests/p-31c.res')\nlen(shx.atoms)\n88\np = shx.grow()\nlen(p)\n208\n\n# The (bond) angle between three atoms:\n\u003e\u003e\u003e at1 = shx.atoms.get_atom_by_name('O1_4')\n\u003e\u003e\u003e at2 = shx.atoms.get_atom_by_name('C1_4')\n\u003e\u003e\u003e at3 = shx.atoms.get_atom_by_name('C2_4')\n\u003e\u003e\u003e shx.atoms.angle(at1, at2, at3)\n109.688123\n\n# The torsion angle between four atoms:\n\u003e\u003e\u003e at1 = shx.atoms.get_atom_by_name('O1')\n\u003e\u003e\u003e at2 = shx.atoms.get_atom_by_name('C1')\n\u003e\u003e\u003e at3 = shx.atoms.get_atom_by_name('C2')\n\u003e\u003e\u003e at4 = shx.atoms.get_atom_by_name('F1')\n\u003e\u003e\u003e shx.atoms.torsion_angle(at1, at2, at3, at4)\n74.095731\n\n```\n\nand many more...\n\n## References\n[1] http://shelx.uni-goettingen.de/, G. M. Sheldrick, Acta Cryst. (2015). C71, 3-8.\nhttps://doi.org/10.1107/S2053229614024218\n\n[2] https://github.com/dkratzert/DSR\n\n[3] https://github.com/dkratzert/StructureFinder\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdkratzert%2Fshelxfile","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdkratzert%2Fshelxfile","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdkratzert%2Fshelxfile/lists"}