14 from io
import StringIO
15 from html
import escape
17 from dateutil.relativedelta
import relativedelta
22 A base class for widgets in the hep ipython projects.
35 from IPython.core.display
import display
42 """The css string for styling the notebook."""
60 """Create the styling widget."""
61 from IPython.core.display
import HTML
62 html = HTML(f
"<style>\n{self.css_string}\n</style>")
68 Viewer Object used to print data to the IPython Notebook.
69 Do not use it on your own.
74 Create a new progress bar viewer.
76 from IPython.core.display
import display
77 from ipywidgets
import FloatProgress, VBox, Layout, Label
85 self.
progress_barprogress_bar = FloatProgress(value=0, min=0, max=1,
86 layout=Layout(width=
"100%", height=
"40px"))
94 def update(self, text_or_percentage):
96 Update the widget with a new event number
99 if isinstance(text_or_percentage, numbers.Number):
101 current_percentage = float(text_or_percentage)
102 current_time = time.time()
104 remaining_percentage = 1.0 - current_percentage
106 time_delta = current_time - self.
last_timelast_time
107 percentage_delta = current_percentage - self.
last_percentagelast_percentage
109 if percentage_delta > 0:
110 time_delta_per_percentage = 1.0 * time_delta / percentage_delta
113 attrs = [
'years',
'months',
'days',
'hours',
'minutes',
'seconds']
115 def human_readable(delta):
return [f
'{int(getattr(delta, attr))} {getattr(delta, attr) > 1 and attr or attr[:-1]}'
116 for attr
in attrs
if getattr(delta, attr)]
118 times_list = human_readable(relativedelta(seconds=time_delta_per_percentage * remaining_percentage))
119 human_readable_str =
" ".join(times_list)
121 display_text = f
"{int(100 * current_percentage)} % Remaining time: {human_readable_str}"
124 self.
progress_barprogress_bar.value = float(current_percentage)
127 self.
progress_labelprogress_label.value = f
"Status: {text_or_percentage}"
128 if "finished" in str(text_or_percentage):
131 elif "failed" in str(text_or_percentage):
140 from IPython.core.display
import display
147 Viewer object for the store entries.
148 Do not use it on your own.
153 Create a new collections viewer with the collections object from the process.
154 Collections must be a StoreContentList with a list of StoreContents.
160 self.
table_row_htmltable_row_html =
"""<tr><td style="padding: 10px 0;">{content.name}</td>
161 <td style="padding: 10px 0;">{content.number}</td></tr>"""
168 import ipywidgets
as widgets
171 return widgets.HTML(
"")
176 for i, event
in enumerate(self.
collectionscollections):
177 html = widgets.HTML()
178 html.value =
"""<table style="border-collapse: separate; border-spacing: 50px 0;">"""
179 for store_content
in event.content:
180 html.value += self.
table_row_htmltable_row_html.format(content=store_content)
181 html.value +=
"</table>"
182 children.append(html)
183 a.set_title(i,
"Event " + str(event.event_number))
185 a.children = children
192 A viewer widget for displaying the
193 statistics in a nicer way in ipython
197 """ Init the widget with the statistics from the process.
198 The statistics must be an instance of Statistics. """
207 self.
table_cell_htmltable_cell_html =
"""<td style="padding: 10px; text-align: left">{content}</td>"""
209 self.
table_cell_3_htmltable_cell_3_html =
"""<td style=\"text-align: right\">{content[0]}</td><td>{content[1]}</td><td>{content[2]}</td>"""
215 import ipywidgets
as widgets
218 return widgets.HTML(
"")
220 html = widgets.HTML()
221 html.value =
"""<table style="border-collapse: collapsed; border: 1px solid black;">
222 <thead><tr style="background: #AAA; font-weight: bold">"""
224 for column
in self.
statisticsstatistics.columns:
225 if column.three_column_format:
226 html.value += self.
table_column_3_htmltable_column_3_html.format(content=column.display_name)
228 html.value += self.
table_column_htmltable_column_html.format(content=column.display_name)
229 html.value +=
"</tr></thead><tbody>"
231 for n, module
in enumerate(self.
statisticsstatistics.modules):
233 html.value +=
"""<tr style="background: #EEE;">"""
235 html.value +=
"""<tr>"""
237 for column
in self.
statisticsstatistics.columns:
238 if column.three_column_format:
239 html.value += self.
table_cell_3_htmltable_cell_3_html.format(content=module[column.name])
241 html.value += self.
table_cell_htmltable_cell_html.format(content=module[column.name])
243 html.value +=
"</tr>"
247 html.value +=
"</tbody></table>"
254 A widget to summarize all the infromation from different processes.
255 Must be filled with the widgets of the single processes
260 Create a process viewer
270 import ipywidgets
as widgets
273 for i
in range(len(self.
childrenchildren)):
274 a.set_title(i,
"Process " + str(i))
275 a.children = [children.create()
for children
in self.
childrenchildren
if children
is not None]
283 import ipywidgets
as widgets
284 from IPython.core.display
import display
290 a = widgets.HTML(
"<strong>Calculation list empty. Nothing to show.</strong>")
297 A widget to show the log of a calculation.
302 Initialize the log viewer.
309 self.
log_levelslog_levels = [
"DEBUG",
"INFO",
"RESULT",
"WARNING",
"ERROR",
"FATAL",
"DEFAULT"]
312 self.
log_color_codeslog_color_codes = {
"DEBUG":
"gray",
"ERROR":
"red",
"FATAL":
"red",
"INFO":
"black",
"RESULT":
"green",
313 "WARNING":
"orange",
"DEFAULT":
"black"}
316 self.
log_messagelog_message =
"""<pre class="log-line-{type_lower}" title="{info}">[{level}] {message}{var_output}</pre>"""
320 $('.log-line-{type_lower}-hide-button').hide();
321 $('.log-line-{type_lower}-show-button').show();"
322 style="cursor: pointer; margin: 0px 10px;"
323 class="log-line-{type_lower}-hide-button">Hide {type_upper}</a>
324 <a onclick="$('.log-line-{type_lower}').show();
325 $('.log-line-{type_lower}-hide-button').show();
326 $('.log-line-{type_lower}-show-button').hide();"
327 style="cursor: pointer; margin: 0px 10px; display: none;"
328 class="log-line-{type_lower}-show-button">Show {type_upper}</a>"""
332 Format the json object of a logmessage as key: value list with recursion and indentation
333 Funnily this is faster than json.dumps() and looks a bit better in the title attribute
335 for key, val
in message.items():
338 if isinstance(val, dict):
339 buf.write(f
"{key}:\n")
340 self.
format_logmessageformat_logmessage(buf, val, indent=indent, base=base + indent)
342 buf.write(base *
" ")
343 buf.write(f
"{key}: {val!r}\n")
347 Create the log viewer.
349 from ipywidgets
import HTML, HBox, VBox
352 output.write(
"<style scoped>\n")
354 level = level.lower()
355 output.write(f
".log-line-{level} {{margin:0; padding:0; line-height:normal; color: {color} !important;}}\n")
357 output.write(
"""</style><div style="max-height: 400px; overflow-y: auto; width: 100%";>""")
359 for line
in self.
log_contentlog_content.split(
"\n"):
360 if line.startswith(
'{"level"'):
362 message = json.loads(line)
369 info = escape(buf.getvalue())
371 variables = message.get(
"variables",
"")
373 variables =
"\n".join([
""] + [f
"\t{k} = {v}" for k, v
in variables.items()])
375 level = message[
"level"].lower()
376 output.write(self.
log_messagelog_message.format(info=info, type_lower=level, var_output=variables, **message))
378 except json.JSONDecodeError:
382 output.write(
'<pre class="log-line-default">')
384 output.write(
'</pre>')
386 output.write(
"</div>")
389 html.value = output.getvalue()
395 buttons.append(HTML(self.
toggle_button_linetoggle_button_line.format(type_lower=type.lower(), type_upper=type.upper())))
397 buttons_view = HBox(buttons)
398 buttons_view.margin =
"10px 0px"
399 result_vbox = VBox((buttons_view, html))