getframes 2.0.0__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.
- getframes/__about__.py +4 -0
- getframes/__init__.py +91 -0
- getframes/analysis/__init__.py +18 -0
- getframes/analysis/apertures.py +92 -0
- getframes/analysis/ptc.py +109 -0
- getframes/calibrate.py +182 -0
- getframes/camera.py +649 -0
- getframes/cli.py +214 -0
- getframes/config.py +420 -0
- getframes/dataset.py +294 -0
- getframes/frame.py +107 -0
- getframes/noise.py +637 -0
- getframes/observation.py +162 -0
- getframes/presets/__init__.py +90 -0
- getframes/presets/data/__init__.py +3 -0
- getframes/presets/data/andor_ikon_m934.toml +22 -0
- getframes/presets/data/andor_ixon_ultra_888.toml +22 -0
- getframes/presets/data/generic_ccd.toml +18 -0
- getframes/presets/data/generic_cmos.toml +18 -0
- getframes/presets/data/generic_eapd.toml +20 -0
- getframes/presets/data/generic_emccd.toml +20 -0
- getframes/presets/data/generic_scmos.toml +21 -0
- getframes/presets/data/hamamatsu_orca_fusion.toml +25 -0
- getframes/presets/data/leonardo_saphira.toml +32 -0
- getframes/presets/data/zwo_asi2600mm.toml +20 -0
- getframes/py.typed +0 -0
- getframes/scene/__init__.py +51 -0
- getframes/scene/optics.py +180 -0
- getframes/scene/photometry.py +311 -0
- getframes/scene/psf.py +371 -0
- getframes/scene/scene.py +205 -0
- getframes/scene/sources.py +683 -0
- getframes/scene/thermal.py +114 -0
- getframes/scene/wcs.py +110 -0
- getframes/spectral.py +449 -0
- getframes-2.0.0.dist-info/METADATA +218 -0
- getframes-2.0.0.dist-info/RECORD +40 -0
- getframes-2.0.0.dist-info/WHEEL +4 -0
- getframes-2.0.0.dist-info/entry_points.txt +2 -0
- getframes-2.0.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: getframes
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: Generate physically realistic synthetic camera frames (CCD/CMOS/EMCCD/eAPD/sCMOS) — dark, bias, flat, and rendered star fields — with auditable noise physics for scientific imaging pipelines.
|
|
5
|
+
Project-URL: Homepage, https://github.com/jacotay7/getframes
|
|
6
|
+
Project-URL: Documentation, https://jacotay7.github.io/getframes/
|
|
7
|
+
Project-URL: Repository, https://github.com/jacotay7/getframes
|
|
8
|
+
Project-URL: Issues, https://github.com/jacotay7/getframes/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/jacotay7/getframes/blob/main/CHANGELOG.md
|
|
10
|
+
Author-email: Jacob Taylor <jacobataylor7@gmail.com>
|
|
11
|
+
License: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: astronomy,camera,ccd,cmos,detector,emccd,imaging,noise,simulation
|
|
14
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
15
|
+
Classifier: Intended Audience :: Science/Research
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering :: Astronomy
|
|
24
|
+
Classifier: Topic :: Scientific/Engineering :: Image Processing
|
|
25
|
+
Classifier: Typing :: Typed
|
|
26
|
+
Requires-Python: >=3.10
|
|
27
|
+
Requires-Dist: astropy>=5.0
|
|
28
|
+
Requires-Dist: numpy>=1.23
|
|
29
|
+
Requires-Dist: scipy>=1.10
|
|
30
|
+
Requires-Dist: tomli>=2.0; python_version < '3.11'
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: build>=1.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: mypy>=1.8; extra == 'dev'
|
|
34
|
+
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
36
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
37
|
+
Provides-Extra: docs
|
|
38
|
+
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
|
|
39
|
+
Requires-Dist: mkdocs>=1.5; extra == 'docs'
|
|
40
|
+
Requires-Dist: mkdocstrings[python]>=0.24; extra == 'docs'
|
|
41
|
+
Provides-Extra: examples
|
|
42
|
+
Requires-Dist: matplotlib>=3.7; extra == 'examples'
|
|
43
|
+
Description-Content-Type: text/markdown
|
|
44
|
+
|
|
45
|
+
# getframes
|
|
46
|
+
|
|
47
|
+
[](https://github.com/jacotay7/getframes/actions/workflows/ci.yml)
|
|
48
|
+
[](https://pypi.org/project/getframes/)
|
|
49
|
+
[](https://pypi.org/project/getframes/)
|
|
50
|
+
[](LICENSE)
|
|
51
|
+
|
|
52
|
+
**Realistic synthetic camera frames for scientific imaging pipelines.**
|
|
53
|
+
|
|
54
|
+
`getframes` gives you a clean, small API for generating physically realistic frames
|
|
55
|
+
from **CCD**, **CMOS**, **EMCCD**, **eAPD**, and **sCMOS** detectors — with
|
|
56
|
+
accurate, auditable noise physics (read noise, dark current, shot noise,
|
|
57
|
+
fixed-pattern non-uniformity, a unified stochastic gain stage, clock-induced
|
|
58
|
+
charge, nonlinearity, and cosmic rays) so you can build and validate
|
|
59
|
+
image-processing pipelines against ground truth.
|
|
60
|
+
|
|
61
|
+
It generates **dark**, **bias**, and **flat** frames, and renders **star fields**
|
|
62
|
+
through a PSF and telescope into a realistic science frame — the full
|
|
63
|
+
photon → electron → ADU signal path, with optional opt-in spectral mode.
|
|
64
|
+
|
|
65
|
+
> **Status:** stable. `getframes` 2.0 freezes the full public surface — the
|
|
66
|
+
> detector, scene, calibration, observation, radiometry, and dataset APIs — under
|
|
67
|
+
> [Semantic Versioning](https://semver.org/spec/v2.0.0.html); see
|
|
68
|
+
> [API stability](docs/stability.md).
|
|
69
|
+
|
|
70
|
+
## Install
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pip install getframes
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
From source (for development):
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
git clone https://github.com/jacotay7/getframes
|
|
80
|
+
cd getframes
|
|
81
|
+
pip install -e ".[dev]"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Quick start
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
import getframes as gf
|
|
88
|
+
|
|
89
|
+
# Pick a camera from the built-in preset library...
|
|
90
|
+
cam = gf.Camera.from_preset("andor_ikon_m934")
|
|
91
|
+
|
|
92
|
+
# ...and generate a reproducible dark frame.
|
|
93
|
+
frame = cam.dark_frame(exposure=60.0, temperature=-60.0, seed=0)
|
|
94
|
+
|
|
95
|
+
frame.data # 2-D numpy array of ADU, shape (1024, 1024)
|
|
96
|
+
frame.stats() # {'mean': ..., 'median': ..., 'std': ..., 'min': ..., 'max': ...}
|
|
97
|
+
frame.metadata # camera/exposure/temperature provenance
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
`Frame` is array-like, so it drops straight into NumPy:
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
import numpy as np
|
|
104
|
+
master_dark = np.mean([np.asarray(f) for f in cam.dark_series(60.0, n_frames=20, seed=1)], axis=0)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Define your own camera
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
cam = gf.Camera(
|
|
111
|
+
gf.CameraConfig(
|
|
112
|
+
name="My Lab CMOS",
|
|
113
|
+
sensor_type="CMOS",
|
|
114
|
+
resolution=(2048, 2048), # (height, width)
|
|
115
|
+
pixel_size_um=6.5,
|
|
116
|
+
quantum_efficiency=0.82,
|
|
117
|
+
full_well_e=30_000,
|
|
118
|
+
bit_depth=12,
|
|
119
|
+
gain_e_per_adu=0.8,
|
|
120
|
+
bias_offset_adu=300,
|
|
121
|
+
read_noise_e=1.8,
|
|
122
|
+
dark_current_e_per_s=0.5, # at the reference temperature
|
|
123
|
+
dark_current_ref_temp_c=20.0,
|
|
124
|
+
dark_current_doubling_temp_c=6.0,
|
|
125
|
+
)
|
|
126
|
+
)
|
|
127
|
+
frame = cam.dark_frame(exposure=30.0, temperature=-10.0)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Observe a simulated star field
|
|
131
|
+
|
|
132
|
+
Render astronomical sources through a PSF and telescope, then expose them on a
|
|
133
|
+
detector — the full photon → electron → ADU path:
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
scene = gf.Scene(
|
|
137
|
+
shape=(256, 256),
|
|
138
|
+
optics=gf.Telescope(aperture_diameter_m=2.5, throughput=0.3,
|
|
139
|
+
plate_scale_arcsec_per_pixel=0.4, band=gf.Bandpass.johnson("V")),
|
|
140
|
+
psf=gf.MoffatPSF(fwhm_arcsec=1.1, beta=3.0),
|
|
141
|
+
sources=[gf.PointSource(x=128, y=128, magnitude=20.0)],
|
|
142
|
+
sky=gf.Sky(surface_brightness_mag_arcsec2=21.0),
|
|
143
|
+
)
|
|
144
|
+
cam = gf.Camera.from_preset("zwo_asi2600mm").with_config(resolution=(256, 256))
|
|
145
|
+
frame = cam.observe(scene, exposure=300.0, seed=0) # a realistic science frame
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
You can also drive the detector directly with a photon-rate map (a scalar for a
|
|
149
|
+
uniform flat, or a per-pixel array): `cam.expose(photon_rate, exposure)`.
|
|
150
|
+
|
|
151
|
+
### Browse the preset library
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
from getframes import available_presets
|
|
155
|
+
from getframes.presets import preset_info
|
|
156
|
+
|
|
157
|
+
available_presets() # ['andor_ikon_m934', 'andor_ixon_ultra_888', 'generic_ccd', ...]
|
|
158
|
+
preset_info() # rich descriptors for each preset
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
| Preset | Sensor | Notes |
|
|
162
|
+
| --- | --- | --- |
|
|
163
|
+
| `andor_ikon_m934` | CCD | Deep-cooled back-illuminated scientific CCD |
|
|
164
|
+
| `andor_ixon_ultra_888` | EMCCD | Single-photon-sensitive EMCCD |
|
|
165
|
+
| `leonardo_saphira` | EAPD | HgCdTe avalanche IR array (AO wavefront sensing) |
|
|
166
|
+
| `zwo_asi2600mm` | CMOS | Sony IMX571 cooled CMOS |
|
|
167
|
+
| `hamamatsu_orca_fusion` | sCMOS | Back-thinned sCMOS with per-pixel read noise |
|
|
168
|
+
| `generic_ccd` / `generic_cmos` / `generic_emccd` / `generic_eapd` / `generic_scmos` | — | Idealised references for teaching/testing |
|
|
169
|
+
|
|
170
|
+
## How the dark-frame model works
|
|
171
|
+
|
|
172
|
+
The dark signal chain (see [`getframes/noise.py`](src/getframes/noise.py)):
|
|
173
|
+
|
|
174
|
+
1. **Dark current vs. temperature** — `D(T) = D_ref · 2^((T − T_ref) / T_double)`
|
|
175
|
+
2. **Fixed-pattern non-uniformity (DSNU)** and **hot pixels** modulate the per-pixel mean
|
|
176
|
+
3. **Shot noise** — Poisson statistics on the dark electrons
|
|
177
|
+
4. **Clock-induced charge** (EMCCD) — small Poisson term
|
|
178
|
+
5. **EM gain** (EMCCD) — stochastic multiplication with realistic excess noise
|
|
179
|
+
6. **Read noise** — Gaussian at the output amplifier
|
|
180
|
+
7. **Digitisation** — gain conversion to ADU, bias pedestal, saturation, quantisation
|
|
181
|
+
|
|
182
|
+
All randomness flows through a seeded `numpy.random.Generator`, so every frame is
|
|
183
|
+
reproducible.
|
|
184
|
+
|
|
185
|
+
## Documentation
|
|
186
|
+
|
|
187
|
+
- [Guides & API reference](docs/) (built with MkDocs) — getting started, the
|
|
188
|
+
noise model, observing scenes, spectral mode, and presets
|
|
189
|
+
- [API stability & versioning](docs/stability.md)
|
|
190
|
+
- [Runnable examples](examples/) — PTC, star-field exposure planning, AO limiting
|
|
191
|
+
magnitude, transit photometry, detector realism
|
|
192
|
+
|
|
193
|
+
## Roadmap
|
|
194
|
+
|
|
195
|
+
**1.0 is shipped:** the full photon → electron → ADU signal path (dark, bias,
|
|
196
|
+
flat, and rendered scenes) across CCD / CMOS / EMCCD / eAPD / sCMOS, with a
|
|
197
|
+
unified gain stage, detector-realism effects, opt-in spectral mode, analysis
|
|
198
|
+
helpers, and a frozen API.
|
|
199
|
+
|
|
200
|
+
The **2.0 plan** moves from a *frame* to an *observation* — closing the
|
|
201
|
+
raw → reduced → ground-truth validation loop, making time-series (variability,
|
|
202
|
+
jitter, persistence) and richer scenes (extended sources, catalogs, sky
|
|
203
|
+
coordinates) first-class, and deepening detector and radiometric fidelity. See
|
|
204
|
+
[docs/roadmap.md](docs/roadmap.md) for the full critique, phased plan, and worked
|
|
205
|
+
examples.
|
|
206
|
+
|
|
207
|
+
## Contributing
|
|
208
|
+
|
|
209
|
+
Contributions — especially new camera presets — are welcome. See
|
|
210
|
+
[CONTRIBUTING.md](CONTRIBUTING.md). Run the checks locally with:
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
ruff check . && ruff format --check . && mypy && pytest
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## License
|
|
217
|
+
|
|
218
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
getframes/__about__.py,sha256=QgrU1hx8R7GlRUzJZZj2iK3ti2_QxCajvahTgdpUWCU,108
|
|
2
|
+
getframes/__init__.py,sha256=vDGPTcDWCclmU9p5HauzxRgusg28WrKMUzVbSDXeYWY,1846
|
|
3
|
+
getframes/calibrate.py,sha256=nkIuuUWT0tn0lWsPsxHOBpTCJW2v1h0xwB19O9QRFug,6609
|
|
4
|
+
getframes/camera.py,sha256=whMsL51Sc96zgtJMu1vnEuf3BScMN1Yrk0Cp7Ic-i2Y,25178
|
|
5
|
+
getframes/cli.py,sha256=XJNvz6LvXhi6mJJL2vCjhu6yNMeNyyZ6IBYQmMQDqRk,7973
|
|
6
|
+
getframes/config.py,sha256=hoQ_qjy_O24s4kb0OA3S0d5651rQpOoMl344cHcWrD0,20635
|
|
7
|
+
getframes/dataset.py,sha256=mGyCz2jb73d5Ymvqrva2x_xWe_MJbpisaD6MS69_QS8,10882
|
|
8
|
+
getframes/frame.py,sha256=hbWQpvZLKIuw0iXpwOAutSbXd5NI6LZjgUqbjjRQi3g,3871
|
|
9
|
+
getframes/noise.py,sha256=x2Mb8VzGn-R8izBcildhYZujj_e0AE1nabatsNt_V60,26731
|
|
10
|
+
getframes/observation.py,sha256=voFRO5dB3bta_W5e494ZkTsezd6T7CsCchvla93e72w,5961
|
|
11
|
+
getframes/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
+
getframes/spectral.py,sha256=nRN5GaIO80NelOkDqoWBfwIQHWLtWxtcA8LoXSpL3Qc,18602
|
|
13
|
+
getframes/analysis/__init__.py,sha256=zpVsy3qcZmhoyjB_WNrTxgCdEgDDp3Jx8fhvTJ6Pshg,499
|
|
14
|
+
getframes/analysis/apertures.py,sha256=jffwmSAKfFsqS93K_iL7QJ7K69DpEhWwgNAv-Py4JfU,3212
|
|
15
|
+
getframes/analysis/ptc.py,sha256=XvxzjinZ6ruQ6BYAFOilEQRh-P-Lr_MNJRff1lB0AkM,4012
|
|
16
|
+
getframes/presets/__init__.py,sha256=B-hdvW_hzJjNnq3oh26RRCeyWlNvd11eJnf4lbJrXtI,2753
|
|
17
|
+
getframes/presets/data/__init__.py,sha256=AEjme3yN51EOw-w3ZtoeOq_kXVeiZX_Vib3zY7qLZmM,162
|
|
18
|
+
getframes/presets/data/andor_ikon_m934.toml,sha256=KMk3nWTTaMCD3QR_X0uu5xA5ZKGzI6xiz7g1bCTNoDw,861
|
|
19
|
+
getframes/presets/data/andor_ixon_ultra_888.toml,sha256=J_A9j0HDtyXCuCNGPGj2WiogXuZlM03eJj5sF55AxGM,812
|
|
20
|
+
getframes/presets/data/generic_ccd.toml,sha256=zsZgDQZN_oAdwc8KkNaw315KwrP5D41UPrW_7aba6oY,523
|
|
21
|
+
getframes/presets/data/generic_cmos.toml,sha256=-bBn_-GhMvdrcDUPKoHqpo278yre8PSWvXywj8jEE0g,539
|
|
22
|
+
getframes/presets/data/generic_eapd.toml,sha256=IEnFxouV4h3VQCzv1EJ1KFWtcpI9nIQ3mfxD73GPsOg,709
|
|
23
|
+
getframes/presets/data/generic_emccd.toml,sha256=txGHZeCZLefCYce5N0Jp7BvBLA6ppuAU1ahg5YywpfM,566
|
|
24
|
+
getframes/presets/data/generic_scmos.toml,sha256=Y3yWEnOe_16mg9xt7lGaUMEtr-wd6ZpfvlkSI0o5SbI,670
|
|
25
|
+
getframes/presets/data/hamamatsu_orca_fusion.toml,sha256=WKyiZOzEvDzOqNZ2P7_EYY2FdEignAW-5LDDQbfnUCQ,927
|
|
26
|
+
getframes/presets/data/leonardo_saphira.toml,sha256=NySszBi6EJ_T3pPbqOpkqA14nvsC9u4sFqRXbM5O_B8,1601
|
|
27
|
+
getframes/presets/data/zwo_asi2600mm.toml,sha256=rWhKY14MhZKTyKlREo8X_lRtdfJZcKgFoqyf4YfhU4Y,696
|
|
28
|
+
getframes/scene/__init__.py,sha256=dv-1UUKLct0-At6mHie-TaHO7ODRX1mki0Ol7Wt_x3s,1195
|
|
29
|
+
getframes/scene/optics.py,sha256=3nHhEUNWPuLianUfhnY2ls7ia_zgvyY242_rdYNEIC8,7448
|
|
30
|
+
getframes/scene/photometry.py,sha256=COyGs6Y1he6VpeBPsnblPpjPzI2YlZS-ctVI8KB0NPY,13053
|
|
31
|
+
getframes/scene/psf.py,sha256=zhCxog6naqbg46JydgZuwd_Q1KpsvJv4TQlTxXPxekU,14245
|
|
32
|
+
getframes/scene/scene.py,sha256=fbtMDKnVBPWNWWtIKqAeNx3bHot5XgnQ7dnqjifUM_Q,8450
|
|
33
|
+
getframes/scene/sources.py,sha256=S-6evDUQWwKFzFPwpfs9Z9fBKXBOgRD4rvbWv0hnoC4,26984
|
|
34
|
+
getframes/scene/thermal.py,sha256=D3qaXjkTWTEZOAaWhzXz5C10I8LbJMxJEYRaPXpZIEs,4533
|
|
35
|
+
getframes/scene/wcs.py,sha256=OKiQ61GKRrCERdOzR5YDIAa-yB9tLRGdvZM2L387aSc,4311
|
|
36
|
+
getframes-2.0.0.dist-info/METADATA,sha256=whb3WX5CLwyXjzMaJHTg-BXHzjiWd5AV4FTYNiz3N1c,8643
|
|
37
|
+
getframes-2.0.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
38
|
+
getframes-2.0.0.dist-info/entry_points.txt,sha256=T0YhnQ84VNBUdT9zVkqgQFBIwXxQ12Gg51aE3iqwLkQ,49
|
|
39
|
+
getframes-2.0.0.dist-info/licenses/LICENSE,sha256=Rq27HaZyzpe1GFxNTVS3xJaRD_O4IauJs9fdQlEOuis,1069
|
|
40
|
+
getframes-2.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jacob Taylor
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|