diff --git a/plio/examples/SpectralProfiler/cl5_398736801edr_f0030004ccam01014m1.dat b/plio/examples/SpectralProfiler/cl5_398736801edr_f0030004ccam01014m1.dat new file mode 100644 index 0000000000000000000000000000000000000000..b9dcce79d7d708162dfe49db82fcb094208ef3b5 Binary files /dev/null and b/plio/examples/SpectralProfiler/cl5_398736801edr_f0030004ccam01014m1.dat differ diff --git a/plio/examples/__init__.py b/plio/examples/__init__.py index 405e9c68f4fc296fa3748d681b97f9bbd1ce6eea..68f159dfefaa1a775abba91ce5c61128ca9b448b 100644 --- a/plio/examples/__init__.py +++ b/plio/examples/__init__.py @@ -3,7 +3,7 @@ import plio __all__ = ['available', 'get_path'] -#Used largely unmodififed from: +# Used largely unmodififed from: # https://github.com/pysal/pysal/blob/master/pysal/examples/__init__.py base = os.path.split(plio.__file__)[0] diff --git a/plio/io/io_edr.py b/plio/io/io_edr.py new file mode 100644 index 0000000000000000000000000000000000000000..caa9d6d396b5917b04c22e22632f93c3a775112d --- /dev/null +++ b/plio/io/io_edr.py @@ -0,0 +1,80 @@ +import os + +import numpy as np +import pandas as pd + + +def EDR(input_file): + f = open(input_file, 'rb') # read as bytes so python won't complain about the binary part of the file + + # read lines of the header until reaching the end of the libs table (collecting other metadata along the way) + end_of_libs_table = False + while end_of_libs_table is False: + line = str(f.readline(), 'utf-8').replace('\r', '').replace('\n', + '') # convert the current line to a string and get rid of newline characters + line = line.split('=') # split the line on equals sign if present + # look for the name of the value we want, if the current line has it, then set the value + if 'RECORD_BYTES' in line[0]: + rbytes = int(line[1]) + if 'LABEL_RECORDS' in line[0]: + lrecs = int(line[1]) + if 'SPACECRAFT_CLOCK_START_COUNT' in line[0]: + sclock = int(line[1].replace('"', '').split('.')[0]) + if 'SEQUENCE_ID' in line[0]: + seqID = line[1].replace('"', '') + if 'INSTRUMENT_FOCUS_DISTANCE' in line[0]: + focus_dist = int(line[1]) + + if 'INSTRUMENT_TEMPERATURE' in line[0]: + instrument_temps = line[1] \ + + str(f.readline(), 'utf-8').replace('\r', '').replace('\n', '') \ + + str(f.readline(), 'utf-8').replace('\r', '').replace('\n', '') \ + + str(f.readline(), 'utf-8').replace('\r', '').replace('\n', '') + instrument_temps = [float(i) for i in + instrument_temps.replace('<degC>', '').replace('(', '').replace(')', '').replace(' ', + '').split( + ',')] + instrument_temps_name = str(f.readline(), 'utf-8').replace('\r', '').replace('\n', '') + instrument_temps_name = instrument_temps_name.split('=')[1] \ + + str(f.readline(), 'utf-8').replace('\r', '').replace('\n', '') \ + + str(f.readline(), 'utf-8').replace('\r', '').replace('\n', '') \ + + str(f.readline(), 'utf-8').replace('\r', '').replace('\n', '') \ + + str(f.readline(), 'utf-8').replace('\r', '').replace('\n', '') + instrument_temps_name = instrument_temps_name.replace(' ', '').replace('(', '').replace(')', '').replace( + '"', '').split(',') + f.readline() + pass + try: + if 'CCAM_LIBS_DATA_CONTAINER' in line[1]: + nshots = int(str(f.readline(), 'utf-8').replace('\r', '').replace('\n', '').split('=')[1]) + start_byte = int(str(f.readline(), 'utf-8').replace('\r', '').replace('\n', '').split('=')[1]) + if 'END_OBJECT' in line[0] and 'CCAM_LIBS_TABLE' in line[1]: + end_of_libs_table = True + except: + pass + + f.close() + header_skip = lrecs * rbytes # calculate the number of header bytes to skip to get to the real data + + with open(input_file, "rb") as f: + f.seek(header_skip + start_byte - 1, 0) + spectra = [] + while spectra.__len__() < nshots: + spectrum = [] + while spectrum.__len__() < 6444: + spectrum.append(int.from_bytes(f.read(2), byteorder='big', signed=False)) + spectra.append(spectrum) + spectra = np.array(spectra, dtype='int') + cols = np.array(list(range(spectra.shape[1]))) + 1 + cols = [('channel', i) for i in cols] + inds = np.array(list(range(spectra.shape[0]))) + 1 + sp = pd.DataFrame(spectra, columns=pd.MultiIndex.from_tuples(cols), index=inds) + sp[('meta', 'EDR_file')] = os.path.basename(input_file) + sp[('meta', 'Spacecraft_Clock')] = sclock + sp[('meta', 'Shot')] = sp.index + sp[('meta', 'SeqID')] = seqID + sp[('meta', 'Focus_Distance')] = focus_dist + for ind, name in enumerate(instrument_temps_name): + sp[('meta', name + '_temp')] = instrument_temps[ind] + sp.to_csv('test.csv') + return sp diff --git a/plio/io/io_moon_minerology_mapper.py b/plio/io/io_moon_minerology_mapper.py new file mode 100644 index 0000000000000000000000000000000000000000..a479ca5e8f656f0495c907a92daf6597a924214c --- /dev/null +++ b/plio/io/io_moon_minerology_mapper.py @@ -0,0 +1,25 @@ +import numpy as np +from osgeo import gdal + + +def openm3(input_data): + if input_data.split('.')[-1] == 'hdr': + # GDAL wants the img, but many users aim at the .hdr + input_data = input_data.split('.')[0] + '.img' + ds = gdal.Open(input_data) + ref_array = ds.GetRasterBand(1).ReadAsArray() + metadata = ds.GetMetadata() + wv_array = metadatatoband(metadata) + return wv_array, ref_array, ds + + +def metadatatoband(metadata): + wv2band = [] + for k, v in metadata.iteritems(): + try: + wv2band.append(float(value)) + except: + v = v.split(" ")[-1].split("(")[1].split(")")[0] + wv2band.append(float(v)) + wv2band.sort(key=int) + return np.asarray(wv2band) diff --git a/plio/io/io_multibandimager.py b/plio/io/io_multibandimager.py new file mode 100644 index 0000000000000000000000000000000000000000..7e5ba2627a240fdc980c9c25a184d93d22168e80 --- /dev/null +++ b/plio/io/io_multibandimager.py @@ -0,0 +1,28 @@ +import numpy as np +from osgeo import gdal + + +def openmi(input_data): + ds = gdal.Open(input_data) + band_pointers = [] + nbands = ds.RasterCount + + for b in xrange(1, nbands + 1): + band_pointers.append(ds.GetRasterBand(b)) + + ref_array = ds.GetRasterBand(1).ReadAsArray() + wv_array = None + return wv_array, ref_array[::3, ::3], ds + + +def getspectra(x, y, ds): + nbands = ds.RasterCount + reflectance = np.empty(nbands) + for b in range(1, nbands + 1): + reflectance[b - 1] = ds.GetRasterBand(b).ReadAsArray(y, x, 1, 1) + + mergedref = np.empty(nbands - 1) + mergedref[:4] = reflectance[:4] + mergedref[4] = (reflectance[4] + reflectance[5]) / 2 + mergedref[5:] = reflectance[6:] + return mergedref diff --git a/plio/io/io_yaml.py b/plio/io/io_yaml.py index 38c787ae91d697aa1efe20ead1387edc56aeaa41..59d1a70d9d24fc43f8a68b658826b27a81c069fb 100644 --- a/plio/io/io_yaml.py +++ b/plio/io/io_yaml.py @@ -1,7 +1,4 @@ -try: - import yaml -except: - print('YAML package not installed, disabling yaml_io module') +import yaml def read_yaml(inputfile): @@ -21,6 +18,6 @@ def read_yaml(inputfile): try: with open(inputfile, 'r') as f: ydict = yaml.load(f) - except: # pragma: no cover + except: # pragma: no cover raise IOError('Unable to load YAML file.') return ydict diff --git a/plio/io/tests/test_io_edr.py b/plio/io/tests/test_io_edr.py new file mode 100644 index 0000000000000000000000000000000000000000..a321f6eb17c4dc3eeac3914fad5e4b02e3a4b016 --- /dev/null +++ b/plio/io/tests/test_io_edr.py @@ -0,0 +1,19 @@ +import unittest + +sys.path.insert(0, os.path.abspath('..')) + +from plio.examples import get_path +from plio.io import io_edr + + +class Test_Tes_IO(unittest.TestCase): + + # Need different test data or need to modify the current code + def setUp(self): + self.examplefile = get_path('cl5_398736801edr_f0030004ccam01014m1.dat') + + def test_open(self): + ds = io_edr.EDR(self.examplefile) + +if __name__ == '__main__': + unittest.main() diff --git a/plio/io/tests/test_structured_io.py b/plio/io/tests/test_structured_io.py index 13a7c4195abfcd2f67cd2816d4b0a641c354befd..84e67b8b59225845c96f98c20766a4c47416cce8 100644 --- a/plio/io/tests/test_structured_io.py +++ b/plio/io/tests/test_structured_io.py @@ -1,7 +1,7 @@ import unittest -from .. import io_json -from .. import io_yaml +from plio.io import io_json +from plio.io import io_yaml try: import yaml diff --git a/plio/utils/utils.py b/plio/utils/utils.py index 761f70d28416f338b896d10f1daff6c4d7eb3ad2..e499cd8418e67d0efb8262bcfaf9f710cc32e735 100644 --- a/plio/utils/utils.py +++ b/plio/utils/utils.py @@ -5,6 +5,7 @@ import os import fnmatch import shutil import tempfile +import pandas as pd def create_dir(basedir=''): @@ -164,3 +165,31 @@ def xstr(s): if s is None: return '' return str(s) + +def lookup(df,lookupfile=None,lookupdf=None,sep=',',skiprows=1,left_on='sclock',right_on='Spacecraft Clock'): +#TODO: automatically determine the number of rows to skip to handle ccam internal master list and PDS "official" master list formats + if lookupfile is not None: + # this loop concatenates together multiple lookup files if provided + # (mostly to handle the three different master lists for chemcam) + for x in lookupfile: + try: + tmp = pd.read_csv(x, sep=sep, skiprows=skiprows, error_bad_lines=False) + lookupdf = pd.concat([lookupdf, tmp]) + except: + lookupdf = pd.read_csv(x, sep=sep, skiprows=skiprows, error_bad_lines=False) + metadata = df['meta'] + + metadata = metadata.merge(lookupdf, left_on=left_on, right_on=right_on, how='left') + + # remove metadata columns that already exist in the data frame to avoid non-unique columns + meta_cols = set(metadata.columns.values) + meta_cols_keep = list(meta_cols - set(df['meta'].columns.values)) + metadata = metadata[meta_cols_keep] + + # make metadata into a multiindex + metadata.columns = [['meta'] * len(metadata.columns), metadata.columns.values] + # give it the same indices as the df + metadata.index = df.index + # combine the df and the new metadata + df = pd.concat([metadata, df], axis=1) + return df