# attune
[![image](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
Tools for tuning optical parametric amplifiers and multidimensional spectrometers.
Documentation is available at <https://attune.wright.tools/en/latest/>.
# Overview
`attune` has three primary jobs:
1. attune parses calibration data to find optimal motor positions
```
# data has scans of a motor position ("OPA1_SHS_crystal") against a signal
# ("signal") for a set of second harmonic signal color setpoints
# ("opa_color")
calibration_data = wt.open(path_to_data.wt5)
calibration_data.transform("opa_color", "motor")
args = {
"data": calibration_data,
"channel": "signal",
"arrangement": "SHS",
"tune": "SHS_crystal",
"instrument": "OPA1",
}
tuned_opa1 = attune.intensity(**args)
```
2. `attune` organizes optimal motor positions. The motor positions are stored in a hierarchy of mappings. Beginning at the lowest level:
* Tune : a map of OPA color (the "independent") to positions of a single motor (the "dependent").
```
my_tune = attune.Tune(
independent=[450, 600, 700],
dependent=[3.225, 2.332, 1.987]
) # relate color to bbo angle
```
* Arrangement : a collection of Tunes that define a concerted process (e.g. to generate idler photons, one might move several motors (`bbo`, `g1`, etc.))
```
idler = attune.Arrangement("idler", dict(bbo=my_tune, g1=my_other_tune))
```
* Instrument : a collection of Arrangements (e.g. an OPA may have signal and idler)
```
my_opa = attune.Instrument({"idler": idler, "signal": signal}, name="opa1")
```
Note: arrangements can be called as tunables if they exist in the same instrument. This can allow nested naming
```
shi = attune.Arrangement(Dict(
idler = Tune(shi_colors, idler_colors),
sh_crystal = Tune(shi_colors, angles)
))
```
3. `attune` stores motor mappings and remembers them through version tracking.
* save a new instrument (or update an existing one)
```
attune.store(my_opa)
```
* lookup a saved instrument (by name)
```
attune.catalog() # lists all saved instruments
my_opa = attune.load("opa1") # fetches the most recent version of the instrument
my_previous_opa = attune.undo(my_opa) # fetches the previous version of the instrument
my_old_opa = attune.load("opa1", time="yesterday") # optional kwarg specifies the version by time of usage
```
## Notes
* `attune` uses default units of nanometers ("nm") for its independent variables.
_At this time, units cannot be changed, so alternate units must be handled externally_ (PRs are welcome!).
WrightTools calibration data is automatically converted into "nm" units for parsing.
Raw data
{
"_id": null,
"home_page": "https://github.com/wright-group/attune",
"name": "attune",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": "",
"keywords": "spectroscopy science multidimensional visualization",
"author": "Blaise Thompson",
"author_email": "blaise@untzag.com",
"download_url": "https://files.pythonhosted.org/packages/c5/0a/8ef2f14610270892d6c71e71154607239e97d67f9e619a43d75c460117d4/attune-0.5.0.tar.gz",
"platform": null,
"description": "# attune\n\n[![image](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n\nTools for tuning optical parametric amplifiers and multidimensional spectrometers. \n\nDocumentation is available at <https://attune.wright.tools/en/latest/>.\n\n# Overview\n\n`attune` has three primary jobs:\n\n1. attune parses calibration data to find optimal motor positions\n ```\n # data has scans of a motor position (\"OPA1_SHS_crystal\") against a signal\n # (\"signal\") for a set of second harmonic signal color setpoints\n # (\"opa_color\")\n calibration_data = wt.open(path_to_data.wt5)\n calibration_data.transform(\"opa_color\", \"motor\")\n args = {\n \"data\": calibration_data,\n \"channel\": \"signal\",\n \"arrangement\": \"SHS\",\n \"tune\": \"SHS_crystal\",\n \"instrument\": \"OPA1\",\n }\n tuned_opa1 = attune.intensity(**args)\n ```\n\n2. `attune` organizes optimal motor positions. The motor positions are stored in a hierarchy of mappings. Beginning at the lowest level:\n\n * Tune : a map of OPA color (the \"independent\") to positions of a single motor (the \"dependent\"). \n ```\n my_tune = attune.Tune(\n independent=[450, 600, 700],\n dependent=[3.225, 2.332, 1.987]\n ) # relate color to bbo angle\n ```\n\n * Arrangement : a collection of Tunes that define a concerted process (e.g. to generate idler photons, one might move several motors (`bbo`, `g1`, etc.))\n ```\n idler = attune.Arrangement(\"idler\", dict(bbo=my_tune, g1=my_other_tune))\n ```\n\n * Instrument : a collection of Arrangements (e.g. an OPA may have signal and idler)\n ```\n my_opa = attune.Instrument({\"idler\": idler, \"signal\": signal}, name=\"opa1\")\n ```\n\n Note: arrangements can be called as tunables if they exist in the same instrument. This can allow nested naming\n ```\n shi = attune.Arrangement(Dict(\n idler = Tune(shi_colors, idler_colors), \n sh_crystal = Tune(shi_colors, angles)\n )) \n ```\n\n3. `attune` stores motor mappings and remembers them through version tracking. \n * save a new instrument (or update an existing one)\n ```\n attune.store(my_opa)\n ```\n\n * lookup a saved instrument (by name)\n ```\n attune.catalog() # lists all saved instruments\n my_opa = attune.load(\"opa1\") # fetches the most recent version of the instrument\n my_previous_opa = attune.undo(my_opa) # fetches the previous version of the instrument\n my_old_opa = attune.load(\"opa1\", time=\"yesterday\") # optional kwarg specifies the version by time of usage \n ```\n\n\n## Notes\n\n* `attune` uses default units of nanometers (\"nm\") for its independent variables.\n _At this time, units cannot be changed, so alternate units must be handled externally_ (PRs are welcome!).\n WrightTools calibration data is automatically converted into \"nm\" units for parsing.\n\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Tools for tuning optical parametric amplifiers and multidimensional spectrometers.",
"version": "0.5.0",
"project_urls": {
"Homepage": "https://github.com/wright-group/attune"
},
"split_keywords": [
"spectroscopy",
"science",
"multidimensional",
"visualization"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "5e5c2a084aad9d0e086a60d9315078313ec7177f13ad3add0b13d045f200d2ac",
"md5": "97c0094ac09d83f73211cf511881e992",
"sha256": "3b6b55b627b73a298248846d82cc5c491a62116b83af9651f68193c6f574e8e7"
},
"downloads": -1,
"filename": "attune-0.5.0-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "97c0094ac09d83f73211cf511881e992",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": ">=3.7",
"size": 31294,
"upload_time": "2024-01-25T21:48:42",
"upload_time_iso_8601": "2024-01-25T21:48:42.752018Z",
"url": "https://files.pythonhosted.org/packages/5e/5c/2a084aad9d0e086a60d9315078313ec7177f13ad3add0b13d045f200d2ac/attune-0.5.0-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "c50a8ef2f14610270892d6c71e71154607239e97d67f9e619a43d75c460117d4",
"md5": "ee97e5e1b6da2e00d28e2abe002589fd",
"sha256": "8ba17659683d9c064074d4c630d2c153d9999e6a6c4f2eb1331bce2a18efd18a"
},
"downloads": -1,
"filename": "attune-0.5.0.tar.gz",
"has_sig": false,
"md5_digest": "ee97e5e1b6da2e00d28e2abe002589fd",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 25462,
"upload_time": "2024-01-25T21:48:44",
"upload_time_iso_8601": "2024-01-25T21:48:44.648505Z",
"url": "https://files.pythonhosted.org/packages/c5/0a/8ef2f14610270892d6c71e71154607239e97d67f9e619a43d75c460117d4/attune-0.5.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-01-25 21:48:44",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "wright-group",
"github_project": "attune",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [],
"lcname": "attune"
}