Completed
Pull Request — develop (#12)
by Adam
52s
created

plot_band()   B

Complexity

Conditions 2

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
dl 0
loc 24
rs 8.9713
c 1
b 0
f 0
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
4
# Copyright (c) 2016-2017 Adam.Dybbroe
5
6
# Author(s):
7
8
#   Adam.Dybbroe <[email protected]>
9
10
# This program is free software: you can redistribute it and/or modify
11
# it under the terms of the GNU General Public License as published by
12
# the Free Software Foundation, either version 3 of the License, or
13
# (at your option) any later version.
14
15
# This program is distributed in the hope that it will be useful,
16
# but WITHOUT ANY WARRANTY; without even the implied warranty of
17
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
# GNU General Public License for more details.
19
20
# You should have received a copy of the GNU General Public License
21
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
23
"""A very basic (example) plotting program to display spectral responses for a
24
set of satellite instruments for a give wavelength range
25
26
"""
27
28
import matplotlib.pyplot as plt
29
from pyspectral.rsr_reader import RelativeSpectralResponse
30
from pyspectral.utils import get_bandname_from_wavelength
31
#import logging
32
from pyspectral.utils import logging_on, logging_off, get_logger
33
import numpy as np
34
35
36
def plot_band(plt_in, band_name, spec_response, pltname=None):
37
    """Do the plotting of one band
38
    """
39
40
    detectors = spec_response[band_name].keys()
41
    # for det in detectors:
42
    det = detectors[0]
43
    resp = spec_response[band_name][det]['response']
44
    wvl = spec_response[band_name][det]['wavelength']
45
46
    resp = np.ma.masked_less_equal(resp, minimum_response)
47
    wvl = np.ma.masked_array(wvl, resp.mask)
48
    resp.compressed()
49
    wvl.compressed()
50
51
    # plt.plot(wvl, resp, label='{platform} - {sensor} - {band}'.format(
52
    #    platform=platform, sensor=sensor, band=band))
53
    if pltname:
54
        plt_in.plot(wvl, resp, label='{platform} - {band}'.format(
55
            platform=pltname, band=band_name))
56
    else:
57
        plt_in.plot(wvl, resp, label='{band}'.format(band=band_name))
58
59
    return plt_in
60
61
if __name__ == "__main__":
62
    import argparse
63
    import sys
64
    parser = argparse.ArgumentParser(
65
        description='Plot spectral responses for a set of satellite imagers')
66
67
    parser.add_argument("--platform_name", '-p', nargs='*',
68
                        help="The Platform name",
69
                        type=str, required=True)
70
    parser.add_argument("--sensor", '-s', nargs='*',
71
                        help="The sensor/instrument name",
72
                        type=str, required=True)
73
    parser.add_argument("-x", "--xlimits", nargs=2,
74
                        help=("x-axis boundaries for plot"),
75
                        default=None, type=float)
76
    parser.add_argument("-t", "--minimum_response",
77
                        help=("Minimum response: Any response lower than " +
78
                              "this will be ignored when plotting"),
79
                        default=0.015, type=float)
80
81
    parser.add_argument("-no_platform_name_in_legend", help=("No platform name in legend"),
82
                        action='store_true')
83
    parser.add_argument("--title", help=("Plot title"),
84
                        default=None, type=str)
85
    parser.add_argument("-o", "--filename", help=("Output plot file name"),
86
                        default=None, type=str)
87
    parser.add_argument(
88
        "-v", '--verbose', help=("Turn logging on"), action='store_true')
89
90
    group = parser.add_mutually_exclusive_group(required=True)
91
    group.add_argument("--bandname", '-b',
92
                       help="The sensor band name", type=str)
93
    group.add_argument("--wavelength", "-w", type=float,
94
                       help='the approximate spectral wavelength in micron')
95
    group.add_argument("--range", "-r", nargs='*',
96
                       help="The wavelength range for the plot",
97
                       default=[None, None], type=float)
98
99
    LOG = get_logger(__name__)
100
101
    args = parser.parse_args()
102
    platform_names = args.platform_name
103
    sensors = args.sensor
104
    minimum_response = args.minimum_response
105
    xlimits = args.xlimits
106
    title = args.title
107
    if not title:
108
        title = 'Relative Spectral Responses'
109
    filename = args.filename
110
    no_platform_name_in_legend = args.no_platform_name_in_legend
111
    verbose = args.verbose
112
113
    if verbose:
114
        logging_on()
115
    else:
116
        logging_off()
117
118
    req_wvl = None
119
    band = None
120
    wvlmin, wvlmax = args.range
121
    if args.bandname:
122
        band = args.bandname
123
    elif args.wavelength:
124
        req_wvl = args.wavelength
125
126
    figscale = 1.0
127
    if wvlmin:
128
        figscale = (wvlmax - wvlmin) / 4.
129
    figsize = (figscale * 1. + 10, figscale * 0.5 + 5)
130
131
    plt.figure(figsize=figsize)
132
    something2plot = False
133
    for platform in platform_names:
134
        for sensor in sensors:
135
            try:
136
                rsr = RelativeSpectralResponse(platform, sensor)
137
            except IOError:
138
                # LOG.exception('Failed getting the rsr data for platform %s ' +
139
                #               'and sensor %s', platform, sensor)
140
                rsr = None
141
            else:
142
                break
143
144
        if not rsr:
145
            continue
146
147
        something2plot = True
148
        if req_wvl:
149
            band = get_bandname_from_wavelength(req_wvl, rsr.rsr, 0.5)
150
            if not band:
151
                continue
152
            if no_platform_name_in_legend:
153
                plt = plot_band(plt, band, rsr.rsr)
154
            else:
155
                plt = plot_band(plt, band, rsr.rsr, platform)
156
        elif band:
157
            if no_platform_name_in_legend:
158
                plt = plot_band(plt, band, rsr.rsr)
159
            else:
160
                plt = plot_band(plt, band, rsr.rsr, platform)
161
        else:
162
            wvlx = wvlmin
163
            prev_band = None
164
            while wvlx < wvlmax:
165
                band = get_bandname_from_wavelength(wvlx, rsr.rsr, 0.05)
166
                wvlx = wvlx + 0.05
167
                if not band:
168
                    continue
169
                if band != prev_band:
170
                    if no_platform_name_in_legend:
171
                        plt = plot_band(plt, band, rsr.rsr)
172
                    else:
173
                        plt = plot_band(plt, band, rsr.rsr, platform)
174
                    prev_band = band
175
176
    if not something2plot:
177
        LOG.error("Nothing to plot!")
178
        sys.exit(0)
179
180
    wmin, wmax = plt.xlim()
181
    delta_x = (wmax - wmin)
182
    wmax = wmax + delta_x / 4.0
183
    if xlimits:
184
        wmin = xlimits[0]
185
        wmax = xlimits[1]
186
187
    plt.xlim((wmin, wmax))
188
189
    plt.title(title)
190
    plt.legend(loc='lower right')
191
    if filename:
192
        plt.savefig(filename)
193
    else:
194
        if req_wvl:
195
            plt.savefig('rsr_band_{:>04d}.png'.format(int(100 * req_wvl)))
196
        elif wvlmin and wvlmax:
197
            plt.savefig('rsr_band_{:>04d}_{:>04d}.png'.format(
198
                int(100 * wvlmin), int(100 * wvlmax)))
199
        else:
200
            plt.savefig('rsr_band_{bandname}.png'.format(bandname=band))
201