Commit 563201b4380d431d6797efba6143c41bc9781b59

Authored by knodlseder
1 parent 211b3d95

add options and cumulative histogram

Showing 1 changed file with 168 additions and 38 deletions
examples/show_ts_distribution.py
1 1 #! /usr/bin/env python
2 2 # ==========================================================================
3   -# This script displays pull histograms that have been generated using the
4   -# cspull script. The pull is defined by
5   -#
6   -# (fitted value - simulated value) / estimated error
7   -#
8   -# and the pull histogram allows to assess possible biases in the fit
9   -# parameters and errors.
  3 +# This script displays the TS distribution values generated using cstsdist.
10 4 #
11 5 # Required 3rd party modules:
12 6 # - matplotlib
... ... @@ -39,9 +33,9 @@ import math
39 33 # ==================== #
40 34 # Read TS distribution #
41 35 # ==================== #
42   -def read_ts(filename):
  36 +def read_ts(filename, tsname="TS"):
43 37 """
44   - Read TS distribution.
  38 + Read TS distribution values from CSV file.
45 39 """
46 40 # Initialise list
47 41 values = []
... ... @@ -57,9 +51,10 @@ def read_ts(filename):
57 51 # Get column index if first row
58 52 if first:
59 53 try:
60   - index = row.index("TS")
  54 + index = row.index(tsname)
61 55 except:
62 56 print 'ERROR: Column "TS" not found in file'
  57 + print row
63 58 raise NameError("TS")
64 59 #print index
65 60  
... ... @@ -72,39 +67,108 @@ def read_ts(filename):
72 67  
73 68 # Create numpy array
74 69 a = np.array(values)
75   - #print a
76 70  
77 71 # Return array
78 72 return a
79 73  
80 74  
81   -# ======================== #
82   -# Main routine entry point #
83   -# ======================== #
84   -if __name__ == '__main__':
  75 +# =========== #
  76 +# Compute erf #
  77 +# =========== #
  78 +def erf(x):
85 79 """
86   - Display pull histogram generated by cspull using matplotlib.
  80 + Compute error function.
87 81 """
88   - # Print usage information
89   - usage = "Usage: show_ts_distribution filename [bins]"
90   - if len(sys.argv) < 2:
91   - print usage
92   - sys.exit()
  82 + # save the sign of x
  83 + sign = 1
  84 + if x < 0:
  85 + sign = -1
  86 + x = abs(x)
93 87  
94   - # Extract parameters
95   - filename = sys.argv[1]
96   - if len(sys.argv) == 3:
97   - nbins = int(sys.argv[2])
98   - else:
99   - nbins = 30
  88 + # constants
  89 + a1 = 0.254829592
  90 + a2 = -0.284496736
  91 + a3 = 1.421413741
  92 + a4 = -1.453152027
  93 + a5 = 1.061405429
  94 + p = 0.3275911
100 95  
101   - # Set lin/log
102   - log = True
  96 + # A&S formula 7.1.26
  97 + t = 1.0/(1.0 + p*x)
  98 + y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*math.exp(-x*x)
103 99  
104   - # Read values from CSV file
105   - values = read_ts(filename)
106   - print len(values), "values read."
  100 + # Return result
  101 + return sign*y # erf(-x) = -erf(x)
  102 +
  103 +
  104 +# =============================== #
  105 +# Display cumulative distribution #
  106 +# =============================== #
  107 +def dist_cdf(values, nbins, title):
  108 + """
  109 + Displays cumulative TS distribution and overplots expectation.
  110 + """
  111 + # Set range and adapt number of bins. We make sure that we have a
  112 + # histogram bin centred on 0 that will capture the TS=0 part.
  113 + max_value = max(values)
  114 + binsize = max_value/nbins
  115 + min_value = 0.5*binsize
  116 + while min_value > min(values):
  117 + min_value -= binsize
  118 + nbins += 1
  119 +
  120 + # Create histogram
  121 + hist_x = []
  122 + hist_y = []
  123 + hist_expect = []
  124 + norm = 0.5*len(values)
  125 + for i in range(nbins):
  126 + x_min = min_value+i*binsize
  127 + x_max = min_value+(i+1)*binsize
  128 + x_val = 0.5*(x_min+x_max)
  129 + y_val = 0.0
  130 + for ts in values:
  131 + if ts > x_min:
  132 + y_val += 1.0
  133 + hist_x.append(x_min)
  134 + hist_y.append(y_val)
  135 + hist_x.append(x_max)
  136 + hist_y.append(y_val)
  137 + if x_min > 0.0:
  138 + value = norm*erf(math.sqrt(0.5*x_min)) + norm
  139 + hist_expect.append(len(values)-value)
  140 + hist_expect.append(len(values)-value)
  141 + else:
  142 + hist_expect.append(norm)
  143 + hist_expect.append(norm)
  144 +
  145 + # Show expected distribution (half)
  146 + l = plt.semilogy(hist_x, hist_y, 'r-', linewidth=2, label="simulations")
  147 + l = plt.semilogy(hist_x, hist_expect, 'k-', linewidth=2, label="expectation")
  148 + l = plt.semilogy(hist_x, hist_y, 'r-', linewidth=2)
  149 +
  150 + # Set plot
  151 + plt.xlabel('TS')
  152 + plt.ylabel('Number of trials > TS')
  153 + plt.title(title)
  154 + plt.grid(True)
  155 + plt.legend(loc="upper right")
  156 +
  157 + # Show histogram
  158 + plt.show()
107 159  
  160 + # Return
  161 + return
  162 +
  163 +
  164 +# ======================================== #
  165 +# Display probability density distribution #
  166 +# ======================================== #
  167 +def dist_pdf(values, nbins, title):
  168 + """
  169 + Display probability density TS distribution and overplots
  170 + expectation.
  171 + """
108 172 # Set range and adapt number of bins. We make sure that we have a
109 173 # histogram bin centred on 0 that will capture the TS=0 part.
110 174 max_value = max(values)
... ... @@ -117,7 +181,7 @@ if __name__ == &#39;__main__&#39;:
117 181 # Create histogram
118 182 n, bins, patches = plt.hist(values, nbins, range=[min_value, max_value], \
119 183 align='mid', facecolor='green', \
120   - log=log)
  184 + log=True, label="simulations")
121 185  
122 186 # Create expected distribution (onyl for positive TS). We compute the
123 187 # full and half of the distribution, as for positively constrained
... ... @@ -139,17 +203,83 @@ if __name__ == &#39;__main__&#39;:
139 203 y_half.append(0.5*y)
140 204  
141 205 # Show expected distribution (half)
142   - if log:
143   - l = plt.semilogy(x, y_half, 'ro', linewidth=2)
144   - else:
145   - l = plt.plot(x, y_half, 'r-', linewidth=2)
  206 + l = plt.semilogy(x, y_half, 'ro', linewidth=2, label="expectation")
146 207  
147 208 # Set plot
148 209 plt.xlabel('TS')
149 210 plt.ylabel('Number of trials')
150   - plt.title('TS distribution ('+filename+')')
  211 + plt.title(title)
151 212 plt.grid(True)
  213 + plt.legend(loc="upper right")
152 214  
153 215 # Show histogram
154 216 plt.show()
  217 +
  218 +
  219 +# ======================== #
  220 +# Main routine entry point #
  221 +# ======================== #
  222 +if __name__ == '__main__':
  223 + """
  224 + Display TS distribution generated using cstsdist using matplotlib.
  225 + """
  226 + # Print usage information
  227 + usage = "Usage: show_ts_distribution filename" \
  228 + " [-n bins] [-c column] [-t title] [-p plot]"
  229 + if len(sys.argv) < 2:
  230 + print usage
  231 + sys.exit()
  232 +
  233 + # Extract parameters
  234 + filename = sys.argv[1]
  235 +
  236 + # Set default parameters
  237 + nbins = 30
  238 + tsname = "TS"
  239 + title = "TS distribution"
  240 + plot = "pdf"
  241 +
  242 + # Parameter dictionnary
  243 + pars = [{'option': '-n', 'value': nbins}, \
  244 + {'option': '-c', 'value': tsname}, \
  245 + {'option': '-t', 'value': title}, \
  246 + {'option': '-p', 'value': plot}]
  247 +
  248 + # Gather parameters from command line
  249 + i = 2
  250 + while i < len(sys.argv):
  251 +
  252 + # Search for options
  253 + for par in pars:
  254 + if sys.argv[i] == par['option']:
  255 + if len(sys.argv) > i+1:
  256 + i += 1
  257 + try:
  258 + par['value'] = sys.argv[i]
  259 + except:
  260 + print usage
  261 + sys.exit()
  262 + else:
  263 + print usage
  264 + sys.exit()
  265 +
  266 + # Next item
  267 + i += 1
  268 +
  269 + # Recover parameters
  270 + nbins = int(pars[0]['value'])
  271 + tsname = pars[1]['value']
  272 + title = pars[2]['value']
  273 + plot = pars[3]['value']
  274 +
  275 + # Read values from CSV file
  276 + values = read_ts(filename, tsname=tsname)
  277 + print len(values), "values read."
  278 +
  279 + # Show histogram
  280 + if plot == "pdf":
  281 + dist_pdf(values, nbins, title)
  282 + else:
  283 + dist_cdf(values, nbins, title)
  284 +
155 285  
156 286 \ No newline at end of file
... ...