gstlal-inspiral  0.4.2
 All Classes Namespaces Files Functions Variables Pages
gstlal_inspiral_summary_page
1 #!/usr/bin/env python
2 #
3 # Copyright (C) 2011 Chad Hanna
4 #
5 # This program is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by the
7 # Free Software Foundation; either version 2 of the License, or (at your
8 # option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13 # Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License along
16 # with this program; if not, write to the Free Software Foundation, Inc.,
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 
19 ## @file
20 # This program makes a summary web page of a gstlal inspiral analysis.
21 
22 import sys, os, socket, re
23 import glob, math, shutil
24 import numpy
25 from glue import cbcwebpage
26 from glue import lal
27 from glue import segments
28 from optparse import OptionParser
29 
30 from gstlal import inspiral_pipe
31 from pylal import git_version
32 __author__ = "Chad Hanna <channa@ligo.caltech.edu>"
33 __version__ = "git id %s" % git_version.id
34 __date__ = git_version.date
35 
36 
37 def parse_command_line():
38  parser = OptionParser(version = git_version.verbose_msg, usage = "%prog [options] [file ...]", description = "%prog summary web page")
39  parser.add_option("--webserver-dir", help = "Set the directory for the webserver. Required. Example /archive/home/channa/public_html/highmass_months_23-24_summary_page")
40  parser.add_option("--open-box", action = "store_true", help = "Produce open box page")
41  parser.add_option("--output-user-tag", action = "append", metavar = "name", help = "Set the basename for image search")
42  parser.add_option("--title", default="gstlal_inspiral offline analysis")
43  parser.add_option("--glob-path", help = "This is the path to search for images")
44 
45  opts, filenames = parser.parse_args()
46  return opts, filenames
47 
48 # PARSE THE COMMAND LINE
49 opts, files = parse_command_line()
50 
51 # INITIALIZE THE PAGE OBJECT
52 page = cbcwebpage.cbcpage(title=opts.title)
53 
54 # add external frames
55 for f in files:
56  page.add_external_frame(f, f)
57 
58 # WELCOME MESSAGE PAGE
59 page.front = "<big>Welcome</big>"
60 
61 ### Summary info.
62 page.add_subpage("summary", "Summary information", "Summary information")
63 page.subpages["summary"].div("""
64 Summary information: This page provides information on the number of triggers, live time and horizon distance.
65 """)
66 
67 # number of triggers
68 tab, name = cbcwebpage.wiki_table_parse(os.path.join(opts.glob_path, '%snum_trigs_table.txt' % opts.output_user_tag[0]))
69 if tab:
70  page.subpages["summary"].add_table(tab[0], "Coinc events summary", "This table gives the number of coincident events")
71 
72 # livetime
73 tab, name = cbcwebpage.wiki_table_parse(os.path.join(opts.glob_path, '%slive_time_table.txt' % opts.output_user_tag[0]))
74 if tab:
75  page.subpages["summary"].add_table(tab[0], "Live time summary", "This table gives the summary of the live time")
76 
77 imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*HORIZON*.png'))
78 page.subpages["summary"].add_table(imgtable, "Horizon Distance", "This is the distance at which you should see a 1.4 1.4 Msun binary at SNR 8. The first panel shows the time evolution of the horizon distance and the second panel shows the same information in histogram form. ")
79 
80 ### INJ PARAM PAGE ###
81 page.add_subpage("injection_params","Injection Parameters", "Injection Parameters")
82 
83 page.subpages["injection_params"].div("""
84 <big><b>OVERVIEW:</b></big><br><br>
85 Injections are the addition of simulated signals into the gravitational wave strain data. They are useful
86 for diagnosing the pipeline and measuring the sensitivity. Care is taken to ensure that the input
87 distribution is sensible. The remaining sections describe the input distributions for the injections.
88 They are not necessarily what is analyzed since the analyzed segments are not used for determining the
89 injection sets (i.e. injections may be scheduled for times when a detector is not even functioning).
90 <br><br>The following plots are typically produced by injection waveform type. Several injection runs
91 of the same waveform (with different random seeds) are often done. Here all runs of the same waveform type
92 are shown together.
93 """)
94 
95 page.subpages["injection_params"].add_section("m1_m2","Injected Parameters m1 and m2")
96 imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*6_sim_dist_m1_m2*.png'))
97 page.subpages["injection_params"].sections["m1_m2"].add_table(imgtable, "Injected mass1, mass2", "Above are the injected mass parameters for the simulations done. Typically injections are done uniformally in component mass unless the waveform approximant cannot support certain mass ratios.")
98 
99 page.subpages["injection_params"].add_section("time_dist","Injected Parameters time and distance")
100 imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*6_sim_dist_time_distance*.png'))
101 page.subpages["injection_params"].sections["time_dist"].add_table(imgtable, "Injection time and distance", "Unless doing a directed search injections are uniform in time. Although the correct distance distribution would be uniform in volume typically logarithmic injections are done")
102 
103 page.subpages["injection_params"].add_section("ra_dec","Injected Parameters RA and DEC")
104 imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*6_sim_dist_ra_dec*.png'))
105 page.subpages["injection_params"].sections["ra_dec"].add_table(imgtable, "Injection RA and DEC", "Unless doing a directed search injections are uniform on the sky.")
106 
107 page.subpages["injection_params"].add_section("inc_pol","Injected Parameters inclination and polarization")
108 imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*6_sim_dist_inc_pol*.png'))
109 page.subpages["injection_params"].sections["inc_pol"].add_table(imgtable, "Injection Inclination and polarization", "Unless doing a directed search injections are uniform in sin(inclination) and polarizations.")
110 
111 page.subpages["injection_params"].add_section("spin","Injected Parameters Z component spin")
112 imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*6_sim_dist_spin1z_spin2z*.png'))
113 page.subpages["injection_params"].sections["spin"].add_table(imgtable, "Injection spin 1z and spin2z", "The Z component spins of the injection set. Often injections are done without spin, so don't be surprised if these are zero.")
114 
115 
116 ### INJ ACC PAGE ###
117 page.add_subpage("injection_params_acc","Injection Parameters Accuracy", "Injection Accuracy")
118 page.subpages["injection_params_acc"].div("""
119 <big><b>OVERVIEW:</b></big><br><br>
120 The accuracy of recovered parameters aids at diagnosing the performance of the pipeline as well as
121 hinting at the possibility of measuring certain parameters. Mass parameters for the low mass search
122 are often recovered better than mass parameters for the high mass search.
123 """)
124 
125 page.subpages["injection_params_acc"].add_section("mchirp_param_acc","Mchirp Parameter Accuracy")
126 imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*2_mchirp_acc_frac_*.png'))
127 page.subpages["injection_params_acc"].sections["mchirp_param_acc"].add_table(imgtable, "Mchirp Accuracy", "Accuracy of chirp mass.")
128 page.subpages["injection_params_acc"].add_section("eta_param_acc","Eta Parameter Accuracy")
129 imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*2_eta_acc_frac_*.png'))
130 page.subpages["injection_params_acc"].sections["eta_param_acc"].add_table(imgtable, "Eta Accuracy", "Accuracy of eta")
131 page.subpages["injection_params_acc"].add_section("time_param_acc","Time Parameter Accuracy")
132 imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*2_t_acc_*.png'))
133 page.subpages["injection_params_acc"].sections["time_param_acc"].add_table(imgtable, "Time Accuracy", "Accuracy of time")
134 page.subpages["injection_params_acc"].add_section("deff_param_acc","Effective Distance Accuracy")
135 imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*2_deff_acc_frac*.png'))
136 page.subpages["injection_params_acc"].sections["deff_param_acc"].add_table(imgtable, "Effective Distance Accuracy", "Accuracy of effective distance")
137 page.subpages["injection_params_acc"].add_section("spin_param_acc","Effective Spin Accuracy")
138 imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*2_chi_acc*.png'))
139 page.subpages["injection_params_acc"].sections["spin_param_acc"].add_table(imgtable, "Effective Spin Accuracy", "Accuracy of mass-weighted spin")
140 
141 ### MISSED FOUND ###
142 page.add_subpage("missed_found","Missed Found", "Missed Found")
143 #page.subpages["missed_found"].add_section("overview","Missed found injections overview")
144 page.subpages["missed_found"].div("""
145 <big><b>OVERVIEW:</b></big><br><br>
146 Measuring the found and missed injections as a function of various parameters aids in diagnosing the
147 pipeline as well as providing the expected sensitivity of the pipeline to real signals. The plots in
148 this section show the missed and found injections as a for the various IFO times for coincident triggers.
149 We allow double coincident events so some categories can have multiple types of found injections (for
150  example H1L1 and H1H2L1 triggers in H1H2L1 time). Because of ambiguity concerning the time of an
151 injection and the injection window it is occasionally possible to find an injection in more detectors
152 than what the "time" refers to. For example, an injection's geocentric end time might be in H1L1 time
153 but that might occur near a boundary where H2 was also on. Thus one could find an H1L1 injection in
154 H1H2L1 time.
155 """)
156 
157 page.subpages["missed_found"].add_section("found_missed_mchirp","Found / Missed Chirp Mass")
158 page.subpages["missed_found"].add_section("found_missed_mtotal","Found / Missed Total Mass")
159 page.subpages["missed_found"].add_section("found_missed_time","Found / Missed Time")
160 page.subpages["missed_found"].add_section("found_missed_chi","Found / Missed Spin")
161 
162 for tag in opts.output_user_tag:
163  tab,name = cbcwebpage.wiki_table_parse(os.path.join(opts.glob_path, '%sinjection_summary.txt' % tag))
164  page.subpages["missed_found"].add_table(tab[0], "Injection Summary Table: %s" % tag, "Summary of missed and found injections broken up by detector time")
165 
166  imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*%s*1_d_vs_mchirp_*.png' % tag))
167  page.subpages["missed_found"].sections["found_missed_mchirp"].add_table(imgtable, "Missed Found Distance vs Mchirp: %s" % tag, "Distance of found and missed injections as a function of chirp mass")
168  imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*%s*1_deff_vs_mchirp_*.png' % tag))
169  page.subpages["missed_found"].sections["found_missed_mchirp"].add_table(imgtable, "Missed Found Effective Distance vs Mchirp: %s" % tag, "Effective distance of found and missed injections as a function of chirp mass")
170  imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*%s*1_chirpdist_vs_mchirp_*.png' % tag))
171  page.subpages["missed_found"].sections["found_missed_mchirp"].add_table(imgtable, "Missed Found Chirp Distance vs Mchirp: %s" % tag, "Chirp distance of found and missed injections as a function of chirp mass. For low mass systems the chirp mass scales out of the expected amplitude. The chirp distance utilizes this and rescales the distance to be appropriate for a NS-NS binary. At low total mass the missed/found barrier should be flat on this plot.")
172 
173  imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*%s*1_deff_vs_mtotal_*.png' % tag))
174  page.subpages["missed_found"].sections["found_missed_mtotal"].add_table(imgtable, "Missed Found Effective Distance vs M total: %s" % tag, "Effective distance of found and missed injections as a function of total mass")
175 
176  imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*%s*1_deff_vs_t_*.png' % tag))
177  page.subpages["missed_found"].sections["found_missed_time"].add_table(imgtable, "Missed Found vs Time: %s" % tag, "Effective distance of found and missed injections as a function of time")
178 
179  imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*%s*1_deff_vs_chi_*.png' % tag))
180  page.subpages["missed_found"].sections["found_missed_chi"].add_table(imgtable, "Missed Found vs Spin: %s" % tag, "Effective distance of found and missed injections as a function of mass-weighted spin")
181 
182 # SEARCH SENSITIVITY PLOTS #
183 page.add_subpage("search_sensitivity","Search Sensitivity", "Search Sensitivity")
184 page.subpages["search_sensitivity"].div("""
185 <big><b>OVERVIEW:</b></big><br><br>
186 This page shows plots that characterize the overall sensitivity of the search. The detection rate is directly proportional to the observed sensitive volume, which is a function of the significance threshold used to identify candidates. These plots are useful for determining how sensitive the search was to the input injection population. Since the search sensitivity is a strong function of the intrinsic parameters of the target source, we break down the sensitive into bins of these parameters. Here we show the sensitivity as a function of total mass and component mass.
187 """)
188 page.subpages["search_sensitivity"].add_section("chirp_mass","Binned by chirp mass")
189 page.subpages["search_sensitivity"].add_section("total_mass","Binned by total mass")
190 page.subpages["search_sensitivity"].add_section("mass1_mass2","Binned by mass1-mass2")
191 page.subpages["search_sensitivity"].add_section("aligned_spin","Binned by aligned spin")
192 page.subpages["search_sensitivity"].add_section("mass_ratio","Binned by mass ratio")
193 
194 for tag in opts.output_user_tag:
195  imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*%s*BINNED_BY_CHIRP_MASS*.png' % tag))
196  page.subpages["search_sensitivity"].sections["chirp_mass"].add_table(imgtable, "Sensitive volume (V*T) and mean sensitive distance: %s" % tag, "Binned by chirp mass")
197  imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*%s*BINNED_BY_TOTAL_MASS*.png' % tag))
198  page.subpages["search_sensitivity"].sections["total_mass"].add_table(imgtable, "Sensitive volume (V*T) and mean sensitive distance: %s" % tag, "Binned by total mass")
199  imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*%s*BINNED_BY_MASS1_MASS2*.png' % tag))
200  page.subpages["search_sensitivity"].sections["mass1_mass2"].add_table(imgtable, "Sensitive volume (V*T) and mean sensitive distance: %s" % tag, "Binned by component mass")
201  imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*%s*BINNED_BY_ALIGNED_SPIN*.png' % tag))
202  page.subpages["search_sensitivity"].sections["aligned_spin"].add_table(imgtable, "Sensitive volume (V*T) and mean sensitive distance: %s" % tag, "Binned by aligned spin")
203  imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*%s*BINNED_BY_MASS_RATIO*.png' % tag))
204  page.subpages["search_sensitivity"].sections["mass_ratio"].add_table(imgtable, "Sensitive volume (V*T) and mean sensitive distance: %s" % tag, "Binned by mass ratio")
205 
206 
207 # BACKGROUND#
208 page.add_subpage("background","Background", "Background")
209 page.subpages["background"].div("""
210 <big><b>OVERVIEW:</b></big><br><br>
211 This page shows the ingredients that go into ranking events and determining the False alarm probability.
212 """)
213 page.subpages["background"].add_section("snrchi","SNR and chi-squared")
214 page.subpages["background"].sections["snrchi"].div("This section gives the SNR / Chisq background statistics.")
215 imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*SNRCHI2*.png'))
216 page.subpages["background"].sections["snrchi"].add_table(imgtable, "","")
217 
218 page.subpages["background"].add_section("snrsnr","SNR ratios")
219 imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*SNR_PDF*.png'))
220 page.subpages["background"].sections["snrsnr"].add_table(imgtable, "","")
221 
222 page.subpages["background"].add_section("rates","Rates")
223 imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*RATES*.png'))
224 page.subpages["background"].sections["rates"].add_table(imgtable, "","")
225 
226 page.subpages["background"].add_section("rankingstat","Ranking Statistic Models")
227 page.subpages["background"].sections["rankingstat"].div("This section shows the ranking statistic (log likelihood ratio) PDFs and CCDFs for the noise and signal models.")
228 imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*LIKELIHOOD_RATIO_*.png'))
229 page.subpages["background"].sections["rankingstat"].add_table(imgtable, "","")
230 
231 
232 #
233 # CLOSED BOX
234 #
235 
236 if not opts.open_box:
237 
238  ### CHISQ ###
239  page.add_subpage("chisq","Chi-squared", "Chi-squared")
240  page.subpages["chisq"].div("""
241 <big><b>OVERVIEW:</b></big><br><br>
242 The chi-squared test checks that the snr accumulated matches expectation.
243  """)
244  page.subpages["chisq"].add_section("chisq","Chi-squared vs SNR")
245  imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*3_chi2_vs_rho_*closedbox*.png'))
246  page.subpages["chisq"].sections["chisq"].add_table(imgtable, "Chi-squared Vs SNR", "Chi-squared vs snr for single detectors after coincidence. Blue points are full data zero lag, red are software injections and black are time slides.")
247 
248  page.subpages["chisq"].add_section("snr","Signal-to-Noise Ratio")
249  imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*4_rho_*_vs_*closedbox*.png'))
250  page.subpages["chisq"].sections["snr"].add_table(imgtable, "Signal-to-Noise Ratio", "Comparison of SNR in pairs of detectors.")
251 
252  page.subpages["chisq"].add_section("deff","Effective Distance")
253  imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*4_deff_*_vs_*closedbox*.png'))
254  page.subpages["chisq"].sections["deff"].add_table(imgtable, "Effective Distance", "Comparison of effective distance in pairs of detectors.")
255 
256  ### Money Plots ###
257  page.add_subpage("money","Money Plots", "Money Plots")
258  page.subpages["money"].div("""
259 <big><b>OVERVIEW:</b></big><br><br>
260 This section provides the detection statistic plots and a summary of the loudest event.
261 """)
262  page.subpages["money"].add_section("ifar","Rate vs. IFAR Threshold")
263  imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*5_count_vs_ifar*closedbox*.png'))
264  page.subpages["money"].sections["ifar"].add_table(imgtable, "Rate vs. IFAR Threshold", "Comparison of observed zero-lag event rate to event rate expected from background as a function of inverse false-alarm rate (IFAR) threshold.")
265  page.subpages["money"].add_section("table","Loudest Table")
266  tab,name = cbcwebpage.wiki_table_parse(os.path.join(opts.glob_path, '%sbgsummary_table.txt' % opts.output_user_tag[0]))
267  page.subpages["money"].sections["table"].add_table(tab[0], "Closed Box Summary Table", "Loudest Events")
268 
269 #
270 # OPEN BOX
271 #
272 
273 else:
274  print >>sys.stderr, "WARNING: OPENING THE BOX"
275 
276  ### CHISQ ###
277  page.add_subpage("chisq","Chi-squared", "Chi-squared")
278  page.subpages["chisq"].div("""
279 <big><b>OVERVIEW:</b></big><br><br>
280 The chi-squared test checks that the snr accumulated matches expectation.
281 FIXME
282  """)
283  page.subpages["chisq"].add_section("chisq","Chi-squared vs SNR")
284  imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*3_chi2_vs_rho_*openbox*.png'))
285  page.subpages["chisq"].sections["chisq"].add_table(imgtable, "Chi-squared Vs SNR", "Chi-squared vs snr for single detectors after coincidence. Blue points are full data zero lag, red are software injections and black are time slides.")
286 
287  page.subpages["chisq"].add_section("snr","Signal-to-Noise Ratio")
288  imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*4_rho_*_vs_*openbox*.png'))
289  page.subpages["chisq"].sections["snr"].add_table(imgtable, "Signal-to-Noise Ratio", "Comparison of SNR in pairs of detectors.")
290 
291  page.subpages["chisq"].add_section("deff","Effective Distance")
292  imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*4_deff_*_vs_*openbox*.png'))
293  page.subpages["chisq"].sections["deff"].add_table(imgtable, "Effective Distance", "Comparison of effective distance in pairs of detectors.")
294 
295  ### Money Plots ###
296  page.add_subpage("money","Money Plots", "Money Plots")
297  page.subpages["money"].div("""
298 <big><b>OVERVIEW:</b></big><br><br>
299 This section provides the detection statistic plots and a summary of the loudest event.
300 """)
301  page.subpages["money"].add_section("ifar","Rate vs. IFAR Threshold")
302  imgtable = cbcwebpage.image_glob(os.path.join(opts.glob_path, '*5_count_vs_ifar*openbox*.png'))
303  page.subpages["money"].sections["ifar"].add_table(imgtable, "Rate vs. IFAR Threshold", "Comparison of observed zero-lag event rate to event rate expected from background as a function of inverse false-alarm rate (IFAR) threshold.")
304  page.subpages["money"].add_section("table","Loudest Table")
305  tab,name = cbcwebpage.wiki_table_parse(os.path.join(opts.glob_path, '%ssummary_table.txt' % opts.output_user_tag[0]))
306  page.subpages["money"].sections["table"].add_table(tab[0], "Summary Table", "Loudest Events")
307 
308  ### UPPER LIMIT PLOTS ###
309  #page.add_subpage("ul","Upper Limit Plots", "Upper Limit Plots")
310  #page.subpages["ul"].div("""
311 #<big><b>OVERVIEW:</b></big><br><br>
312 #This section describes the upperlimit calculation which is a 90% confidence upper limit on the rate of mergers with units mergers/Mpc^3/year as a function of mass. Various
313 #quantities go into this calculation. They are shown here.
314 #""")
315 
316  #range_summs = glob.glob(base_name+'-*_range_summary.txt')
317  #for rs in range_summs:
318  # tag = rs.replace('_',' ').replace('.txt','')
319  # page.subpages["ul"].add_section(tag,rs)
320  # tab,name = cbcwebpage.wiki_table_parse(rs)
321  # page.subpages["ul"].sections[tag].add_table(tab[0], "Range Summary", "Range summary")
322 
323  #page.subpages["ul"].add_section("vt","Volume x time")
324  #imgtable = cbcwebpage.image_glob(base_name+'-*_volume_time.png')
325  #page.subpages["ul"].sections["vt"].add_table(imgtable, "Volume x time", "mass1 mass2 volume x time")
326 
327  #page.subpages["ul"].add_section("evt","Error on Volume x time")
328  #imgtable = cbcwebpage.image_glob(base_name+'-*_fractional_error.png')
329  #page.subpages["ul"].sections["evt"].add_table(imgtable, "Error on Volume x time", "Error on mass1 mass2 volume x time")
330 
331  #page.subpages["ul"].add_section("l","Lambda")
332  #imgtable = cbcwebpage.image_glob(base_name+'-*_lambda.png')
333  #page.subpages["ul"].sections["l"].add_table(imgtable, "Lambda", "likelihood fg/bg @ loudest event")
334 
335  #page.subpages["ul"].add_section("p","Posterior")
336  #imgtable = cbcwebpage.image_glob(base_name+'-*_posterior.png')
337  #page.subpages["ul"].sections["p"].add_table(imgtable, "Posterior", "Poseterior on the rate")
338 
339  #page.subpages["ul"].add_section("ul","90% Upper limit")
340  #imgtable = cbcwebpage.image_glob(base_name+'-*_upper_limit.png')
341  #page.subpages["ul"].sections["ul"].add_table(imgtable, "90% Upper limit", "90% upper limit")
342 
343  #page.subpages["ul"].add_section("cul","Combined 90% Upper limit")
344  #imgtable = [[cbcwebpage._imagelinkcpy(base_name+'upper_limit.png'), cbcwebpage._imagelinkcpy(base_name+'posterior.png')]]
345  #page.subpages["ul"].sections["cul"].add_table(imgtable, "Combined 90% Upper limit", "Combined 90% upper limit")
346 
347 
348 if opts.open_box:
349  page.write("%s_openbox" % opts.output_user_tag[0])
350 else:
351  page.write("%s_closebox" % opts.output_user_tag[0])
352 
353 # copy the output
354 if opts.webserver_dir:
355  for f in page.external_frames:
356  shutil.copy(f[0], opts.webserver_dir)
357  for f in page.fnames:
358  shutil.copy(f,opts.webserver_dir)
359  #FIXME not the best way to do this, I should explicitely save file names
360  try: os.mkdir(opts.webserver_dir+'/Images')
361  except: pass
362  for f in glob.glob('Images/*.png'):
363  shutil.copy(f,opts.webserver_dir+'/Images')