Reading an existing dataset

Simple format (FFI 1001)

import icartt
import pathlib

# load a new dataset from an existing file
wd = pathlib.Path(__file__).parent
ict = icartt.Dataset(wd / ".." / "example_data" / "expect_ok" / "DC8-20160517.ict")

# read some metadata
ict.PIName
ict.PIAffiliation
ict.missionName
ict.dataSourceDescription
ict.dataID
ict.locationID

# list variable names
[x for x in ict.variables]

# some info on a variable
ict.variables["Alt_ft"].units
ict.variables["Alt_ft"].miss

# get data for variable 'UTC':
ict.data["UTC"]

# get all data (NumPy array):
ict.data[:]

# get the altitude in feet for those data where UTC < 86400.0:
ict.data[ict.data["UTC"] < 86400.0]["Alt_ft"]

More complex (FFI 2110)

Identical to FFI1001, only the data structure is more complex.

import icartt
import pathlib

# load a new dataset from an existing file
wd = pathlib.Path(__file__).parent
ict = icartt.Dataset(
    wd / ".." / "example_data" / "expect_warn" / "AR_DC8_20050203_R0.ict"
)

# list variable names
[x for x in ict.variables]

# independent, independent bounded, dependent, auxiliary variables?
ict.independentVariable.shortname
ict.independentBoundedVariable.shortname
", ".join([x for x in ict.auxiliaryVariables])
", ".join([x for x in ict.dependentVariables])

# some info on a variable (units, missing value of "Latitude")
ict.variables["Latitude"].units
ict.variables["Latitude"].miss

# get steps for which data is available:
tsteps = [x for x in ict.data]

# let's look at the first time step data
ict.data[tsteps[0]]

# auxiliary data at this time step:
ict.data[tsteps[0]]["AUX"][:]

# dependent data at this time step:
tstepdata = ict.data[tsteps[0]]["DEP"][:]

# get the ozone mixing ratio for those data where Altitude < 10000.0:
tstepdata[tstepdata["Altitude[]"] < 10000.0]["O3_MR[]"]

Creating a new dataset

Simple format (FFI 1001)

import datetime

import icartt

# ------------------------------------------------------
# Phase 1: define file format, properties and variables
# ------------------------------------------------------

ict = icartt.Dataset(format=icartt.Formats.FFI1001)

ict.PIName = "Knote, Christoph"
ict.PIAffiliation = "Faculty of Medicine, University Augsburg, Germany"
ict.dataSourceDescription = "Example data"
ict.missionName = "MBEES"
# to simplify dates and avoid time zone issues, these dates are simple 3 item lists [YYYY, MM, DD]
ict.dateOfCollection = datetime.datetime.utcnow().timetuple()[:3]
ict.dateOfRevision = datetime.datetime.utcnow().timetuple()[:3]

ict.dataIntervalCode = [0]

ict.independentVariable = icartt.Variable(
    "Time_Start",
    "seconds_from_0_hours_on_valid_date",
    "Time_Start",
    "Time_Start",
    vartype=icartt.VariableType.IndependentVariable,
    scale=1.0,
    miss=-9999999,
)

ict.dependentVariables["Time_Stop"] = icartt.Variable(
    "Time_Stop",
    "seconds_from_0_hours_on_valid_date",
    "Time_Stop",
    "Time_Stop",
    scale=1.0,
    miss=-9999999,
)

ict.dependentVariables["Payload"] = icartt.Variable(
    "Payload", "some_units", "Payload", "Payload", scale=1.0, miss=-9999999
)

# Normal and Special Comments

# note: all comments can be multi-line per standard.
# To ensure portability the decision was made to represent them as lists,
# with each list item representing a line.

# E.g., Special Comments are simple lists, which we can append to:
ict.specialComments.append("Some comments on this dataset:")
ict.specialComments.append("They are just examples!")
ict.specialComments.append("Adapt as needed.")

# Normal Comments are separated into freeform and (required) keyword comments.

# Freeform comments are, just like special comments, a list with one line per entry
ict.normalComments.freeform.append("free comment line 1")
ict.normalComments.freeform.append("free comment line 2")

# Keywords are mandatory, all need to exist, and default to N/A
# they can be set as follows:
ict.normalComments.keywords["PI_CONTACT_INFO"].append(
    "Christoph Knote, MBEES, Faculty of Medicine, University Augsburg, Augsburg, Germany"
)
ict.normalComments.keywords["PI_CONTACT_INFO"].append(
    "christoph.knote@med.uni-augsburg.de"
)
ict.normalComments.keywords["PLATFORM"].append("ICARTT")
ict.normalComments.keywords["PROJECT_INFO"].append(
    "A format reader/writer for ICARTT files"
)
# ... and so forth

# note for revisions: we assume you take care of the required documentation of past versions
# and setting the correct date for the current revision (ict.dateOfRevision, see above)
ict.normalComments.keywords["REVISION"].append("R1")
ict.normalComments.keywords["REVISION"].append("R1: current status")
ict.normalComments.keywords["REVISION"].append("R0: early beta")

ict.endDefineMode()

# ------------------------------------------------------
# Phase 2: after ending define mode, add data
# ------------------------------------------------------

# all data are stored as NumPy arrays, and need to be provided as such.

import numpy as np

#                 ivar  dvar1 dvar2
data = np.array([(15.4, 15.0, 5.24524952903484e5)])
ict.data.add(data)

# Note 1: you are responsible to ensure that the order of elements in a data line
# corresponds to variable listing below:
print([x for x in ict.variables])

# Note 2: evenfor single lines, you still need to make it an array!

# Note 3: multiple data lines can be added in bulk!
#                 ivar  dvar1 dvar2       ivar  dvar1 dvar2      ...
data = np.array([(13.4, 14.0, 2.348925e5), (14.1, 14.9, 2.3425634e5)])

ict.data.add(data)

# Now, look at it in ICARTT form:
ict.write()

# And you could simply write to file:
# with open('output.ict', 'w') as f:
#    ict.write(f=f)

More complex (FFI 2110)

Again, like for FFI 1001, but using a more complex data structure.

import datetime

import numpy as np

import icartt

# ------------------------------------------------------
# Phase 1: define file format, properties and variables
# ------------------------------------------------------

ict = icartt.Dataset(format=icartt.Formats.FFI2110)

ict.PIName = "Knote, Christoph"
ict.PIAffiliation = "Faculty of Medicine, University Augsburg, Germany"
ict.dataSourceDescription = "Example data"
ict.missionName = "MBEES"
ict.dateOfCollection = datetime.datetime.utcnow().timetuple()[:3]
ict.dateOfRevision = datetime.datetime.utcnow().timetuple()[:3]

ict.dataIntervalCode = [0]

ict.independentVariable = icartt.Variable(
    "Time_Start",
    "seconds_from_0_hours_on_valid_date",
    "Time_Start",
    "Time_Start",
    vartype=icartt.VariableType.IndependentVariable,
    scale=1.0,
    miss=-9999999,
)

ict.independentBoundedVariable = icartt.Variable(
    "Altitude",
    "altitude_above_ground_in_meters",
    "Altitude",
    "Altitude",
    vartype=icartt.VariableType.IndependentBoundedVariable,
    scale=1.0,
    miss=-9999999,
)

# ICARTT convention: first aux variable contains number of dependent elements
ict.auxiliaryVariables["nAltitudes"] = icartt.Variable(
    "nAltitudes",
    "number_of_dependent_variable_items",
    "variable",
    "nAltitudes",
    scale=1.0,
    miss=-9999999,
)

ict.auxiliaryVariables["Time_Stop"] = icartt.Variable(
    "Time_Stop",
    "seconds_from_0_hours_on_valid_date",
    "Time_Stop",
    "Time_Stop",
    scale=1.0,
    miss=-9999999,
)

ict.auxiliaryVariables["Longitude"] = icartt.Variable(
    "Longitude",
    "longitude_in_degrees",
    "Longitude",
    "Longitude",
    scale=1.0,
    miss=-9999999,
)

ict.auxiliaryVariables["Latitude"] = icartt.Variable(
    "Latitude", "latitude_in_degrees", "Latitude", "Latitude", scale=1.0, miss=-9999999
)

ict.dependentVariables["Payload1"] = icartt.Variable(
    "Payload1", "some_units", "Payload1", "Payload1", scale=1.0, miss=-9999999
)

ict.dependentVariables["Payload2"] = icartt.Variable(
    "Payload2", "some_units", "Payload2", "Payload2", scale=1.0, miss=-9999999
)

ict.specialComments.append("Some comments on this dataset:")
ict.specialComments.append("They are just examples!")
ict.specialComments.append("Adapt as needed.")

ict.endDefineMode()

# ------------------------------------------------------
# Phase 2: after ending define mode, add data
# ------------------------------------------------------

import numpy as np

# same as for 1001, but data needs to be added in chunks for each ivar value

# note, the second variable ('4') is the number of dependent lines to follow
#                   ivar, ndepvar, auxvar1, auxvar2, auxvar3
auxData = np.array([(12.3, 4, 12.5, 48.21, 10.3)])
#                   ibvar,  dvar1,  dvar2  ... (repeat ndepvar times)
depData = np.array(
    [(0, 123, 8.4e4), (100, 122, 9.1e4), (250, 115, 9.3e4), (500, 106, 9.8e4)]
)

ict.data.add(auxData, depData)

# ... and so forth for the next chunk:

auxData = np.array([(12.4, 2, 12.8, 48.41, 12.1)])
#                   ibvar,  dvar1,  dvar2
depData = np.array([(0, 153, 7.3e4), (270, 172, 8.9e4)])

ict.data.add(auxData, depData)

# Now, look at it in ICARTT form:
ict.write()

# And you could simply write to file:
# with open('output.ict', 'w') as f:
#    ict.write(f=f)