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 #! /usr/bin/env python 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 # Required 3rd party modules: 5 # Required 3rd party modules:
12 # - matplotlib 6 # - matplotlib
@@ -39,9 +33,9 @@ import math @@ -39,9 +33,9 @@ import math
39 # ==================== # 33 # ==================== #
40 # Read TS distribution # 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 # Initialise list 40 # Initialise list
47 values = [] 41 values = []
@@ -57,9 +51,10 @@ def read_ts(filename): @@ -57,9 +51,10 @@ def read_ts(filename):
57 # Get column index if first row 51 # Get column index if first row
58 if first: 52 if first:
59 try: 53 try:
60 - index = row.index("TS") 54 + index = row.index(tsname)
61 except: 55 except:
62 print 'ERROR: Column "TS" not found in file' 56 print 'ERROR: Column "TS" not found in file'
  57 + print row
63 raise NameError("TS") 58 raise NameError("TS")
64 #print index 59 #print index
65 60
@@ -72,39 +67,108 @@ def read_ts(filename): @@ -72,39 +67,108 @@ def read_ts(filename):
72 67
73 # Create numpy array 68 # Create numpy array
74 a = np.array(values) 69 a = np.array(values)
75 - #print a  
76 70
77 # Return array 71 # Return array
78 return a 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 # Set range and adapt number of bins. We make sure that we have a 172 # Set range and adapt number of bins. We make sure that we have a
109 # histogram bin centred on 0 that will capture the TS=0 part. 173 # histogram bin centred on 0 that will capture the TS=0 part.
110 max_value = max(values) 174 max_value = max(values)
@@ -117,7 +181,7 @@ if __name__ == &#39;__main__&#39;: @@ -117,7 +181,7 @@ if __name__ == &#39;__main__&#39;:
117 # Create histogram 181 # Create histogram
118 n, bins, patches = plt.hist(values, nbins, range=[min_value, max_value], \ 182 n, bins, patches = plt.hist(values, nbins, range=[min_value, max_value], \
119 align='mid', facecolor='green', \ 183 align='mid', facecolor='green', \
120 - log=log) 184 + log=True, label="simulations")
121 185
122 # Create expected distribution (onyl for positive TS). We compute the 186 # Create expected distribution (onyl for positive TS). We compute the
123 # full and half of the distribution, as for positively constrained 187 # full and half of the distribution, as for positively constrained
@@ -139,17 +203,83 @@ if __name__ == &#39;__main__&#39;: @@ -139,17 +203,83 @@ if __name__ == &#39;__main__&#39;:
139 y_half.append(0.5*y) 203 y_half.append(0.5*y)
140 204
141 # Show expected distribution (half) 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 # Set plot 208 # Set plot
148 plt.xlabel('TS') 209 plt.xlabel('TS')
149 plt.ylabel('Number of trials') 210 plt.ylabel('Number of trials')
150 - plt.title('TS distribution ('+filename+')') 211 + plt.title(title)
151 plt.grid(True) 212 plt.grid(True)
  213 + plt.legend(loc="upper right")
152 214
153 # Show histogram 215 # Show histogram
154 plt.show() 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 \ No newline at end of file 286 \ No newline at end of file