Skip to content

earthlib.utils

Utility functions for working with spectral libraries and earth engine routines.

getBandDescriptions(sensor)

Returns a list band name descriptions by sensor.

Parameters:

Name Type Description Default
sensor str

the name of the sensor (from earthlib.listSensors()).

required

Returns:

Name Type Description
bands list

a list of sensor-specific band names.

Source code in earthlib/utils.py
127
128
129
130
131
132
133
134
135
136
137
138
def getBandDescriptions(sensor: str) -> list:
    """Returns a list band name descriptions by sensor.

    Args:
        sensor: the name of the sensor (from earthlib.listSensors()).

    Returns:
        bands: a list of sensor-specific band names.
    """
    validateSensor(sensor)
    bands = collections[sensor]["band_descriptions"]
    return bands

getBandIndices(custom_bands, sensor)

Cross-references a list of bands passed as strings to the 0-based integer indices

Parameters:

Name Type Description Default
custom_bands list

a list of band names.

required
sensor str

a string sensor type for indexing the supported collections.

required

Returns:

Name Type Description
indices list

list of integer band indices.

Source code in earthlib/utils.py
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
def getBandIndices(custom_bands: list, sensor: str) -> list:
    """Cross-references a list of bands passed as strings to the 0-based integer indices

    Args:
        custom_bands: a list of band names.
        sensor: a string sensor type for indexing the supported collections.

    Returns:
        indices: list of integer band indices.
    """
    validateSensor(sensor)
    sensor_bands = collections[sensor]["band_names"]
    indices = list()

    if type(custom_bands) in (list, tuple):
        for band in custom_bands:
            if band in sensor_bands:
                indices.append(sensor_bands.index(band))

    elif type(custom_bands) == str:
        indices.append(sensor_bands.index(custom_bands))

    indices.sort()
    return indices

getBands(sensor)

Returns a list of available band names by sensor.

Parameters:

Name Type Description Default
sensor str

the name of the sensor (from earthlib.listSensors()).

required

Returns:

Name Type Description
bands list

a list of sensor-specific band names.

Source code in earthlib/utils.py
113
114
115
116
117
118
119
120
121
122
123
124
def getBands(sensor: str) -> list:
    """Returns a list of available band names by sensor.

    Args:
        sensor: the name of the sensor (from earthlib.listSensors()).

    Returns:
        bands: a list of sensor-specific band names.
    """
    validateSensor(sensor)
    bands = collections[sensor]["band_names"]
    return bands

getCollection(sensor)

Returns the default image collection for a satellite sensor.

Parameters:

Name Type Description Default
sensor str

the name of the sensor (from earthlib.listSensors()).

required

Returns:

Type Description
ImageCollection

that sensor's ee image collection.

Source code in earthlib/utils.py
87
88
89
90
91
92
93
94
95
96
def getCollection(sensor: str) -> ee.ImageCollection:
    """Returns the default image collection for a satellite sensor.

    Args:
        sensor: the name of the sensor (from earthlib.listSensors()).

    Returns:
        that sensor's ee image collection.
    """
    return ee.ImageCollection(getCollectionName(sensor))

getCollectionName(sensor)

Returns the earth engine collection name for a specific satellite sensor.

Parameters:

Name Type Description Default
sensor str

the name of the sensor (from earthlib.listSensors()).

required

Returns:

Name Type Description
collection str

a string with the earth engine collection.

Source code in earthlib/utils.py
73
74
75
76
77
78
79
80
81
82
83
84
def getCollectionName(sensor: str) -> str:
    """Returns the earth engine collection name for a specific satellite sensor.

    Args:
        sensor: the name of the sensor (from earthlib.listSensors()).

    Returns:
        collection: a string with the earth engine collection.
    """
    validateSensor(sensor)
    collection = collections[sensor]["collection"]
    return collection

getScaler(sensor)

Returns the scaling factor to convert sensor data to percent reflectance (0-1).

Parameters:

Name Type Description Default
sensor str

the name of the sensor (from earthlib.listSensors()).

required

Returns:

Name Type Description
scaler str

the scale factor to multiply.

Source code in earthlib/utils.py
 99
100
101
102
103
104
105
106
107
108
109
110
def getScaler(sensor: str) -> str:
    """Returns the scaling factor to convert sensor data to percent reflectance (0-1).

    Args:
        sensor: the name of the sensor (from earthlib.listSensors()).

    Returns:
        scaler: the scale factor to multiply.
    """
    validateSensor(sensor)
    scaler = collections[sensor]["scale"]
    return scaler

getTypeLevel(Type)

Checks whether a spectral data type is available in the endmember library.

Parameters:

Name Type Description Default
Type str

the type of spectra to select.

required

Returns:

Name Type Description
level int

the metadata "level" of the group for subsetting. returns 0 if not found.

Source code in earthlib/utils.py
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
def getTypeLevel(Type: str) -> int:
    """Checks whether a spectral data type is available in the endmember library.

    Args:
        Type: the type of spectra to select.

    Returns:
        level: the metadata "level" of the group for subsetting. returns 0 if not found.
    """
    for i in range(4):
        level = i + 1
        available_types = listTypes(level=level)
        if Type in available_types:
            return level

    return 0

listSensors()

Returns a list of the supported sensor image collections.

Returns:

Name Type Description
sensors list

a list of supported sensors using the names referenced by this package.

Source code in earthlib/utils.py
15
16
17
18
19
20
21
22
def listSensors() -> list:
    """Returns a list of the supported sensor image collections.

    Returns:
        sensors: a list of supported sensors using the names referenced by this package.
    """
    sensors = list(collections.keys())
    return sensors

listTypes(level=2)

Returns a list of the spectral classification types.

Parameters:

Name Type Description Default
level int

the level of spectral classification specificity to return. Supports integers 1-4.

2

Returns:

Name Type Description
classes list

a list of spectral data types referenced throughout this package.

Source code in earthlib/utils.py
41
42
43
44
45
46
47
48
49
50
51
52
def listTypes(level: int = 2) -> list:
    """Returns a list of the spectral classification types.

    Args:
        level: the level of spectral classification specificity to return. Supports integers 1-4.

    Returns:
        classes: a list of spectral data types referenced throughout this package.
    """
    key = f"LEVEL_{level}"
    types = list(metadata[key].unique())
    return types

selectSpectra(Type, sensor, n=20, bands=None)

Subsets the earthlib spectral endmember library.

Selects endmembers from specific class, then resamples the spectra to the wavelengths of a specific satellite sensor. This also performs random spectra selection.

Parameters:

Name Type Description Default
Type str

the type of spectra to select (from earthlib.listTypes()).

required
sensor str

the sensor type to resample wavelengths to.

required
n int

the number of random spectra to sample. n=0 returns all spectra.

20
bands list

list of bands to use. Accepts 0-based indices or a list of band names (e.g. ["B2", "B3", "B4"]).

None

Returns:

Type Description
list

a list of spectral endmembers resampled to a specific sensor's wavelengths.

Source code in earthlib/utils.py
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
def selectSpectra(Type: str, sensor: str, n: int = 20, bands: list = None) -> list:
    """Subsets the earthlib spectral endmember library.

    Selects endmembers from specific class, then resamples the spectra to the wavelengths
    of a specific satellite sensor. This also performs random spectra selection.

    Args:
        Type: the type of spectra to select (from earthlib.listTypes()).
        sensor: the sensor type to resample wavelengths to.
        n: the number of random spectra to sample. n=0 returns all spectra.
        bands: list of bands to use. Accepts 0-based indices or a list of band names (e.g. ["B2", "B3", "B4"]).

    Returns:
        a list of spectral endmembers resampled to a specific sensor's wavelengths.
    """
    validateSensor(sensor)

    # get the level of the group selected
    level = getTypeLevel(Type)
    if level == 0:
        raise EndmemberError(
            f"Invalid group parameter: {Type}. Get valid values from earthlib.listTypes()."
        )

    # read the spectral library into memory
    endmembers = spectralLibrary(endmember_path)

    # subset to specific bands, if set
    if bands is None:
        bands = range(len(getBands(sensor)))
    else:
        if type(bands[0]) is str:
            bands = getBandIndices(bands, sensor)

    # create a band resampler for this collection
    sensor_centers = np.array(collections[sensor]["band_centers"])[bands]
    sensor_fwhm = np.array(collections[sensor]["band_widths"])[bands]
    resampler = spectral.BandResampler(
        endmembers.band_centers, sensor_centers, fwhm2=sensor_fwhm
    )

    # select the endmembers from just the type passed
    key = f"LEVEL_{level}"
    indices = metadata[key] == Type
    spectra_raw = endmembers.spectra[indices, :]

    # subset them further if the n parameter is passed
    if n > 0:
        random_indices = np.random.randint(indices.sum(), size=n)
        spectra_raw = spectra_raw[random_indices, :]

    # loop through each spectrum and resample to the sensor wavelengths
    resampled = list()
    for i in range(spectra_raw.shape[0]):
        spectrum = resampler(spectra_raw[i, :])
        resampled.append(spectrum)

    return resampled

validateSensor(sensor)

Verify a string sensor ID is valid, raise an error otherwise.

Parameters:

Name Type Description Default
sensor str

the name of the sensor (from earthlib.listSensors()).

required

Raises:

Type Description
SensorError

when an invalid sensor name is passed

Source code in earthlib/utils.py
25
26
27
28
29
30
31
32
33
34
35
36
37
38
def validateSensor(sensor: str) -> None:
    """Verify a string sensor ID is valid, raise an error otherwise.

    Args:
        sensor: the name of the sensor (from earthlib.listSensors()).

    Raises:
        SensorError: when an invalid sensor name is passed
    """
    supported = listSensors()
    if sensor not in supported:
        raise SensorError(
            f"Invalid sensor: {sensor}. Supported: {', '.join(supported)}"
        )