Jupyter (MC+ROOT) - Init notebook

Lutz Althüser (l.althueser@uni-muenster.de)
Updated: 2017-09-16

Imports


In [ ]:
#Init_ToC()
#Init_saveHTML("00_Init")

In [6]:
import sys
nb_stdout = sys.stdout
import os
import os.path
import time
from datetime import datetime
import shutil
import glob
from pathlib import Path
import socket
import multiprocessing
import gzip

import math
import numpy as np
from scipy.optimize import curve_fit
from scipy import interpolate
import pandas as pd
from multihist import Histdd
from tqdm import tqdm, tqdm_notebook
import pickle
import fnmatch
import itertools
from random import gauss
import collections

import ROOT #see next line
#import rootpy.ROOT as ROOT
from rootpy.io import root_open, TemporaryFile
from rootpy.tree import Tree, TreeModel, FloatCol, IntCol, IntArrayCol
from rootpy.plotting import Hist, Hist2D, HistStack, Profile, Profile2D
from rootpy.plotting import root2matplotlib as rplt
import root_pandas
from root_numpy import root2array

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from matplotlib import gridspec
from matplotlib.mlab import griddata
from matplotlib.colors import LogNorm
from matplotlib.patches import Circle, Wedge, Polygon
from matplotlib.collections import PatchCollection
from multihist import Histdd

# Turn interactive plotting off - show plots with plt.show() and close unwanted figures with plt.close(fig)
plt.ioff()

#from IPython.core.display import display, HTML
from IPython.display import Image, display, HTML, Javascript, display_javascript, Markdown, Latex
from IPython.core.magics.display import Javascript

import logging
logging.getLogger('rootpy.stl').setLevel(logging.CRITICAL)
logging.basicConfig(level=logging.CRITICAL)
log = logging.getLogger('Nb_log')
import warnings
warnings.filterwarnings('ignore')
sys.stdout = nb_stdout

%matplotlib inline
matplotlib.rc('font', size=16)
matplotlib.rcParams.update({'figure.autolayout': True})
plt.rcParams['figure.figsize'] = (12.0, 10.0)
my_cmap = matplotlib.cm.get_cmap('jet') # use jet or viridis
my_cmap.set_under('w')
plt.set_cmap(my_cmap) 
plt.close()

def in_notebook():
    """
    Returns ``True`` if the module is running in IPython kernel,
    ``False`` if in IPython shell or other Python shell.
    """
    return 'ipykernel' in sys.modules

Notebook functions


In [3]:
Nb_directory = "./"
Nb_name = ""
Nb_hostname = socket.gethostname()

def Init_Init(_Nb_name):
    global Nb_directory
    global Nb_name
    Nb_name = _Nb_name
    Nb_directory = './'+Nb_name
    cur_dir = os.getcwd()
    sub_dir = '/'.join(os.getcwd().split('/')[:-1])

    if not os.path.exists(Nb_directory):
        os.makedirs(Nb_directory)

    # print('Initialized with notebook name: ' + Nb_name)

In [4]:
def Init_save():
    return display(Javascript("IPython.notebook.save_notebook()"),
                   include=['application/javascript'])

# use `output_HTML(notebook_name)` to save as HTML
def Init_saveHTML(read_file):
    Init_save()
    time.sleep(3)
    if Path(read_file+'.ipynb').is_file():
        print('Save notebook to: '+read_file+'_<date>.html')
        os.system('jupyter nbconvert --to html '+read_file+'.ipynb')
        os.system('mv '+read_file+'.html '+read_file+'_$(date +"%Y%m%d-%H%M%S").html')

In [5]:
def Init_cssNbWidth(width):
    display(HTML("<style>.container {{ width:{0}% !important; margin-left: 5% !important;}}</style>".format(width)))
    
def Init_cssNbCenterPlots():
    # center plots in output
    CSS = """
    .output_png img {
        display: block;
        margin-left: auto;
        margin-right: auto;
    }
    """
    display(HTML('<style>{0}</style>'.format(CSS)))

In [24]:
def show_numbered(key="figure"):
    return display(HTML('''<div id="%s"></div>
<script>
var fignb = 1;
var key = "%s"
$("div").each(function(i){
    if (this.id === key){
        this.innerHTML = '<a name="' + key + '-' + fignb.toString() + '"></a>' +
                         '<a class="anchor" href="#' + key + '-' + fignb.toString() +'"><b><i>' + key.charAt(0).toUpperCase() + key.slice(1) + ' ' + fignb.toString() + '</i></b></a>';
        fignb += 1;
    }
});
</script>
''' % (key,key)))

LaTeX settings


In [6]:
# Add new LaTeX style file
def Init_plt_LaTeXstyle(LaTeX=False):
    
    # from \the\textwidth in LaTeX
    textwidth_pt = 405.45178

    fig_width_pt = textwidth_pt                    # Get this from LaTeX using \the\textwidth
    inches_per_pt = 1.0/72.27                      # Convert pt to inch
    fig_width = fig_width_pt*inches_per_pt*2       # width in inches
    fig_height = fig_width*2/3                     # height in inches
    # figure.figsize: 5.610236335962363, 3.740157557308242
        
    if LaTeX:
        style="""
        backend: pgf

        pgf.texsystem: pdflatex        # change this if using xetex or lautex
        pgf.rcfonts: False
        text.usetex: True              # use LaTeX to write all text
        font.family: serif
        font.serif: []                 # blank entries should cause plots to inherit fonts from the document
        font.sans-serif: []
        font.monospace: []

        axes.labelsize: 22

        font.size: 24
        legend.fontsize: 24
        xtick.labelsize: 20
        ytick.labelsize: 20

        figure.figsize: {0}, {1}
        figure.dpi: 150
        savefig.dpi: 150
        
        text.latex.preamble:  \\usepackage[utf8x]{{inputenc}}, \\usepackage[T1]{{fontenc}}, \\usepackage{{siunitx}}, \\usepackage{{isotope}}
        pgf.preamble:  \\usepackage[utf8x]{{inputenc}}, \\usepackage[T1]{{fontenc}}, \\usepackage{{siunitx}}, \\usepackage{{isotope}}

        # from LaTeX:
        # \\the\\textwidth
        """.format(fig_width,fig_height)
       
    else:
        style="""
        backend: Agg
        
        # LaTeX to write all text
        text.usetex: False 
        text.latex.preamble:  \\usepackage[utf8x]{{inputenc}}, \\usepackage[T1]{{fontenc}}, \\usepackage{{siunitx}}, \\usepackage{{isotope}}
        
        # colormap
        #image.cmap : viridis

        # figure
        figure.figsize : {0}, {1}
        figure.dpi: 100
        savefig.dpi: 100

        # font
        font.size: 22
        font.serif: Computer Modern Roman
        font.monospace: Computer Modern Typewriter
        font.sans-serif: Computer Modern Sans serif
        #font.family: serif 
        font.family: STIXGeneral
        
        mathtext.fontset: custom
        mathtext.it: STIXGeneral:italic
        mathtext.bf: STIXGeneral:italic:bold
        mathtext.rm: STIXGeneral:roman        
        mathtext.fallback_to_cm : True
        mathtext.default : it 
        
        # axes
        axes.titlesize : 28
        axes.labelsize : 22
        axes.linewidth : 1

        # ticks
        xtick.labelsize : 18
        ytick.labelsize : 18

        xtick.major.size : 7
        xtick.minor.size : 3
        ytick.major.size : 7
        ytick.minor.size : 3

        xtick.major.width : 1
        xtick.minor.width : 1
        ytick.major.width : 1
        ytick.minor.width : 1

        xtick.direction : in
        ytick.direction : in

        savefig.bbox : tight
        legend.fontsize : 18
        """.format(fig_width,fig_height)
        
    if not Path(matplotlib.get_configdir()+'/stylelib').exists():
        os.mkdir(matplotlib.get_configdir()+'/stylelib')

    with open(matplotlib.get_configdir()+'/stylelib/latex_thesis.mplstyle', 'w') as f:
        f.write(style)
        
    # use the style
    plt.style.use(matplotlib.get_configdir()+'/stylelib/latex_thesis.mplstyle')

ToC with Javascript


In [2]:
def Init_HTML_additions(maxlevel=3, attribution=''):
    """
    Adds a floating code hider button and table of content to the top right of the notebook. Only the first apperance of equal headlines is linked. This can also be used to add a table of content somewhere in a markdown cell.

    To add a table of content in a markdown cell use the following code:
        <h2 id="tocheading">Table of Content</h2>
        <div id="tocinline"></div>
    
    Args:
        maxlevel: Set the max level to which headlines are added. (default: maxlevel=3)
        attribution: This will add a footer with you desired string. (default: attribution='')
    """
    if attribution == 'LA': attribution = 'Created by Lutz Althüser.'
    return HTML('''<script>
// Converts integer to roman numeral
function romanize(num) {
    var lookup = {M:1000,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1},
    roman = '',
        i;
    for ( i in lookup ) {
        while ( num >= lookup[i] ) {
        roman += i;
        num -= lookup[i];
        }
    }
    return roman;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

// Builds a <ul> Table of Contents from all <headers> in DOM
function createTOC(toc_tag){
    var toc = "";
    var level = 0;
    var maxlevel = 1 + %s;
    var levels = {};
    $('#'+toc_tag).html('');

    $(":header").each(function(i){
        if (this.id=='tocheading'){return;}
        if (this.tagName[1] >= maxlevel){return;}
        
        var titleText = this.innerHTML;
        var openLevel = this.tagName[1];

        // Wiki hacks
        if (titleText.indexOf("User Tools") !== -1){return;}
        if (titleText.indexOf("Site Tools") !== -1){return;}
        if (titleText.indexOf("Page Tools") !== -1){return;}
        if (titleText.indexOf("XENON1TWiki") !== -1){return;}

        if (levels[openLevel]){
        levels[openLevel] += 1;
        } else{
        levels[openLevel] = 1;
        }

        if (openLevel > level) {
        toc += (new Array(openLevel - level + 1)).join('<ul class="'+toc_tag+'">');
        } else if (openLevel < level) {
        toc += (new Array(level - openLevel + 1)).join("</ul>");
        for (i=level;i>openLevel;i--){levels[i]=0;}
        }

        level = parseInt(openLevel);

        if (this.id==''){this.id = this.innerHTML.replace(/ /g,"-")}
        var anchor = this.id;

        toc += '<li><a href="#' + escape(anchor) + '">'
        + romanize(levels[openLevel].toString()) + '. ' + titleText
        + '</a></li>';
        
    });
    
    if (level) {
    toc += (new Array(level + 1)).join("</ul>");
    }
 
    $('#'+toc_tag).append(toc);
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

// Executes the createTOC_inline function
setTimeout(function(){createTOC('tocinline');},1000);
setTimeout(function(){createTOC('tocinline');},5000);
setTimeout(function(){createTOC('tocinline');},15000);

// Rebuild TOC_inline every 5 minutes
setInterval(function(){createTOC('tocinline');},300000);

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

$('<div id="toc"></div>').css({position: 'fixed', top: '160px', right: 20, background: "rgba(255, 255, 255, 0.6)"}).appendTo(document.body);
$("#toc").css("z-index", "2000");

// Executes the createToc function
setTimeout(function(){createTOC('toc');},100);
setTimeout(function(){createTOC('toc');},5000);
setTimeout(function(){createTOC('toc');},15000);

// Rebuild TOC every 5 minutes
setInterval(function(){createTOC('toc');},300000);

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

function toc_toggle() {
 if ($('#toc').is(':visible')){
     $('#toc').hide('500');
     $('#tocButton').val('Show table of content')
 } else {
     $('#toc').show('500');
     $('#tocButton').val('Hide table of content')
 }
} 

if (!($('#tocButton').length)) {
    $('<form action="javascript:toc_toggle()"><input type="submit" id="tocButton" value="Hide table of content"></form>').css({position: 'fixed', top: '135px', right: 20, background: "rgba(255, 255, 255, 0.6)"}).appendTo(document.body);
} else {
    $('#tocButton').val('Hide table of content')
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

function code_toggle() {
 if ($("div.input").is(':visible')){
     $("div.input").hide('500');
     $('#CodeButton').val('Show all Code')
     $('#CodeButton_inline').val('Show all code in this notebook')
 } else {
     $("div.input").show('500');
     $('#CodeButton').val('Hide all Code')
     $('#CodeButton_inline').val('Hide all code in this notebook')
 }
} 

$( document ).ready(function(){ $('div.input').hide() });

if (!($('#CodeButton').length)) {
    $('<form action="javascript:code_toggle()"><input type="submit" id="CodeButton" value="Show all code"></form>').css({position: 'fixed', top: '110px', right: 20, background: "rgba(255, 255, 255, 0.6)"}).appendTo(document.body);
} else {
    $('#CodeButton').val('Show all Code')
}

$('<div id="attribution_footer" style="float:right; color:#999; background:#fff;"> </div>').css({position: 'fixed', bottom: '0px', right: 20}).appendTo(document.body);
$('#attribution_footer').html('%s');

</script>

<form action="javascript:code_toggle()"><input type="submit" id="CodeButton_inline" value="Show all code in this notebook"></form>

''' % (maxlevel, attribution))

ROOT stuff


In [9]:
# This is for intercepting the output of ROOT
# In a cell, put %%rootprint so that the output that would normally be
# sent directly to the stdout will instead be displayed in the cell.
# It must be the first element in the cell.
import tempfile
from IPython.core.magic import (Magics, magics_class, cell_magic)

@magics_class
class RootMagics(Magics):
    """Magics related to Root.

    %%rootprint  - Capture Root stdout output and show in result cell
    """

    def __init__(self, shell):
        super(RootMagics, self).__init__(shell)

    @cell_magic
    def rootprint(self, line, cell):
        """Capture Root stdout output and print in ipython notebook."""

        with tempfile.NamedTemporaryFile(mode='w+', newline='\n') as tmpFile:
            ROOT.gSystem.RedirectOutput(tmpFile.name, "w")
            exec(cell) in self.shell.user_ns
            ROOT.gROOT.ProcessLine("gSystem->RedirectOutput(0);")
            print(tmpFile.read())

# Register
ip = get_ipython()
ip.register_magics(RootMagics)

In [10]:
class Quiet_ROOT:
    """Context manager for silencing certain ROOT operations.  Usage:
    with Quiet_ROOT(ROOT.kFatal):
       foo_that_makes_output

    You can set a higher or lower warning level to ignore different
    kinds of messages.  After the end of indentation, the level is set
    back to what it was previously.
    """
    def __init__(self, level=ROOT.kInfo + 1):
        self.level = level
    
    def __enter__(self):
        self.oldlevel = ROOT.gErrorIgnoreLevel
        ROOT.gErrorIgnoreLevel = self.level

    def __exit__(self, type, value, traceback):
        ROOT.gErrorIgnoreLevel = self.oldlevel

In [ ]: