pyExtinction 2.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.
@@ -0,0 +1,12 @@
1
+ # SPDX-FileCopyrightText: 2013-present Yannick Copin <y.copin@ip2i.in2p3.fr>
2
+ # SPDX-License-Identifier: CECILL-C
3
+
4
+ """pyExtinction initialization."""
5
+
6
+ __version__ = '2.0'
7
+ __author__ = "Yannick Copin <y.copin@ip2i.in2p3.fr>, " \
8
+ "Clément Buton <c.buton@araiko.ai>"
9
+
10
+ __all__ = ['atmospheric_extinction']
11
+ for _mod in __all__:
12
+ __import__(__name__ + "." + _mod, fromlist=[None])
@@ -0,0 +1,206 @@
1
+ #!/usr/bin/env python3
2
+ # SPDX-FileCopyrightText: 2013-present Yannick Copin <y.copin@ip2i.in2p3.fr>
3
+ # SPDX-License-Identifier: CECILL-C
4
+
5
+ import argparse
6
+ import os
7
+ import numpy as np
8
+ import matplotlib.pyplot as plt
9
+
10
+ from pyextinction import __version__
11
+ from pyextinction.atmospheric_extinction import ExtinctionModel, O3Template
12
+
13
+ def main():
14
+
15
+ # Options =================================================================
16
+
17
+ description = """\
18
+ Compute and/or plot atmospheric extinction from physical parameters,
19
+ as described in Buton et al. (2013A&A...549A...8B), *Atmospheric
20
+ extinction properties above Mauna Kea from the Nearby Supernova
21
+ Factory spectro-photometric data set*.
22
+
23
+ Default extinction parameters correspond to mean Mauna-Kea summit
24
+ conditions. Each extinction parameter can be specified using option
25
+ '--param value stderr'.
26
+ """
27
+
28
+ epilog = """\
29
+
30
+ If you have found this software useful for your research, we would
31
+ appreciate a reference to *the atmospheric extinction of Buton et
32
+ al. (2013)*.
33
+ """
34
+
35
+ parser = argparse.ArgumentParser(
36
+ description=description,
37
+ epilog=epilog,
38
+ formatter_class=argparse.RawDescriptionHelpFormatter,
39
+ )
40
+
41
+ parser.add_argument(
42
+ "--version",
43
+ action="version",
44
+ version=__version__,
45
+ )
46
+
47
+ # Rayleigh parameters ------------------------------------------------------
48
+
49
+ rayleigh = parser.add_argument_group("Rayleigh parameters")
50
+
51
+ rayleigh.add_argument(
52
+ "-p",
53
+ "--pressure",
54
+ type=float,
55
+ nargs=2,
56
+ default=(616.0, 2.0),
57
+ metavar=("PRESSURE", "STDERR"),
58
+ help="Surface pressure [%(default)s mbar]",
59
+ )
60
+
61
+ # Ozone parameters ---------------------------------------------------------
62
+
63
+ ozone = parser.add_argument_group("Ozone parameters")
64
+
65
+ ozone.add_argument(
66
+ "-t",
67
+ "--o3template",
68
+ metavar="FILE.fits",
69
+ default=O3Template,
70
+ help="Ozone transmission template [%(default)s]",
71
+ )
72
+
73
+ ozone.add_argument(
74
+ "-c",
75
+ "--o3column",
76
+ type=float,
77
+ nargs=2,
78
+ default=(257.0, 23.0),
79
+ metavar=("COLUMN", "STDERR"),
80
+ help="Ozone column density [%(default)s DU]",
81
+ )
82
+
83
+ # Aerosol parameters -------------------------------------------------------
84
+
85
+ aerosols = parser.add_argument_group("Aerosol parameters")
86
+
87
+ aerosols.add_argument(
88
+ "-d",
89
+ "--depth",
90
+ type=float,
91
+ nargs=2,
92
+ default=(7.6e-3, 1.4e-3),
93
+ metavar=("DEPTH", "STDERR"),
94
+ help="Aerosol optical depth at 1 micron [%(default)s]",
95
+ )
96
+
97
+ aerosols.add_argument(
98
+ "-a",
99
+ "--angstrom",
100
+ type=float,
101
+ nargs=2,
102
+ default=(1.26, 1.33),
103
+ metavar=("EXPONENT", "STDERR"),
104
+ help="Aerosol Angstrom exponent [%(default)s]",
105
+ )
106
+
107
+ # Output parameters --------------------------------------------------------
108
+
109
+ outputs = parser.add_argument_group("Output parameters")
110
+
111
+ outputs.add_argument(
112
+ "-w",
113
+ "--wrange",
114
+ type=float,
115
+ nargs=3,
116
+ default=(3200.0, 10001.0, 10.0),
117
+ metavar=("START", "END", "STEP"),
118
+ help="Wavelength range [%(default)s Å]",
119
+ )
120
+
121
+ outputs.add_argument(
122
+ "-o",
123
+ "--output",
124
+ metavar="FILE.txt|fits",
125
+ default="atmosphericExtinction.txt",
126
+ help="Output table name (.txt or .fits) [%(default)s]",
127
+ )
128
+
129
+ outputs.add_argument(
130
+ "-P",
131
+ "--plot",
132
+ action="store_true",
133
+ help="Interactive plot",
134
+ )
135
+
136
+ outputs.add_argument(
137
+ "-T",
138
+ "--transmission",
139
+ action="store_true",
140
+ help="Plot transmission rather than extinction",
141
+ )
142
+
143
+ # Check for options consistency ============================================
144
+
145
+ args = parser.parse_args()
146
+
147
+ # Wavelength range
148
+ w_start, w_end, w_step = args.wrange
149
+
150
+ if w_start > w_end or w_step > (w_end - w_start):
151
+ parser.error(
152
+ f"Invalid wavelength range '--wrange {','.join(map(str, args.wrange))}'.")
153
+
154
+ # Output
155
+ if args.output:
156
+ _, outformat = os.path.splitext(args.output)
157
+ if outformat.lower() not in (".fits", ".txt"):
158
+ parser.error(f"Unknown output format {outformat!r}.")
159
+
160
+ outformat = outformat[1:].lower()
161
+
162
+ # ==========================================================================
163
+
164
+ # Input parameters ---------------------------------------------------------
165
+
166
+ # Wavelength domain
167
+ lbda = np.arange(w_start, w_end, w_step, dtype=float)
168
+
169
+ # Extinction parameters
170
+ o3, do3 = args.o3column
171
+ ang, dang = args.angstrom
172
+ tau, dtau = args.depth
173
+ p, dp = args.pressure
174
+
175
+ # Extinction model ----------------------------------------------------------
176
+
177
+ ext_model = ExtinctionModel(lbda, args.o3template)
178
+
179
+ ext = ext_model.extinction(
180
+ [p, o3, tau, ang],
181
+ [dp, do3, dtau, dang],
182
+ components=True,
183
+ )
184
+
185
+ print(ext_model)
186
+
187
+ # Create output tables -----------------------------------------------------
188
+
189
+ if args.output:
190
+ print(f"Saving extinction table {args.output!r}...")
191
+ ext_model.write(args.output, ext, outformat)
192
+
193
+ # Create output graphics ---------------------------------------------------
194
+
195
+ if args.plot:
196
+ print("Generating interactive figure...")
197
+
198
+ ax = ext_model.plot(
199
+ ext,
200
+ components=True,
201
+ transmission=args.transmission,
202
+ )
203
+
204
+ plt.show()
205
+
206
+ print(epilog)
@@ -0,0 +1,141 @@
1
+ #!/usr/bin/env python
2
+
3
+ import os
4
+ import numpy as np
5
+ from .pyextinction import O3Template, ExtinctionModel
6
+
7
+ import optparse
8
+
9
+ # Options =================================================================
10
+
11
+ usage = "usage: %prog [options]"
12
+
13
+ description = """\
14
+ Compute and/or plot atmospheric extinction from physical parameters,
15
+ as described in Buton et al. (2013A&A...549A...8B), *Atmospheric
16
+ extinction properties above Mauna Kea from the Nearby Supernova
17
+ Factory spectro-photometric data set*.
18
+
19
+ Default extinction parameters correspond to mean Mauna-Kea summit
20
+ conditions. Each extinction parameter can be specified using option
21
+ '--param value stderr'.
22
+ """
23
+ epilog = """\
24
+ If you have found this software useful for your research, we would
25
+ appreciate a reference to *the atmospheric extinction of Buton et
26
+ al. (2013)*."""
27
+
28
+ parser = optparse.OptionParser(usage, version=__version__,
29
+ description=description,
30
+ epilog=epilog)
31
+
32
+ # Rayleigh parameters ------------------------------
33
+
34
+ rayleigh = optparse.OptionGroup(parser, "Rayleigh parameters")
35
+
36
+ rayleigh.add_option('-p', '--pressure', type=float, nargs=2,
37
+ help="Surface pressure [%default mbar]",
38
+ default=(616., 2.))
39
+
40
+ parser.add_option_group(rayleigh)
41
+
42
+ # Ozone parameters ------------------------------
43
+
44
+ ozone = optparse.OptionGroup(parser, "Ozone parameters")
45
+
46
+ ozone.add_option('-t', '--o3template', metavar='FILE.fits',
47
+ help="Ozone transmission template",
48
+ default=O3Template)
49
+ ozone.add_option('-c', '--o3column', type=float, nargs=2,
50
+ help="Ozone column density [%default DU]",
51
+ default=(257., 23.))
52
+
53
+ parser.add_option_group(ozone)
54
+
55
+ # Aerosol parameters ------------------------------
56
+
57
+ aerosols = optparse.OptionGroup(parser, "Aerosol parameters")
58
+
59
+ aerosols.add_option('-d', '--depth', type=float, nargs=2,
60
+ help="Aerosol optical depth at 1 micron [%default]",
61
+ default=(7.6e-3, 1.4e-3))
62
+ aerosols.add_option('-a', '--angstrom', type=float, nargs=2,
63
+ help="Aerosol Angstrom exponent [%default]",
64
+ default=(1.26, 1.33))
65
+
66
+ parser.add_option_group(aerosols)
67
+
68
+ # Output ------------------------------
69
+
70
+ outputs = optparse.OptionGroup(parser, "Output parameters")
71
+
72
+ outputs.add_option('-w', '--wrange', metavar='START,END,STEP',
73
+ type=float, nargs=3,
74
+ help="Wavelength range [%default A]",
75
+ default=(3200, 10001, 10))
76
+
77
+ outputs.add_option('-o', '--output', metavar="FILE.txt|fits",
78
+ help="Output table name (.txt|.fits)",
79
+ default="atmosphericExtinction.txt")
80
+
81
+ outputs.add_option("-P", "--plot", action='store_true',
82
+ help="Interactive plot")
83
+ outputs.add_option("-T", "--transmission", action='store_true',
84
+ help="Plot transmission rather than extinction")
85
+
86
+ parser.add_option_group(outputs)
87
+
88
+ # Check for options consistency ============================================
89
+
90
+ opts, args = parser.parse_args()
91
+
92
+ # Wavelength range
93
+ wStart, wEnd, wStep = opts.wrange
94
+ if (wStart > wEnd) or (wStep > (wEnd - wStart)):
95
+ parser.error("Invalid wavelength range '--wrange %s'" %
96
+ (','.join(opts.wrange)))
97
+
98
+ # Output
99
+ if opts.output: # Decipher output format
100
+ basename, outformat = os.path.splitext(opts.output)
101
+ if outformat.lower() not in ('.fits', '.txt'):
102
+ parser.error("Unknown output format '%s'" % outformat)
103
+ outformat = outformat[1:].lower() # Remove leading dot
104
+
105
+ # ==========================================================================
106
+
107
+ # Inputs parameters ------------------------------
108
+
109
+ # Wavelength domain
110
+ lbda = np.arange(wStart, wEnd, wStep, dtype=float)
111
+
112
+ # Extinction parameters
113
+ o3, do3 = opts.o3column # Ozone column density [DU]
114
+ ang, dang = opts.angstrom # Ångström exponent
115
+ tau, dtau = opts.depth # Aerosol optical depth at ref. wavelength
116
+ p, dp = opts.pressure # Surface pressure [mbar]
117
+
118
+ # Extinction model ------------------------------
119
+
120
+ extModel = ExtinctionModel(lbda, opts.o3template)
121
+ ext = extModel.extinction([ p, o3, tau, ang],
122
+ [dp, do3, dtau, dang], components=True)
123
+ desc = str(extModel)
124
+ print desc
125
+
126
+ # Create output tables ------------------------------
127
+
128
+ if opts.output:
129
+ print "Saving extinction table '%s'..." % opts.output
130
+ extModel.write(opts.output, ext, outformat)
131
+
132
+ # Create output graphics ------------------------------
133
+
134
+ if opts.plot:
135
+ print "Generating interactive figure..."
136
+ import matplotlib.pyplot as P
137
+
138
+ ax = extModel.plot(ext, components=True, transmission=opts.transmission)
139
+ P.show()
140
+
141
+ print epilog