{"id":18843320,"url":"https://github.com/quatrope/uttrs","last_synced_at":"2025-04-14T07:32:23.229Z","repository":{"id":56138823,"uuid":"313040933","full_name":"quatrope/uttrs","owner":"quatrope","description":"uttrs provides  utilities for creating attrs  based classes with astropy units.","archived":false,"fork":false,"pushed_at":"2021-07-14T04:16:13.000Z","size":107,"stargazers_count":4,"open_issues_count":1,"forks_count":1,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-27T21:38:37.680Z","etag":null,"topics":["astronomy","astropy","astropy-units","attrs","classes","oop","units-measures-converter"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/quatrope.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-11-15T13:47:15.000Z","updated_at":"2023-05-19T20:51:02.000Z","dependencies_parsed_at":"2022-08-15T13:21:11.796Z","dependency_job_id":null,"html_url":"https://github.com/quatrope/uttrs","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quatrope%2Futtrs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quatrope%2Futtrs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quatrope%2Futtrs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quatrope%2Futtrs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/quatrope","download_url":"https://codeload.github.com/quatrope/uttrs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248839521,"owners_count":21169825,"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":["astronomy","astropy","astropy-units","attrs","classes","oop","units-measures-converter"],"created_at":"2024-11-08T02:57:30.420Z","updated_at":"2025-04-14T07:32:22.871Z","avatar_url":"https://github.com/quatrope.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Uttrs\n\n`uttrs` seeks to interoperate Classes definided using attrs and *astropy units* in a simple manner.\n\n![img](https://github.com/quatrope/uttrs/blob/main/res/ugly_logo.png?raw=true)\n\n----\n\n[![QuatroPe](https://img.shields.io/badge/QuatroPe-Applications-1c5896)](https://quatrope.github.io/)\n[![Build Status](https://travis-ci.com/quatrope/uttrs.svg?branch=main)](https://travis-ci.com/quatrope/uttrs)\n[![Documentation Status](https://readthedocs.org/projects/uttrs/badge/?version=latest)](https://uttrs.readthedocs.io/en/latest/?badge=latest)\n[![License](https://img.shields.io/pypi/l/uttrs?color=blue)](https://www.tldrlegal.com/l/bsd3)\n[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://badge.fury.io/py/uttrs)\n[![PyPI](https://img.shields.io/pypi/v/uttrs)](https://pypi.org/project/uttrs/)\n\n\n\n**uttrs** is mainly three functions:\n\n- `uttr.ib` which generates attributes sensitive to units.\n- `uttr.array_accessor` which allows access to attributes linked to units, and transform them into numpy arrays.\n- `uttr.s` a class decorator to automatically add the `array_accessor`.\n\n## Code and issues\n\nThe entire source code of is hosted in GitHub\n[https://github.com/quatrope/uttrs/](https://github.com/quatrope/uttrs/)\n\n## License\n\nUttrs is under\n[The BSD-3 License](https://github.com/quatrope/uttrs/blob/master/LICENSE)\n\nThe BSD 3-clause license allows you almost unlimited freedom with the software so long as you include the BSD copyright and license notice in it (found in Fulltext).\n\n\n## Installation\n\nThis is the recommended way to install uttrs.\n\n### Installing  with pip\n\nMake sure that the Python interpreter can load uttrs code.\nThe most convenient way to do this is to use virtualenv, virtualenvwrapper, and pip.\n\nAfter setting up and activating the virtualenv, run the following command:\n\n```console\n$ pip install uttrs\n...\n```\n\nThat should be it all.\n\n### Installing the development version\n\nIf you’d like to be able to update your uttrs code occasionally with the latest bug fixes and improvements, follow these instructions:\n\nMake sure that you have Git installed and that you can run its commands from a shell.\n(Enter *git help* at a shell prompt to test this.)\n\nCheck out uttrs main development branch like so:\n\n```console\n$ git clone https://github.com/quatrope/uttrs\n...\n```\n\nThis will create a directory *uttrs* in your current directory.\n\nThen you can proceed to install with the commands\n\n```console\n$ cd uttrs\n$ pip install -e .\n...\n```\n\n## Documentation\n\nThe full documentation of the project are available in\n[https://uttrs.readthedocs.io/](https://uttrs.readthedocs.io/)\n\n## Contact\n\nFor bugs or question please contact\n\n\u003e **Juan B. Cabral:** [jbcabral@unc.edu.ar](jbcabral@unc.edu.ar)\n\n\n## Quick Start\n\nThe following piece of code is an example prototype of a Class representing a Galaxy.\nThe Galaxy contains:\n\n- three arrays (`x`, `y`, `z`) with particle positions, measured in *kiloparsecs* (`u.kpc`).\n- three arrays (`vx`, `vy`, `vz`) for the particle velocities, measured in *Km/s* (`u.kms/u.s`).\n- an array (`m`) of particle masses, expressed in *solar masses* (`u.M_sun`).\n- a free text for note taking in `notes`.\n\nIn every case we would like to access to position, velocity and mass of the particles, with and without units (as `np.ndarray`).\nSuggested units in the information of the attributes behave like this:\n\n- If the user makes the class instance without unit specification then default assumed unit is used.\n- If, otherwise, another unit is used as input, it is validated the feasibility of the conversion to default unit.\n\n```python\nimport uttr\n\nimport astropy.units as u\n\n@uttr.s\nclass Galaxy:\n    x = uttr.ib(unit=u.kpc)\n    y = uttr.ib(unit=u.kpc)\n    z = uttr.ib(unit=u.kpc)\n\n    vx = uttr.ib(unit=u.km/u.s)\n    vy = uttr.ib(unit=u.km/u.s)\n    vz = uttr.ib(unit=u.km/u.s)\n\n    m = uttr.ib(unit=u.M_sun)\n\n    notes = uttr.ib(converter=str)\n\n```\n\n## Creating a galaxy\n\n```python\n\u003e\u003e\u003e import numpy as np\n\u003e\u003e\u003e import astropy.units as u\n\n# Creating the particle arrays\n\u003e\u003e\u003e x = np.random.randint(1000, 10_000, size=5) + np.random.rand(5)\n\u003e\u003e\u003e y = np.random.randint(1000, 10_000, size=5) + np.random.rand(5)\n\u003e\u003e\u003e z = np.random.randint(1000, 10_000, size=5) + np.random.rand(5)\n\u003e\u003e\u003e vx = np.random.randint(1000, 10_000, size=5) + np.random.rand(5)\n\u003e\u003e\u003e vy = np.random.randint(1000, 10_000, size=5) + np.random.rand(5)\n\u003e\u003e\u003e vz = np.random.randint(1000, 10_000, size=5) + np.random.rand(5)\n\u003e\u003e\u003e m = np.random.randint(1000, 10_000, size=5) + np.random.rand(5)\n\n\u003e\u003e\u003e gal = Galaxy(\n...     x = x * u.kpc,  # kpc is the suggested unit\n...     y = y * u.mpc,  # milliparsec is equivalent to kpc\n...     z = z,  # we assume is the suggested kpc unit\n...     vx = vx * (u.km/u.s), # the suggested unit\n...     vy = vy * (u.km/u.s), # the suggested unit\n...     vz = vz, # the suggested unit\n...     m = m * u.M_sun, # the suggested unit\n...     notes=\"a random galaxy made with random numbers\")\n\n\u003e\u003e\u003e gal\nGalaxy(\n    x=\u003cQuantity [5632.35740606, 1363.36235923, 3037.46794044, 2785.45299727, 2515.35793673] kpc\u003e,\n    y=\u003cQuantity [4457.3573917 , 2873.54575512, 7979.68745148, 5930.55394614, 5903.63598164] mpc\u003e,\n    z=\u003cQuantity [6122.35929872, 3740.22821927, 6859.42245056, 7119.8256744 , 3632.74980958] kpc\u003e,\n    vx=\u003cQuantity [7141.40469733, 5713.29552487, 5000.535142  , 9366.36402447, 2967.2546077 ] km / s\u003e,\n    vy=\u003cQuantity [8514.83018331, 1362.13309457, 1136.30959053, 1985.49551226, 3286.69029298] km / s\u003e,\n    vz=\u003cQuantity [6218.56279077, 2015.04638043, 9919.99579782, 1278.94359767, 7228.21626876] km / s\u003e,\n    m=\u003cQuantity [5640.62516958, 4070.66620947, 6106.583697  , 4063.39917315, 3028.85393523] solMass\u003e,\n    notes='a random galaxy made with random numbers')\n\n# we can access al the attributes in the traditional python way\n\u003e\u003e\u003e gal.x\n\u003cQuantity [5632.35740606, 1363.36235923, 3037.46794044, 2785.45299727, 2515.35793673] kpc\u003e\n\n\u003e\u003e\u003e gal.vz  # z is now a km/s\n\u003cQuantity [6218.56279077, 2015.04638043, 9919.99579782, 1278.94359767, 7228.21626876] km / s\u003e\n\n# We stored y as mpc (milliparsec)\n\u003e\u003e\u003e gal.y\n\u003cQuantity [8093.44916403, 2198.55398718, 5464.79397835, 1860.72260272, 3636.64010118] mpc\u003e\n\n```\n\n\n## Simple interaction with `numpy.ndarray`\n\nWe can access all the same attributes declared with `uttr.ib but` coerced to the default unit as numpy array.\n\n```python\n\u003e\u003e\u003e gal.arr_.y\narray([0.00809345, 0.00219855, 0.00546479, 0.00186072, 0.00363664])\n```\n\nThe above code is equivalent to\n\n```python\n\u003e\u003e\u003e gal.y.to_value(u.kpc)\narray([0.00809345, 0.00219855, 0.00546479, 0.00186072, 0.00363664])\n```\n\n## Equivalent units errors\n\nIf we change the unit to something not equivalent to the default unit\ndeclares in `uttr.ib` an exception is raised.\n\nLets fot example define `x` as a kilogram (`u.kg`)\n\n```python\n\u003e\u003e\u003e gal = Galaxy(\n...     x = x * u.kg,  # kg is not equivalent to kpc\n...     y = y,\n...     z = z,\n...     vx = vx,\n...     vy = vy,\n...     vz = vz,\n...     m = m,\n...     notes=\"a random galaxy made with random numbers\")\n\nValueError: Unit of attribute 'x' must be equivalent to 'kpc'.Found 'kg'.\n```\n\n\n## References\n\n### Astropy\n\n\u003e Price-Whelan, Adrian M., et al. \"The Astropy project:\n  Building an open-science project and status of the v2. 0 core\n  package.\" The Astronomical Journal 156.3 (2018): 123.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquatrope%2Futtrs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fquatrope%2Futtrs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquatrope%2Futtrs/lists"}