diff --git a/scripts/postprocessing/io_py_result_processor.py b/scripts/postprocessing/io_py_result_processor.py
new file mode 100644
index 0000000..befe4eb
--- /dev/null
+++ b/scripts/postprocessing/io_py_result_processor.py
@@ -0,0 +1,207 @@
+import sys
+import math
+import itertools
+
+from colorama import Fore, Style
+
+
+def med_dev(vals):
+    med = sum(vals) / len(vals)
+    dev = ((sum(abs(med - i) ** 2 for i in vals) / len(vals)) ** 0.5)
+    return int(med), int(dev)
+
+
+def round_deviation(med_dev):
+    med, dev = med_dev
+
+    if dev < 1E-7:
+        return med_dev
+
+    dev_div = 10.0 ** (math.floor(math.log10(dev)) - 1)
+    dev = int(dev / dev_div) * dev_div
+    med = int(med / dev_div) * dev_div
+    return (type(med_dev[0])(med),
+            type(med_dev[1])(dev))
+
+
+def groupby_globally(data, key_func):
+    grouped = {}
+    grouped_iter = itertools.groupby(data, key_func)
+
+    for (bs, cache_tp, act), curr_data_it in grouped_iter:
+        key = (bs, cache_tp, act)
+        grouped.setdefault(key, []).extend(curr_data_it)
+
+    return grouped
+
+
+class Data(object):
+    def __init__(self, name):
+        self.name = name
+        self.series = {}
+        self.processed_series = {}
+
+
+def process_inplace(data):
+    processed = {}
+    for key, values in data.series.items():
+        processed[key] = round_deviation(med_dev(values))
+    data.processed_series = processed
+
+
+def diff_table(*datas):
+    res_table = {}
+
+    for key in datas[0].processed_series:
+        baseline = datas[0].processed_series[key]
+        base_max = baseline[0] + baseline[1]
+        base_min = baseline[0] - baseline[1]
+
+        res_line = [baseline]
+
+        for data in datas[1:]:
+            val, dev = data.processed_series[key]
+            val_min = val - dev
+            val_max = val + dev
+
+            diff_1 = int(float(val_min - base_max) / base_max * 100)
+            diff_2 = int(float(val_max - base_min) / base_max * 100)
+
+            diff_max = max(diff_1, diff_2)
+            diff_min = min(diff_1, diff_2)
+
+            res_line.append((diff_max, diff_min))
+        res_table[key] = res_line
+
+    return [data.name for data in datas], res_table
+
+
+def print_table(headers, table):
+    lines = []
+    items = sorted(table.items())
+    lines.append([(len(i), i) for i in [""] + headers])
+    item_frmt = "{0}{1:>4}{2} ~ {3}{4:>4}{5}"
+
+    for key, vals in items:
+        ln1 = "{0:>4} {1} {2:>9} {3}".format(*map(str, key))
+        ln2 = "{0:>4} ~ {1:>3}".format(*vals[0])
+
+        line = [(len(ln1), ln1), (len(ln2), ln2)]
+
+        for idx, val in enumerate(vals[1:], 2):
+            cval = []
+            for vl in val:
+                if vl < -10:
+                    cval.extend([Fore.RED, vl, Style.RESET_ALL])
+                elif vl > 10:
+                    cval.extend([Fore.GREEN, vl, Style.RESET_ALL])
+                else:
+                    cval.extend(["", vl, ""])
+
+            ln = len(item_frmt.format("", cval[1], "", "", cval[4], ""))
+            line.append((ln, item_frmt.format(*cval)))
+
+        lines.append(line)
+
+    max_columns_with = []
+    for idx in range(len(lines[0])):
+        max_columns_with.append(
+            max(line[idx][0] for line in lines))
+
+    sep = '-' * (4 + sum(max_columns_with) + 3 * (len(lines[0]) - 1))
+
+    print sep
+    for idx, line in enumerate(lines):
+        cline = []
+        for (curr_len, txt), exp_ln in zip(line, max_columns_with):
+            cline.append(" " * (exp_ln - curr_len) + txt)
+        print "| " + " | ".join(cline) + " |"
+        if 0 == idx:
+            print sep
+    print sep
+
+
+def key_func(x):
+    return (x['__meta__']['blocksize'],
+            'd' if 'direct' in x['__meta__'] else 's',
+            x['__meta__']['name'])
+
+
+template = "{bs:>4}  {action:>12}  {cache_tp:>3}  {conc:>4}"
+template += " | {iops[0]:>6} ~ {iops[1]:>5} | {bw[0]:>7} ~ {bw[1]:>6}"
+template += " | {lat[0]:>6} ~ {lat[1]:>5} |"
+
+headers = dict(bs="BS",
+               action="operation",
+               cache_tp="S/D",
+               conc="CONC",
+               iops=("IOPS", "dev"),
+               bw=("BW kBps", "dev"),
+               lat=("LAT ms", "dev"))
+
+
+def load_io_py_file(fname):
+    with open(fname) as fc:
+        block = None
+        for line in fc:
+            if line.startswith("{"):
+                block = line
+            elif block is not None:
+                block += line
+
+            if block is not None and block.count('}') == block.count('{'):
+                cut = block.rfind('}')
+                block = block[0:cut+1]
+                yield eval(block)
+                block = None
+
+    if block is not None and block.count('}') == block.count('{'):
+        yield eval(block)
+
+
+def main(argv):
+    items = []
+    CONC_POS = 3
+    for hdr_fname in argv[1:]:
+        hdr, fname = hdr_fname.split("=", 1)
+        data = list(load_io_py_file(fname))
+        item = Data(hdr)
+        for key, vals in groupby_globally(data, key_func).items():
+            item.series[key] = [val['iops'] * key[CONC_POS] for val in vals]
+        process_inplace(item)
+        items.append(item)
+
+    print_table(*diff_table(*items))
+
+    # print template.format(**headers)
+
+    # for (bs, cache_tp, act, conc), curr_data in sorted(grouped.items()):
+    #     iops = med_dev([i['iops'] * int(conc) for i in curr_data])
+    #     bw_mean = med_dev([i['bw_mean'] * int(conc) for i in curr_data])
+    #     lat = med_dev([i['lat'] / 1000 for i in curr_data])
+
+    #     iops = round_deviation(iops)
+    #     bw_mean = round_deviation(bw_mean)
+    #     lat = round_deviation(lat)
+
+    #     params = dict(
+    #         bs=bs,
+    #         action=act,
+    #         cache_tp=cache_tp,
+    #         iops=iops,
+    #         bw=bw_mean,
+    #         lat=lat,
+    #         conc=conc
+    #     )
+
+    #     print template.format(**params)
+
+
+if __name__ == "__main__":
+    exit(main(sys.argv))
+
+    # vals = [(123, 23), (125678, 5678), (123.546756, 23.77),
+    #         (123.546756, 102.77), (0.1234, 0.0224),
+    #         (0.001234, 0.000224), (0.001234, 0.0000224)]
+    # for val in :
+    #     print val, "=>", round_deviation(val)
diff --git a/scripts/postprocessing/stat.py b/scripts/postprocessing/stat.py
new file mode 100644
index 0000000..893c0fc
--- /dev/null
+++ b/scripts/postprocessing/stat.py
@@ -0,0 +1,199 @@
+import sys
+import time
+
+from copy import deepcopy
+
+import numpy
+import scipy.optimize as scp
+import matplotlib.pyplot as plt
+
+import io_py_result_processor as io_test
+
+key_pos = {'blocksize': 0, 'direct_io': 1, 'name': 2}
+actions = ['randwrite', 'randread', 'read', 'write']
+types = ['s', 'd']
+colors = ['red', 'green', 'blue', 'cyan',
+          'magenta', 'black', 'yellow', 'burlywood']
+
+def get_key(x, no):
+    """ x = (), no = key_pos key """
+    keys = deepcopy(key_pos)
+    del keys[no]
+    key = [x[n] for n in keys.values()]
+    return tuple(key), x[key_pos[no]]
+
+
+def generate_groups(data, group_id):
+    """ select data for plot by group_id
+        data - processed_series"""
+    grouped = {}
+
+    for key, val in data.items():
+        new_key, group_val = get_key(key, group_id)
+        group = grouped.setdefault(new_key, {})
+        group[group_val] = val
+
+    return grouped
+
+
+def gen_dots(val):
+    """Generate dots from real data
+       val = dict (x:y)
+       return ox, oy lists """
+    oy = []
+    ox = []
+    for x in sorted(val.keys()):
+        ox.append(int(x[:-1]))
+        if val[x][0] != 0:
+            oy.append(1.0/val[x][0])
+        else:
+            oy.append(0)
+    return ox, oy
+
+
+def gen_line_numpy(x, y):
+    A = numpy.vstack([x, numpy.ones(len(x))]).T
+    coef = numpy.linalg.lstsq(A, y)[0]
+    funcLine = lambda tpl, x: tpl[0] * x + tpl[1]
+    print coef
+    return x, funcLine(coef, x)
+
+
+def gen_line_scipy(x, y):
+    funcLine = lambda tpl, x: tpl[0] * x + tpl[1]
+    ErrorFunc = lambda tpl, x, y: 1.0 - y/funcLine(tpl, x)
+    tplInitial = (1.0, 0.0)
+    # print x, y
+    tplFinal, success = scp.leastsq(ErrorFunc, tplInitial[:], args=(x, y),
+                                    diag=(1./x.mean(), 1./y.mean()))
+    if success not in range(1, 4):
+        raise ValueError("No line for this dots")
+    xx = numpy.linspace(x.min(), x.max(), 50)
+    print tplFinal
+    # print x, ErrorFunc(tplFinal, x, y)
+    return xx, funcLine(tplFinal, xx)
+
+
+def gen_app_plot(key, val, plot, color):
+    """ Plots with fake line and real dots around"""
+    ox, oy = gen_dots(val)
+    name = "_".join(str(k) for k in key)
+    if len(ox) < 2:
+        # skip single dots
+        return False
+    # create approximation
+    x = numpy.array(ox)#numpy.log(ox))
+    y = numpy.array(oy)#numpy.log(oy))
+    print x, y
+    try:
+        print name
+        x1, y1 = gen_line_scipy(x, y)
+        plot.plot(x1, y1, color=color)
+        # 
+        #plot.loglog(x1, y1, color=color)
+    except ValueError:
+        # just don't draw it - it's ok
+        # we'll see no appr and bad dots
+        # not return False, because we need see dots
+        pass
+    plot.plot(x, y, '^', label=name, markersize=7, color=color)
+    #plot.loglog(x, y, '^', label=name, markersize=7, color=color)
+    return True
+
+
+def save_plot(key, val):
+    """ one plot from one dict item with value list"""
+    ox, oy = gen_dots(val)
+    name = "_".join(str(k) for k in key)
+    plt.plot(ox, oy, label=name)
+
+
+def plot_generation(fname, group_by):
+    """ plots for value group_by in imgs by actions"""
+    data = list(io_test.load_io_py_file(fname))
+    item = io_test.Data("hdr")
+    for key, vals in io_test.groupby_globally(data, io_test.key_func).items():
+        item.series[key] = [val['iops'] for val in vals]
+    io_test.process_inplace(item)
+
+    pr_data = generate_groups(item.processed_series, group_by)
+    print pr_data
+
+    #fig = plt.figure()
+    plot = plt.subplot(111)
+
+    for action in actions:
+        for tp in types:
+            color = 0
+            hasPlot = False
+            for key, val in pr_data.items():
+                if action in key and tp in key:
+                    ok = gen_app_plot(key, val, plot, colors[color])
+                    hasPlot = hasPlot or ok
+                    color += 1
+                    # use it for just connect dots
+                    #save_plot(key, val)
+            if hasPlot:
+                # Shrink current axis by 10%
+                box = plot.get_position()
+                plot.set_position([box.x0, box.y0 + box.height * 0.1,
+                     box.width, box.height * 0.9])
+
+                # Put a legend to the bottom
+                plot.legend(loc='lower center', bbox_to_anchor=(0.5, -0.25),
+                            fancybox=True, shadow=True, ncol=4,
+                            fontsize='xx-small')
+                plt.title("Plot for %s on %s" % (group_by, action))
+                plt.ylabel("time")
+                plt.xlabel(group_by)
+                plt.grid()
+                # use it if want scale plot somehow
+                # plt.axis([0.0, 5000.0, 0.0, 64.0])
+                name = "%s__%s_%s.png" % (group_by, action, tp)
+                plt.savefig(name, format='png', dpi=100)
+            plt.clf()
+            plot = plt.subplot(111)
+            color = 0
+
+
+def deviation_on_deviation(groups_list, data):
+    """ calc deviation of data all and by selection groups"""
+    total_dev = io_test.round_deviation(io_test.med_dev(data))
+    grouped_dev = [total_dev]
+    for group in groups_list:
+        beg = 0
+        end = group
+        local_dev = []
+        while end <= len(data):
+            local_dev.append(io_test.round_deviation(io_test.med_dev(data[beg:end]))[0])
+            beg += group
+            end += group
+        grouped_dev.append(io_test.round_deviation(io_test.med_dev(local_dev)))
+    return grouped_dev
+
+
+
+def deviation_generation(fname, groups_list):
+    """ Print deviation by groups for data from fname """
+    CONC_POS = key_pos['concurence']
+    int_list = [int(i) for i in groups_list]
+    data = list(io_test.load_io_py_file(fname))
+    item = io_test.Data("hdr")
+    for key, vals in io_test.groupby_globally(data, io_test.key_func).items():
+        item.series[key] = [val['iops'] * key[CONC_POS] for val in vals]
+        print deviation_on_deviation(int_list, item.series[key])
+
+
+def main(argv):
+    if argv[1] == "plot":
+        plot_generation(argv[2], argv[3])
+    elif argv[1] == "dev":
+        deviation_generation(argv[2], argv[3:])
+    
+
+if __name__ == "__main__":
+    exit(main(sys.argv))
+
+
+
+
