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

#!/usr/bin/env python
 
try :
    import psyco
    psyco.full()
except ImportError :
    pass
 
import matplotlib
matplotlib.use("Agg")
 
# File column labels
 
label_bin_index = "bin_index"
label_bin_center = "bin_center"
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"
 
 
x_min = -0.03
x_max = 0.03
y_min = -0.1
y_max = 1.1
 
class Timestep :
 
    def __init__(self) :
 
        self.__time = 0.0
 
        self.__num_bins = 0
 
        self.__bin_center = 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, 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(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_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
 
 
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)
 
        if (num_lines < 3) :
            stderr.write("Incompatible file")
            raise ValueError("Incompatible file")
 
        time_list = list()
        file_blocks = list()
 
        linePtr = 0
 
        # Read the labels
 
        current_line = filelines[0]
        linePtr += 1
 
        labels = current_line.split()
 
        print labels, num_lines
 
        # Read the timesteps
 
        while (linePtr < num_lines) :
 
            current_line = filelines[linePtr]
            linePtr += 1
 
            words = current_line.split()
 
            current_time = float(words[1])
 
            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
        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_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 (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()
            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]))
                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, entries_list,
                               weight_list, mean_list, stddev_list, min_list,
                               max_list)
 
            self.__timestep_list.append(new_step)
 
 
def main(arg_list) :
 
    import pylab
 
    from sys import stderr, exit
 
    argc = len(arg_list)
 
    if (argc != 2) :
        stderr.write("Usage: " + argv[0] + " file\n")
        exit()
 
    argPtr = 1
 
    filename = str(argv[argPtr])
    argPtr += 1
 
    ts_list = TimestepList(filename)
 
    num_lists = len(ts_list)
 
    for ts_index in range(num_lists) :
 
        current_ts = ts_list[ts_index]
 
        stderr.write("Current time [ " + str(current_ts.get_time()) + " ]\n")
 
        fig = pylab.figure(1)
        fig.clf()
        fig.hold(True)
 
        ch = fig.add_subplot(1,1,1)
 
        coords = current_ts.get_bin_center()
 
        # Determine the extent of the coordinates
 
        coord_min = min(coords)
        coord_max = max(coords)
 
        coord_mid = (coord_min + coord_max) * 0.5
 
        means = current_ts.get_bin_mean()
        stddevs = current_ts.get_bin_stddev()
 
        mins = current_ts.get_bin_min()
        maxs = current_ts.get_bin_max()
 
        num_bins = current_ts.get_num_bins()
 
        mean_pstd = list()
        mean_mstd = list()
 
        for i in range(num_bins) :
            stddev_val = stddevs[i]
            mean_val = means[i]
 
            mean_pstd.append(mean_val + stddev_val)
            mean_mstd.append(mean_val - stddev_val)
 
            # Subtract the midpoint from coords
 
            coords[i] -= coord_mid
 
        ch.plot(coords,means, label="Mean")
        # ch.plot(coords,mean_pstd, label="Upper StdDev")
        # ch.plot(coords,mean_mstd, label="Lower Stddev")
        ch.plot(coords,mins, label="Minimum Value")
        ch.plot(coords,maxs, label="Maximum Value")
 
        ch.set_xlim(x_min, x_max)
        ch.set_ylim(y_min, y_max)
        ch.legend(loc="best")
 
        output_filename = filename + "_" \
                          + ("%(index)04d" % { "index" : ts_index}) + ".png"
 
        pylab.savefig(output_filename)
        # pylab.show()
 
 
if (__name__ == "__main__") :
 
    from sys import argv
 
    main(argv)