• Facebook
  • Twitter
  • Reddit
  • StumbleUpon
  • Digg
  • email

# File column labels
 
label_bin_index = "bin_index"
label_bin_center = "bin_center"
label_bin_center_align = "bin_center_align"
label_map_bin_center = "map_bin_center"
label_map_bin_center_align = "map_bin_center_align"
label_num_entries = "num_entries"
label_bin_weight = "bin_weight"
label_bin_mean = "bin_mean"
label_bin_stddev = "bin_stddev"
label_bin_min = "bin_min"
label_bin_max = "bin_max"
 
 
class Timestep :
 
    def __init__(self) :
 
        self.__time = 0.0
 
        self.__num_bins = 0
 
        self.__bin_center = list()
        self.__bin_center_align = list()
        self.__map_bin_center = list()
        self.__map_bin_center_align = list()
        self.__num_entries = list()
        self.__bin_weight = list()
        self.__bin_mean = list()
        self.__bin_stddev = list()
        self.__bin_min = list()
        self.__bin_max = list()
 
    def load_data(self, time, bin_center, bin_center_align, map_bin_center,
                  map_bin_center_align, num_entries, bin_weight, bin_mean,
                  bin_stddev, bin_min, bin_max) :
 
        from sys import stderr
 
        self.__time = time
 
        # Check the lengths of the arrays
 
        self.__num_bins = len(bin_center)
 
        self.__bin_center = list(bin_center)
 
        if (len(bin_center_align) != self.__num_bins) :
            stderr.write("Incompatible bin_center_align")
            raise ValueError("Incompatible bin_center_align")
 
        self.__bin_center_align = list(bin_center_align)
 
        if (len(map_bin_center) != self.__num_bins) :
            stderr.write("Incompatible map_bin_center")
            raise ValueError("Incompatible map_bin_center")
 
        self.__map_bin_center = list(map_bin_center)
 
        if (len(map_bin_center_align) != self.__num_bins) :
            stderr.write("Incompatible map_bin_center_align")
            raise ValueError("Incompatible map_bin_center_align")
 
        self.__map_bin_center_align = list(map_bin_center_align)
 
        if (len(num_entries) != self.__num_bins) :
            stderr.write("Incompatible num_entries")
            raise ValueError("Incompatible num_entries")
 
        self.__num_entries = list(num_entries)
 
        if (len(bin_weight) != self.__num_bins) :
            stderr.write("Incompatible bin_weight")
            raise ValueError("Incompatible bin_weight")
 
        self.__bin_weight = list(bin_weight)
 
        if (len(bin_mean) != self.__num_bins) :
            stderr.write("Incompatible bin_mean")
            raise ValueError("Incompatible bin_mean")
 
        self.__bin_mean = list(bin_mean)
 
        if (len(bin_stddev) != self.__num_bins) :
            stderr.write("Incompatible bin_stddev")
            raise ValueError("Incompatible bin_stddev")
 
        self.__bin_stddev = list(bin_stddev)
 
        if (len(bin_min) != self.__num_bins) :
            stderr.write("Incompatible bin_min")
            raise ValueError("Incompatible bin_min")
 
        self.__bin_min = list(bin_min)
 
        if (len(bin_max) != self.__num_bins) :
            stderr.write("Incompatible bin_max")
            raise ValueError("Incompatible bin_max")
 
        self.__bin_max = list(bin_max)
 
    def get_time(self) :
        return self.__time
 
    def get_num_bins(self) :
        return self.__num_bins
 
    def get_bin_center(self) :
        return self.__bin_center
 
    def get_bin_center_align(self) :
        return self.__bin_center_align
 
    def get_map_bin_center(self) :
        return self.__map_bin_center
 
    def get_map_bin_center_align(self) :
        return self.__map_bin_center_align
 
    def get_num_entries(self) :
        return self.__num_entries
 
    def get_bin_weight(self) :
        return self.__bin_weight
 
    def get_bin_mean(self) :
        return self.__bin_mean
 
    def get_bin_stddev(self) :
        return self.__bin_stddev
 
    def get_bin_min(self) :
        return self.__bin_min
 
    def get_bin_max(self) :
        return self.__bin_max
 
    def find_transition_min_index(self, value, from_below=None) :
 
        ret_val = None  # If found, returns index of first bin past transition
 
        num_bins = self.__num_bins
 
        if (num_bins > 1) :
 
            if (from_below is None) :
 
                # Look for transition in either direction
 
                last_val = self.__bin_mean[0]
 
                last_val_rel = last_val - value
 
                i = int(1)
 
                found_trans = False
 
                while ((i < num_bins) and (not found_trans)) :
 
                    next_val = self.__bin_mean[i]
 
                    next_val_rel = next_val - value
 
                    # At transition, the relative values change sign
 
                    if ((next_val_rel * last_val_rel) < 0.0) :
                        found_trans = True
                    else :
                        i += 1
 
                if (found_trans) :
                    ret_val = i
 
            elif (from_below) :
 
                # Find the index of the first bin above or equal to value
 
                i = int(0)
 
                found_bin = False
 
                while ((i < num_bins) and (not found_bin)) :
 
                    next_val = self.__bin_means[i]
 
                    if (not (next_val < value)) :
                        found_bin = True
                    else :
                        i += 1
 
                if (found_bin) :
                    ret_val = i
 
            else :
 
                # Find the index of the first bin below or equal to value
 
                i = int(0)
 
                found_bin = False
 
                while ((i < num_bins) and (not found_bin)) :
 
                    next_val = self.__bin_means[i]
 
                    if (not (next_val > value)) :
                        found_bin = True
                    else :
                        i += 1
 
                if (found_bin) :
                    ret_val = i
 
        return ret_val
 
 
    def find_transition_max_index(self, value, from_below=None) :
 
        ret_val = None  # If found, returns index of last bin before transition
 
        num_bins = self.__num_bins
 
        last_bin = num_bins - 1
 
        if (num_bins > 1) :
 
            if (from_below is None) :
 
                # Look for transition in either direction
 
                last_val = self.__bin_mean[last_bin]
 
                last_val_rel = last_val - value
 
                i = int(last_bin - 1)
 
                found_trans = False
 
                while ((i >= 0) and (not found_trans)) :
 
                    next_val = self.__bin_mean[i]
 
                    next_val_rel = next_val - value
 
                    # At transition, the relative values change sign
 
                    if ((next_val_rel * last_val_rel) < 0.0) :
                        found_trans = True
                    else :
                        i -= 1
 
                if (found_trans) :
                    ret_val = i
 
            elif (from_below) :
 
                # Find the index of the last bin above or equal to value
 
                i = int(last_bin)
 
                found_bin = False
 
                while ((i >= 0) and (not found_bin)) :
 
                    next_val = self.__bin_means[i]
 
                    if (not (next_val < value)) :
                        found_bin = True
                    else :
                        i -= 1
 
                if (found_bin) :
                    ret_val = i
 
            else :
 
                # Find the index of the first bin below or equal to value
 
                i = int(last_bin)
 
                found_bin = False
 
                while ((i >= 0) and (not found_bin)) :
 
                    next_val = self.__bin_means[i]
 
                    if (not (next_val > value)) :
                        found_bin = True
                    else :
                        i -= 1
 
                if (found_bin) :
                    ret_val = i
 
        return ret_val
 
 
class TimestepList :
 
    def __init__(self, filename) :
 
        self.__timestep_list = list()
 
        self.__read_file(filename)
 
    def __len__(self) :
        return len(self.__timestep_list)
 
    def __getitem__(self, index) :
        return self.__timestep_list[index]
 
    def __parse_file(self, filename) :
 
        from sys import stderr
 
        infile = file(filename, "r")
 
        filelines = infile.readlines()
 
        num_lines = len(filelines)
 
        # Find the index of the first non-comment line
 
        start_line = int(0)
 
        found_start = False
 
        while ((not found_start) and (start_line < num_lines)) :
            clean_words = filelines[start_line].split("#")[0].split()
 
            if (len(clean_words) > 0) :
                found_start = True
            else :
                start_line += 1
 
        if ((num_lines - start_line) < 3) :
            stderr.write("Incompatible file")
            raise ValueError("Incompatible file")
 
        time_list = list()
        file_blocks = list()
 
        linePtr = start_line
 
        # Read the labels
 
        current_line = filelines[linePtr]
        linePtr += 1
 
        labels = current_line.split("#")[0].split()
 
        # Read the timesteps
 
        while (linePtr < num_lines) :
 
            start_found = False
 
            while ((not start_found) and (linePtr < num_lines)) :
                current_line = filelines[linePtr]
 
                words = current_line.split("#")[0].split()
 
                if (len(words) > 0) :
                    if (words[0] == "[") :
                        start_found = True
 
                if (not start_found) :
                    linePtr += 1
 
            if (start_found) :
 
                current_line = filelines[linePtr]
                linePtr += 1
 
                words = current_line.split()
 
                if (len(words) != 10) :
                    raise ValueError("Incompatible timestep descriptor")
 
                current_time = float(words[4])
 
                block_lines = list()
 
                block_finished = False
 
                while ((linePtr < num_lines) and (not block_finished)) :
 
                    current_line = filelines[linePtr]
 
                    words = current_line.split()
 
                    if (words[0][0] == '[') :
                        block_finished = True
                    else :
                        block_lines.append(words)
                        linePtr += 1
 
                time_list.append(current_time)
                file_blocks.append(block_lines)
 
        return labels, time_list, file_blocks
 
 
    def __read_file(self, filename) :
 
        labels, time_list, file_blocks = self.__parse_file(filename)
 
        # Determine the indexes of the columns
 
        center_index = -1
        center_align_index = -1
        map_center_index = -1
        map_center_align_index = -1
        entries_index = -1
        weight_index = -1
        mean_index = -1
        stddev_index = -1
        min_index = -1
        max_index = -1
 
        num_labels = len(labels)
 
        for i in range(num_labels) :
 
            word = labels[i]
 
            if (word == label_bin_center) :
                center_index = i
            elif (word == label_bin_center_align) :
                center_align_index = i
            elif (word == label_map_bin_center) :
                map_center_index = i
            elif (word == label_map_bin_center_align) :
                map_center_align_index = i
            elif (word == label_num_entries) :
                entries_index = i
            elif (word == label_bin_weight) :
                weight_index = i
            elif (word == label_bin_mean) :
                mean_index = i
            elif (word == label_bin_stddev) :
                stddev_index = i
            elif (word == label_bin_min) :
                min_index = i
            elif (word == label_bin_max) :
                max_index = i
 
        if (center_index < 0) :
            raise ValueError("center_index not found")
 
        if (center_align_index < 0) :
            raise ValueError("center_align_index not found")
 
        if (map_center_index < 0) :
            raise ValueError("map_center_index not found")
 
        if (map_center_align_index < 0) :
            raise ValueError("map_center_align_index not found")
 
        if (entries_index < 0) :
            raise ValueError("entries_index not found")
 
        if (weight_index < 0) :
            raise ValueError("weight_index not found")
 
        if (mean_index < 0) :
            raise ValueError("mean_index not found")
 
        if (stddev_index < 0) :
            raise ValueError("stddev_index not found")
 
        if (min_index < 0) :
            raise ValueError("min_index not found")
 
        if (max_index < 0) :
            raise ValueError("max_index not found")
 
        # Parse the file contents
 
        num_timesteps = len(time_list)
 
        for timestep_index in range(num_timesteps) :
 
            center_list = list()
            center_align_list = list()
            map_center_list = list()
            map_center_align_list = list()
            entries_list = list()
            weight_list = list()
            mean_list = list()
            stddev_list = list()
            min_list = list()
            max_list = list()
 
            current_time = time_list[timestep_index]
 
            data_block = file_blocks[timestep_index]
 
            list_ptr = 0
 
            for words in data_block :
 
                center_list.append(float(words[center_index]))
                center_align_list.append(float(words[center_align_index]))
                map_center_list.append(float(words[map_center_index]))
                map_center_align_list.append(float(words[map_center_align_index]))
                entries_list.append(int(words[entries_index]))
                weight_list.append(float(words[weight_index]))
                mean_list.append(float(words[mean_index]))
                stddev_list.append(float(words[stddev_index]))
                min_list.append(float(words[min_index]))
                max_list.append(float(words[max_index]))
 
            new_step = Timestep()
 
            new_step.load_data(current_time, center_list, center_align_list,
                               map_center_list, map_center_align_list,
                               entries_list,
                               weight_list, mean_list, stddev_list, min_list,
                               max_list)
 
            self.__timestep_list.append(new_step)