Commit 563201b4380d431d6797efba6143c41bc9781b59
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__ == '__main__': |
| 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__ == '__main__': |
| 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 | ... | ... |