# metadata_reader.py
# By Nathan C. Hearn
# November 21, 2007
#
# Reader for metadata files from omega_slicer and layer_distrib.
from sys import stderr
class KeywordGroup :
def __init__(self, group_name=None, group_type=None) :
self.__name = group_name
self.__type = group_type
self.__sort_key = int(-1) # Default is higher precedence than zero
self.__values = dict()
def set_group_name(self, group_name) :
self.__name = group_name
def get_group_name(self) :
return self.__name
def get_group_type(self) :
return self.__type
def set_sort_key(self, key) :
self.__sort_key = key
def get_sort_key(self) :
return self.__sort_key
def __cmp__(self, other) :
return cmp(self.__sort_key, other.get_sort_key())
def get_string(self, line_prefix="") :
string = line_prefix + "Name [ " + str(self.__name) + " ]\n"
if (self.__type is not None) :
string += line_prefix + " Type [ " + str(self.__type) + " ]\n"
string += line_prefix + " Sort key [ " + str(self.__sort_key) + " ]\n"
for key in self.__values :
string += line_prefix + " Key [ " + str(key) + " ] Value [ " \
+ str(self.__values[key]) + " ]\n"
return string
def __str__(self) :
return self.get_string()
def add_keyword_value(self, keyword, value=None) :
if (self.__values.has_key(keyword)) :
stderr.write("\nDuplicate keyword [ " + str(keyword) + " ]\n\n")
raise RuntimeError("Duplicate keyword")
self.__values[keyword] = value
def keyword_present(self, keyword) :
return self.__values.has_key(keyword)
def get_value(self, keyword) :
return self.__values[keyword]
def __getitem__(self, keyword) :
return self.get_value(keyword)
def get_keyword_list(self) :
return self.__values.keys()
class DataGroup(KeywordGroup) :
def __init__(self, group_name, group_type=None) :
KeywordGroup.__init__(self, group_name, group_type)
self.__keyword_group_list = list()
def get_string(self, line_prefix="") :
string = KeywordGroup.get_string(self) + "\n"
for group in self.__keyword_group_list :
string += group.get_string(line_prefix + " ") + "\n"
return string
def __str__(self) :
return self.get_string()
def add_keyword_group(self, keyword_group) :
sort_key = keyword_group.get_sort_key()
# Find the sorted location for this group
num_groups = len(self.__keyword_group_list)
index = (0)
found_it = False
while ((not found_it) and (index < num_groups)) :
if (self.__keyword_group_list[index].get_sort_key() > sort_key) :
found_it = True
else :
index += 1
if (not found_it) :
self.__keyword_group_list.append(keyword_group)
else :
self.__keyword_group_list.insert(index, keyword_group)
def get_keyword_group_list(self, group_type=None) :
keyword_group_list = list()
for group in self.__keyword_group_list :
include_group = False
if (group_type is None) :
include_group = True
elif (group.get_group_type() == group_type) :
include_group = True
if (include_group) :
keyword_group_list.append(group)
return keyword_group_list
def split_vector(vector_string) :
## Split on both "," and " "
split_words = vector_string.split()
vector_elems = list()
for word in split_words :
comma_words = word.split(",")
for elem in comma_words :
vector_elems.append(elem)
return vector_elems
def remove_comments(line) :
return line.split("#")[0].strip()
def read_next_line(input_file) :
ret_val = None # Return None if at end of file
finished = False
while (not finished) :
current_line = input_file.readline()
if (current_line == "") :
finished = True # End of file
else :
work_line = remove_comments(current_line)
if (work_line != "") :
ret_val = work_line
finished = True
return ret_val
def parse_file_line_slicer(line) :
work_line = line.strip()
keyword_values = dict()
split_pairs = work_line.split("]")
num_split_pairs= len(split_pairs)
# Parse the elements
for pair in split_pairs :
pair_elems = pair.split("[")
num_elems = len(pair_elems)
if ((num_elems > 2) or (num_elems < 1)) :
stderr.write("\nError parsing metadata [ " + work_line + " ]\n\n")
raise RuntimeError("Error parsing metadata")
keyword = None
value = None
keyword = pair_elems[0].strip()
temp_value = None
if (num_elems > 1) :
temp_value = pair_elems[1].strip()
include_pair = True
if (keyword == "") :
if ((num_elems < 2) or (temp_value == "")) :
include_pair = False
else :
stderr.write("\nError: Missing keyword [ " + work_line
+ " ]\n\n")
raise RuntimeError("Missing keyword")
if (include_pair) :
if (num_elems > 1) :
if (temp_value != "") :
value = split_vector(temp_value)
if (len(value) == 1) :
value = value[0]
elif (len(value) < 1) :
value = None
keyword_values[keyword] = value
return keyword_values
def parse_slicer_metadata(filename) :
datafile_group = None
dataset_list = list()
current_line = None
f = file(filename, "r")
# Read the file metadata
current_line = read_next_line(f)
if (current_line is None) :
raise RuntimeError("EOF reached early")
current_metadata = parse_file_line_slicer(current_line)
if (len(current_metadata) != 1) :
raise RuntimeError("Improper flash filename entry")
flash_file_name = current_metadata["FlashFile"]
datafile_group = KeywordGroup(flash_file_name)
finished_header = False
while (not finished_header) :
current_line = read_next_line(f)
if (current_line is None) :
finished_header = True # End of file
current_metadata = None
else :
current_metadata = parse_file_line(current_line)
if (current_metadata.has_key("Dataset")) :
finished_header = True ## Keep current_metadata for next part
else :
if (current_metadata.has_key("Time")) :
time = float(current_metadata["Time"])
datafile_group.add_keyword_value("Time", time)
elif (current_metadata.has_key("Dimensions")) :
dims = int(current_metadata["Dimensions"])
datafile_group.add_keyword_value("Dims", dims)
elif (current_metadata.has_key("EnvelopeMinPos")) :
pos = float(current_metadata["EnvelopeMinPos"])
datafile_group.add_keyword_value("EnvelopeMinPos", pos)
elif (current_metadata.has_key("EnvelopeMaxPos")) :
pos = float(current_metadata["EnvelopeMaxPos"])
datafile_group.add_keyword_value("EnvelopeMaxPos", pos)
elif (current_metadata.has_key("GridMinCoords")) :
min_coords_str = current_metadata["GridMinCoords"]
min_coords = list()
for elem in min_coords_str :
min_coords.append(float(elem))
datafile_group.add_keyword_value("GridMinCoords",
min_coords)
elif (current_metadata.has_key("GridMaxCoords")) :
max_coords_str = current_metadata["GridMaxCoords"]
max_coords = list()
for elem in max_coords_str :
max_coords.append(float(elem))
datafile_group.add_keyword_value("GridMaxCoords",
max_coords)
elif (current_metadata.has_key("GridCenter")) :
center_coords_str = current_metadata["GridCenter"]
center_coords = list()
for elem in center_coords_str :
center_coords.append(float(elem))
datafile_group.add_keyword_value("GridCenter",
center_coords)
elif (current_metadata.has_key("GridWidth")) :
axis_width_str = current_metadata["GridWidth"]
axis_width = list()
for elem in axis_width_str :
axis_width.append(float(elem))
datafile_group.add_keyword_value("GridWidth", axis_width)
elif (current_metadata.has_key("GridPixels")) :
grid_pixels_str = current_metadata["GridPixels"]
grid_pixels = list()
for elem in grid_pixels_str :
grid_pixels.append(int(elem))
datafile_group.add_keyword_value("GridPixels",
grid_pixels)
elif (current_metadata.has_key("XSectGridMinCoords")) :
min_coords_str = current_metadata["XSectGridMinCoords"]
min_coords = list()
for elem in min_coords_str :
min_coords.append(float(elem))
datafile_group.add_keyword_value("XSectGridMinCoords",
min_coords)
elif (current_metadata.has_key("XSectGridMaxCoords")) :
max_coords_str = current_metadata["XSectGridMaxCoords"]
max_coords = list()
for elem in max_coords_str :
max_coords.append(float(elem))
datafile_group.add_keyword_value("XSectGridMaxCoords",
max_coords)
elif (current_metadata.has_key("XSectGridCenter")) :
center_coords_str = current_metadata["XSectGridCenter"]
center_coords = list()
for elem in center_coords_str :
center_coords.append(float(elem))
datafile_group.add_keyword_value("XSectGridCenter",
center_coords)
elif (current_metadata.has_key("XSectGridWidth")) :
axis_width_str = current_metadata["XSectGridWidth"]
axis_width = list()
for elem in axis_width_str :
axis_width.append(float(elem))
datafile_group.add_keyword_value("XSectGridWidth",
axis_width)
elif (current_metadata.has_key("XSectGridPixels")) :
grid_pixels_str = current_metadata["XSectGridPixels"]
grid_pixels = list()
for elem in grid_pixels_str :
grid_pixels.append(int(elem))
datafile_group.add_keyword_value("XSectGridPixels",
grid_pixels)
elif (current_metadata.has_key("XSectLowerPlanePos")) :
xsect_bottom_pos \
= float(current_metadata["XSectLowerPlanePos"])
datafile_group.add_keyword_value("XSectLowerPlanePos",
xsect_bottom_pos)
elif (current_metadata.has_key("XSectMiddlePlanePos")) :
xsect_flame_front_pos \
= float(current_metadata["XSectMiddlePlanePos"])
datafile_group.add_keyword_value("XSectMiddlePlanePos",
xsect_flame_front_pos)
elif (current_metadata.has_key("XSectUpperPlanePos")) :
xsect_top_pos \
= float(current_metadata["XSectUpperPlanePos"])
datafile_group.add_keyword_value("XSectUpperPlanePos",
xsect_top_pos)
# Process datasets
finished_datasets = False
while (not finished_datasets) :
if (current_metadata is None) :
finished_datasets = True
else :
if (not current_metadata.has_key("Dataset")) :
raise RuntimeError("Unrecognized file line")
dataset_name = current_metadata["Dataset"]
dataset_group = DataGroup(dataset_name, "Dataset")
min_value = float(current_metadata["MinValue"])
max_value = float(current_metadata["MaxValue"])
dataset_group.add_keyword_value("MinValue", min_value)
dataset_group.add_keyword_value("MaxValue", max_value)
# Read the Image, data, and cross section info
dataset_complete = False
while (not dataset_complete) :
current_line = read_next_line(f)
if (current_line is None) :
dataset_complete = True
current_metadata = None
else :
current_metadata = parse_file_line_slicer(current_line)
if (current_metadata.has_key("Dataset")) :
dataset_complete = True
else :
if (current_metadata.has_key("Image")) :
image_group \
= KeywordGroup(current_metadata["Image"],
"Image")
filename = current_metadata["File"]
image_group.add_keyword_value("File", filename)
min_coords = list()
max_coords = list()
for elem in current_metadata["MinCoords"] :
min_coords.append(float(elem))
for elem in current_metadata["MaxCoords"] :
max_coords.append(float(elem))
image_group.add_keyword_value("MinCoords",
min_coords)
image_group.add_keyword_value("MaxCoords",
max_coords)
min_val = float(current_metadata["MinValue"])
max_val = float(current_metadata["MaxValue"])
image_group.add_keyword_value("MinValue", min_val)
image_group.add_keyword_value("MaxValue", max_val)
dataset_group.add_keyword_group(image_group)
elif (current_metadata.has_key("Data")) :
image_group \
= KeywordGroup(current_metadata["Data"],
"Data")
filename = current_metadata["File"]
image_group.add_keyword_value("File", filename)
min_coords = list()
max_coords = list()
for elem in current_metadata["MinCoords"] :
min_coords.append(float(elem))
for elem in current_metadata["MaxCoords"] :
max_coords.append(float(elem))
image_group.add_keyword_value("MinCoords",
min_coords)
image_group.add_keyword_value("MaxCoords",
max_coords)
min_val = float(current_metadata["MinValue"])
max_val = float(current_metadata["MaxValue"])
image_group.add_keyword_value("MinValue", min_val)
image_group.add_keyword_value("MaxValue", max_val)
dataset_group.add_keyword_group(image_group)
elif (current_metadata.has_key("XSect")) :
xsect_type = current_metadata["XSect"]
group_type = "XSect_" + xsect_type
image_group \
= KeywordGroup(current_metadata["File"],
group_type)
filename = current_metadata["File"]
image_group.add_keyword_value("File", filename)
if (current_metadata.has_key("Index")) :
xsect_index = int(current_metadata["Index"])
image_group.set_sort_key(xsect_index)
xsect_type = str(current_metadata["Type"])
image_group.add_keyword_value("Type", xsect_type)
x_pos = float(current_metadata["Pos"])
image_group.add_keyword_value("Pos", x_pos)
min_coords = list()
max_coords = list()
for elem in current_metadata["MinCoords"] :
min_coords.append(float(elem))
for elem in current_metadata["MaxCoords"] :
max_coords.append(float(elem))
image_group.add_keyword_value("MinCoords",
min_coords)
image_group.add_keyword_value("MaxCoords",
max_coords)
min_val = float(current_metadata["MinValue"])
max_val = float(current_metadata["MaxValue"])
image_group.add_keyword_value("MinValue", min_val)
image_group.add_keyword_value("MaxValue", max_val)
dataset_group.add_keyword_group(image_group)
dataset_list.append(dataset_group)
return datafile_group, dataset_list
def parse_file_line_distrib(line) :
work_line = line.strip()
keyword = None
value_string = None
split_line = work_line.split(" ", 1)
num_items = len(split_line)
if (num_items > 0) :
keyword = split_line[0]
if (num_items > 1) :
value_string = split_line[1]
return keyword, value_string
def parse_distrib_metadata(filename) :
from sys import stderr
datafile_group = None
dataset_list = list()
current_line = None
f = file(filename, "r")
# Read the file metadata
datafile_group = KeywordGroup()
slice_list = list()
finished = False
while (not finished) :
current_line = read_next_line(f)
if (current_line is None) :
finished = True # End of file
else :
keyword, value_string = parse_file_line_distrib(current_line)
if (keyword == "DataFile") :
datafile = value_string
datafile_group.set_group_name(datafile)
elif (keyword == "SimTime") :
sim_time = float(value_string)
datafile_group.add_keyword_value("SimTime", sim_time)
elif (keyword == "Dimensions") :
dims = int(value_string)
datafile_group.add_keyword_value("Dims", dims)
elif (keyword == "EnvelopeDataset") :
dataset = value_string
datafile_group.add_keyword_value("EnvelopeDataset", dataset)
elif (keyword == "MaxSampleRadius") :
sample_rad = float(value_string)
datafile_group.add_keyword_value("MaxSampleRadius", sample_rad)
elif (keyword == "DistribBinWidth") :
distrib_bin_width = float(value_string)
datafile_group.add_keyword_value("DistribBinWidth",
distrib_bin_width)
elif (keyword == "MaxSlices") :
max_slices = int(value_string)
datafile_group.add_keyword_value("MaxSlices", max_slices)
elif (keyword == "EnvelopeMinPos") :
pos = float(value_string)
datafile_group.add_keyword_value("EnvelopeMinPos", pos)
elif (keyword == "EnvelopeMaxPos") :
pos = float(value_string)
datafile_group.add_keyword_value("EnvelopeMaxPos", pos)
elif (keyword == "EnvelopeWidth") :
width = float(value_string)
datafile_group.add_keyword_value("EnvelopeWidth", width)
elif (keyword == "MinArrayPos") :
pos = float(value_string)
datafile_group.add_keyword_value("MinArrayPos", pos)
elif (keyword == "MaxArrayPos") :
pos = float(value_string)
datafile_group.add_keyword_value("MaxArrayPos", pos)
elif (keyword == "ArrayTotalMass") :
mass = float(value_string)
datafile_group.add_keyword_value("ArrayTotalMass", mass)
elif (keyword == "ArrayPolyMass") :
mass = float(value_string)
datafile_group.add_keyword_value("ArrayPolyMass", mass)
elif (keyword == "ArrayCHBrMass") :
mass = float(value_string)
datafile_group.add_keyword_value("ArrayCHBrMass", mass)
elif (keyword == "ArrayFoamMass") :
mass = float(value_string)
datafile_group.add_keyword_value("ArrayFoamMass", mass)
elif (keyword == "LayerDistribFile") :
distrib_file = value_string
datafile_group.add_keyword_value("LayerDistribFile",
distrib_file)
elif (keyword == "FoundLayerMin") :
state = False
if (value_string == "true") :
state = True
datafile_group.add_keyword_value("FoundLayerMin", state)
elif (keyword == "FoundLayerMax") :
state = False
if (value_string == "true") :
state = True
datafile_group.add_keyword_value("FoundLayerMax", state)
elif (keyword == "LayerPeakValueFract") :
fract = float(value_string)
datafile_group.add_keyword_value("LayerPeakValueFract", fract)
elif (keyword == "LayerMinPos") :
pos = float(value_string)
datafile_group.add_keyword_value("LayerMinPos", pos)
elif (keyword == "LayerMaxPos") :
pos = float(value_string)
datafile_group.add_keyword_value("LayerMaxPos", pos)
elif (keyword == "LayerWidth") :
width = float(value_string)
datafile_group.add_keyword_value("LayerWidth", pos)
elif (keyword == "MinEnvelopePos") :
pos = float(value_string)
datafile_group.add_keyword_value("MinEnvelopePos", pos)
elif (keyword == "MaxEnvelopePos") :
pos = float(value_string)
datafile_group.add_keyword_value("MaxEnvelopePos", pos)
elif (keyword == "FoundShockFront") :
state = False
if (value_string == "true") :
state = True
datafile_group.add_keyword_value("FoundShockFront", state)
elif (keyword == "SliceSpacing") :
spacing = float(value_string)
datafile_group.add_keyword_value("SliceSpacing", spacing)
elif (keyword == "SliceWidth") :
width = float(value_string)
datafile_group.add_keyword_value("SliceWidth", width)
elif (keyword == "SliceBinWidth") :
width = float(value_string)
datafile_group.add_keyword_value("SliceBinWidth", width)
elif (keyword == "Slice1D") :
words = value_string.split()
num_words = len(words)
if (num_words != 3) :
stderr.write("\nError: Incompatible slice value string [ "
+ value_string + " ]")
raise RuntimeError("Incompatible slice value string")
slice_id = int(words[0])
slice_pos = float(words[1])
slice_output_file = words[2]
slice_group = KeywordGroup(slice_id, keyword)
slice_group.add_keyword_value("SlicePos", slice_pos)
slice_group.add_keyword_value("OutputFile", slice_output_file)
slice_list.append(slice_group)
return datafile_group, slice_list