diff --git a/cal_tools/cal_tools/ana_tools.py b/cal_tools/cal_tools/ana_tools.py
index 689c946814c010052f115765926e3b20989be8d1..2015576b9b6391fc30c092a3ecf8c820ba9dbc9a 100644
--- a/cal_tools/cal_tools/ana_tools.py
+++ b/cal_tools/cal_tools/ana_tools.py
@@ -2,6 +2,7 @@ import h5py
 import numpy as np
 import matplotlib.pyplot as plt
 import datetime
+import dateutil.parser
 import glob
 
 
@@ -43,16 +44,16 @@ def load_data_from_hdf5(filelist):
                     if mKey not in data[cKey]:
                         data[cKey][mKey] = {}
                     # Loop over module data
-                    for tKey in f.get(cKey + '/' + mKey):
+                    for tKey in f.get('{}/{}'.format(cKey, mKey)):
 
                         if tKey == 'ctime':
-                            if "ctime" not in data[cKey][mKey]:
-                                data[cKey][mKey]["ctime"] = []
+                            ctime = data[cKey][mKey].get("ctime", [])
                             for timeKey in f.get("/".join((cKey, mKey, tKey))):
                                 path = "/".join((cKey, mKey, tKey, timeKey))
                                 value = f.get(path).value
-                                value = datetime.datetime.fromtimestamp(value)
-                                data[cKey][mKey]["ctime"].append(value)
+                                value = dateutil.parser.parse(value)
+                                ctime.append(value)
+                            data[cKey][mKey]["ctime"] = ctime
                             continue
 
                         # Load ndarray if they are there
@@ -63,7 +64,7 @@ def load_data_from_hdf5(filelist):
                             continue
 
                         # Loop over stored data
-                        for dKay in f.get( "/".join((cKey, mKey, tKey))):
+                        for dKay in f.get("/".join((cKey, mKey, tKey))):
 
                             # Loop over metadata
                             if dKay == "mdata":
@@ -74,19 +75,19 @@ def load_data_from_hdf5(filelist):
                                         "/".join(
                                             (cKey, mKey, tKey, 'mdata',
                                              mdKey))).value
-                                if "mdata" not in data[cKey][mKey]:
-                                    data[cKey][mKey]["mdata"] = []
-                                data[cKey][mKey]["mdata"].append(mdata)
+                                mdata_l = data[cKey][mKey].get("mdata", [])
+                                mdata_l.append(mdata)
+                                data[cKey][mKey]["mdata"] = mdata_l
                                 continue
 
                             if dKay not in data[cKey][mKey]:
                                 data[cKey][mKey][dKay] = []
 
                             value = f.get(
-                            "/".join((cKey, mKey, tKey, dKay))).value
+                                "/".join((cKey, mKey, tKey, dKay))).value
 
                             if dKay == "ctime":
-                                value = datetime.datetime.fromtimestamp(value)
+                                value = dateutil.parser.parse(value)
 
                             data[cKey][mKey][dKay].append(value)
     return data
@@ -106,7 +107,7 @@ def recursively_save_dict_contents_to_group(h5file, path, dic):
 
         # Prepare datatime to save
         if isinstance(item, datetime.datetime):
-            item = item.timestamp()
+            item = item.isoformat()
 
         # Iterate over dictionary
         if isinstance(item, dict):
@@ -119,7 +120,7 @@ def recursively_save_dict_contents_to_group(h5file, path, dic):
                 if isinstance(x, dict):
                     recursively_save_dict_contents_to_group(h5file, newpath, x)
                 elif isinstance(x, datetime.datetime):
-                    h5file[newpath] = x.timestamp()
+                    h5file[newpath] = x.isoformat()
                 else:
                     raise ValueError('Cannot save a list of %s ' % type(item))
 
@@ -302,11 +303,11 @@ def multi_intersect(a, b):
     return from_multiset(aa & bb)
 
 
-def HMCombine(data, fname=None, type=1, **kwargs):
+def hm_combine(data, fname=None, type=1, **kwargs):
     """
     Plot heatmap for calibration report
 
-    :param data: data to plot
+    :param data: 2D numpy.array of data points to plot
     :param fname: file name of output file
     :param type: type of figure
     :param kwargs: other keywords supported by pyDetLib heatmapPlot
@@ -334,7 +335,7 @@ def HMCombine(data, fname=None, type=1, **kwargs):
     vmin = kwargs.get('vmin', None)
     vmax = kwargs.get('vmax', None)
 
-    h_frame = (1 - pad_b - pad_t)
+    h_frame = 1 - pad_b - pad_t
     w_frame = 1 - pad_l - pad_r
 
     if type == 2:
@@ -347,7 +348,8 @@ def HMCombine(data, fname=None, type=1, **kwargs):
             mean = np.nanmean(data[y])
             if vmin and vmax:
                 mean = np.nanmean(
-                    data[y, np.where((data[y] > vmin) & (data[y] < vmax))])
+                    data[y, np.where((data[y] > vmin) & (data[y] < vmax))]
+                )
 
             ax = plt.axes(
                 [pad_l, pad_b + h_frame * y + mar, w_frame, h_frame - 2 * mar],
@@ -356,17 +358,16 @@ def HMCombine(data, fname=None, type=1, **kwargs):
                 yticklabels=['{:4.2f}'.format(mean)],
                 xticks=[],
                 xticklabels=[]
-                )
+            )
             ax.tick_params(axis='y', which='major', pad=25)
 
             if vmin and vmax:
-                ax.set_ylim([vmin, vmax])
+                ax.set_ylim(vmin, vmax)
 
             d = [{'x': np.arange(data.shape[1]),
                   'y': data[y],
                   'drawstyle': 'steps-mid',
                   'linestyle': 'dotted',
-                  # 'marker': '^',
                   'linewidth': 2,
 
                   'color': 'white',
@@ -381,15 +382,16 @@ def HMCombine(data, fname=None, type=1, **kwargs):
                  ]
 
             y_lab = ''
-            if y == data.shape[0] / 2:
+            # Locate label in a middle of the axis
+            if y == int(data.shape[0] / 2):
                 y_lab = 'Average over time'
 
-            _ = xana.simplePlot(d,  # aspect=1.6,
+            _ = xana.simplePlot(d,
                                 x_label="",
                                 y_label=y_lab,
                                 use_axis=ax,
                                 y_log=False)
-    elif type == 1:
+    if type == 1:
 
         ax2 = plt.axes([pad_l, pad_b, w_frame, h_frame / 16.], frame_on=False,
                        yticks=range(3), yticklabels=[32, 16, 0],
@@ -399,8 +401,6 @@ def HMCombine(data, fname=None, type=1, **kwargs):
         ax2.set_ylabel('Memory cell ID', color='r')
         ax2.tick_params('y', colors='r', right=True, left=False,
                         labelright=True, labelleft=False, )
-    else:
-        pass
 
     if fname:
         fig.savefig(fname, bbox_inches='tight')
diff --git a/notebooks/AGIPD/PlotFromCalDB_AGIPD_NBC.ipynb b/notebooks/AGIPD/PlotFromCalDB_AGIPD_NBC.ipynb
index ebd3e6629a64f2085bc766c597efce9d70cf54a4..6d74ac1ef738b01bdddc25762f9edf9d336aef28 100644
--- a/notebooks/AGIPD/PlotFromCalDB_AGIPD_NBC.ipynb
+++ b/notebooks/AGIPD/PlotFromCalDB_AGIPD_NBC.ipynb
@@ -35,8 +35,8 @@
     "bias_voltages = [300, 500]  # Bias voltage\n",
     "mem_cells = [128, 176]  # Number of used memory cells. Typically: 4,32,64,128,176.\n",
     "photon_energy = 9.2  # Photon energy of the beam\n",
-    "out_folder = \"/gpfs/exfel/data/scratch/karnem/testAGIPD16_14/\"  # Output folder, required\n",
-    "use_existing = \"/gpfs/exfel/data/scratch/karnem/testAGIPD16_9/\" # Input folder\n",
+    "out_folder = \"/gpfs/exfel/data/scratch/karnem/testAGIPD16_10/\"  # Output folder, required\n",
+    "use_existing = \"\" # Input folder\n",
     "cal_db_timeout = 1200000 # timeout on caldb requests\",\n",
     "detectorDB = \"AGIPD1M1\"  # detector entry in the DB to investigate\n",
     "dclass = \"AGIPD\"  # Detector class\n",
@@ -52,24 +52,20 @@
    },
    "outputs": [],
    "source": [
-    "import os\n",
-    "import numpy as np\n",
-    "import matplotlib\n",
-    "\n",
-    "##matplotlib.use(\"agg\")\n",
-    "import matplotlib.pyplot as plt\n",
-    "% matplotlib inline\n",
-    "\n",
-    "import sys\n",
     "import datetime\n",
     "import dateutil.parser\n",
+    "import numpy as np\n",
+    "import os\n",
+    "import sys\n",
     "import warnings\n",
-    "\n",
     "warnings.filterwarnings('ignore')\n",
     "\n",
+    "import matplotlib\n",
+    "% matplotlib inline\n",
+    "\n",
     "from iCalibrationDB import Constants, Conditions, Detectors\n",
     "from cal_tools.tools import get_from_db\n",
-    "from cal_tools.ana_tools import *\n"
+    "from cal_tools.ana_tools import *"
    ]
   },
   {
@@ -83,8 +79,10 @@
     "# Prepare variables\n",
     "interval = 1  # interval for evaluation in days\n",
     "\n",
-    "if modules[0] == -1:\n",
-    "    modules = list(range(16))\n",
+    "nMem = 176 # Number of mem Cells to store\n",
+    "spShape = (64,64) # Shape of superpixel\n",
+    "\n",
+    "adu_to_photon = 8000 / 3.6 / 67.# ADU to photon conversion factor\n",
     "\n",
     "in_mod_names = []\n",
     "for mod in modules:\n",
@@ -120,15 +118,6 @@
     "print('CalDB Interface {}'.format(cal_db_interface))"
    ]
   },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": []
-  },
   {
    "cell_type": "code",
    "execution_count": null,
@@ -140,7 +129,7 @@
     "import copy\n",
     "\n",
     "def prepare_to_store(a, nMem):\n",
-    "    shape = list(a.shape[:2])+[nMem,2]\n",
+    "    shape = list(a.shape[:2])+[nMem, 2]\n",
     "    b = np.full(shape, np.nan)\n",
     "    b[:, :, :a.shape[2]] = a[:, :, :, :2]\n",
     "    return b\n",
@@ -154,9 +143,32 @@
     "                a.shape[2],\n",
     "                a.shape[3])\n",
     "    \n",
+    "def modify_const(const, data, isBP = False):\n",
+    "    if const in ['SlopesFF']:\n",
+    "        if (len(data.shape) == 4):\n",
+    "            data = data[:, :, :, 0][..., None]\n",
+    "        else:\n",
+    "            data = data[..., None]\n",
     "\n",
-    "nMem = 176 # Number of mem Cells to store\n",
-    "spShape = (64,64) # Shape of superpixel\n",
+    "    if not isBP:\n",
+    "        if data.shape[0] != 128:\n",
+    "            data = data.swapaxes(0, 2).swapaxes(1, 3).swapaxes(2, 3)\n",
+    "\n",
+    "        # Copy slope medium to be saved later\n",
+    "        if const in ['SlopesPC']:\n",
+    "            data[:, :, :, 1] = data[:, :, :, 3]\n",
+    "    else:\n",
+    "        if const in ['SlopesPC']:\n",
+    "            if len(data.shape) == 3:\n",
+    "                data = data[:, :, :, None].repeat(10, axis=3)\n",
+    "\n",
+    "        if data.shape[0] != 128:\n",
+    "            data = data.swapaxes(0, 1).swapaxes(1, 2)\n",
+    "        \n",
+    "    if len(data.shape) < 4:\n",
+    "        print(data.shape, \"Unexpected shape !!!!!!!!!\")\n",
+    "\n",
+    "    return data\n",
     "\n",
     "ret_constants = {}\n",
     "\n",
@@ -223,29 +235,11 @@
     "                                                                  cdata is not None),\n",
     "                          ctime)\n",
     "                    print(cdata.shape)\n",
-    "\n",
-    "                    if const in ['SlopesFF']:\n",
-    "                        if (len(cdata.shape) == 4):\n",
-    "                            cdata = cdata[:, :, :, 0][..., None]\n",
-    "                        else:\n",
-    "                            cdata = cdata[..., None]\n",
-    "\n",
-    "                    if len(cdata.shape) < 4:\n",
-    "                        print(cdata.shape, \"Unexpected shape !!!!!!!!!\")\n",
-    "\n",
-    "                    if cdata.shape[0] != 128:\n",
-    "                        cdata = cdata.swapaxes(0, 2).swapaxes(1, 3).swapaxes(2, 3)\n",
-    "\n",
-    "                    # Copy slope medium to be saved later\n",
-    "                    if const in ['SlopesPC']:\n",
-    "                        cdata[:, :, :, 1] = cdata[:, :, :, 3]\n",
-    "\n",
+    "                    cdata = modify_const(const, cdata)\n",
     "                    print(cdata.shape)\n",
     "\n",
     "                    # Request bad pixel mask\n",
     "                    if const in constantsDark:\n",
-    "                        #for par in mcond.parameters:\n",
-    "                        #    print (par.name, par.value)\n",
     "                        print('RequestBP ',\n",
     "                              (creation_time + step + step + step + step))\n",
     "                        cdataBP, ctimeBP = get_from_db(getattr(det, qm),\n",
@@ -269,26 +263,11 @@
     "\n",
     "                        print(\"Found BP {}\".format(ctimeBP))\n",
     "                        print(cdataBP.shape)\n",
-    "\n",
-    "                        if const in ['SlopesFF']:\n",
-    "                            if len(cdataBP.shape) == 4:\n",
-    "                                cdataBP = cdataBP[:, :, :, 0][..., None]\n",
-    "                            else:\n",
-    "                                cdataBP = cdataBP[..., None]\n",
-    "\n",
-    "                        if const in ['SlopesPC']:\n",
-    "                            if len(cdataBP.shape) == 3:\n",
-    "                                cdataBP = cdataBP[:, :, :, None].repeat(10,\n",
-    "                                                                        axis=3)\n",
-    "\n",
-    "                        if cdataBP.shape[0] != 128:\n",
-    "                            cdataBP = cdataBP.swapaxes(0, 1).swapaxes(1, 2)\n",
-    "\n",
-    "                        if (len(cdataBP.shape) < 4):\n",
-    "                            print(cdataBP.shape, \"Unexpected shape !!!!!!!!!\")\n",
-    "\n",
+    "                        cdataBP = modify_const(const, cdataBP, True)\n",
+    "                        print(cdataBP.shape)\n",
+    "                        \n",
     "                        if cdataBP.shape != cdata.shape:\n",
-    "                            print(cdataBP.shape, 'Wrong BP shape!!!')\n",
+    "                            print('Wrong BP shape!!!')\n",
     "                            ctime = ctime.replace(tzinfo=None)\n",
     "                            dt = ctime - step\n",
     "                            continue\n",
@@ -329,7 +308,7 @@
     "                                                     'mdata': dpar})\n",
     "                    \n",
     "                    ctime = ctime.replace(tzinfo=None)\n",
-    "                    dt = ctime - step\n"
+    "                    dt = ctime - step"
    ]
   },
   {
@@ -373,10 +352,12 @@
    },
    "outputs": [],
    "source": [
-    "print ('Combine Gain FF and PC and Noise in [e-]')\n",
+    "# Combine FF and PC data to calculate Gain\n",
+    "# Estimate Noise in units of electrons\n",
+    "print ('Calculate Gain and Noise in electron units')\n",
+    "\n",
     "ret_constants[\"Gain\"] = {}\n",
     "ret_constants[\"Noise-e\"] = {}\n",
-    "\n",
     "for module in list(range(16)):\n",
     "    if (\"SlopesFF\" not in ret_constants or\n",
     "            \"SlopesPC\" not in ret_constants):\n",
@@ -422,6 +403,7 @@
     "    \n",
     "    ret_constants[\"Gain\"][qm][\"ctime\"] = ctime\n",
     "    ret_constants[\"Gain\"][qm][\"data\"] = np.array(gain_vs_time)\n",
+    "    # Fill missing data for compatibility with plotting code\n",
     "    ret_constants[\"Gain\"][qm][\"dataBP\"] = np.array(gain_vs_time)\n",
     "    ret_constants[\"Gain\"][qm][\"nBP\"] = np.array(gain_vs_time)\n",
     "\n",
@@ -448,12 +430,13 @@
     "    data_vs_time = []\n",
     "    for iG, iN in icomb:\n",
     "        data_vs_time.append(\n",
-    "            cdataN_vs_time[iN] * (8000 / 3.6 / 67.) / cdataG_vs_time[iG])\n",
+    "            cdataN_vs_time[iN] * adu_to_photon / cdataG_vs_time[iG])\n",
     "\n",
     "    print(np.array(gain_vs_time).shape)\n",
     "    ctime_ts = [t.timestamp() for t in ctime]\n",
     "    ret_constants[\"Noise-e\"][qm][\"ctime\"] = ctime\n",
     "    ret_constants[\"Noise-e\"][qm][\"data\"] = np.array(data_vs_time)\n",
+    "    # Fill missing data for compatibility with plotting code\n",
     "    ret_constants[\"Noise-e\"][qm][\"dataBP\"] = np.array(data_vs_time)\n",
     "    ret_constants[\"Noise-e\"][qm][\"nBP\"] = np.array(data_vs_time)\n",
     "    \n",
@@ -473,12 +456,12 @@
     "\n",
     "# Define range for plotting\n",
     "rangevals = {\n",
-    "    \"Offset\": [[800., 1500], [600, 900]],\n",
-    "    \"Noise\": [[2.0, 16], [1.0, 7.0]],\n",
-    "    \"Gain\": [[20, 30], [20, 30]],\n",
-    "    \"Noise-e\": [[100., 600.], [100., 600.]],\n",
-    "    \"SlopesCI\": [[0.95, 1.05], [0.0, 0.5]],\n",
-    "    \"SlopesFF\": [[0.8, 1.2], [0.8, 1.2]]\n",
+    "    \"Offset\": [[4000., 5500], [6500, 8500]],\n",
+    "    \"Noise\": [[2.5, 15], [7.5, 17.0]],\n",
+    "    \"Gain\": [[0.8, 1.2], [0.8, 1.2]],\n",
+    "    \"Noise-e\": [[85., 500.], [85., 500.]],\n",
+    "    \"SlopesPC\": [[22.0, 27.0], [-0.5, 1.5]],\n",
+    "    \"SlopesFF\": [[0.8, 1.2], [0.6, 1.2]]\n",
     "}\n",
     "\n",
     "nMemToShow = 32\n",
@@ -553,7 +536,6 @@
     "                if item[0] in data:\n",
     "                    rdata[key] = np.array(data[item[0]])[sort_ind]\n",
     "\n",
-    "            # print(rdata['Mean'].shape)\n",
     "            nTimes = rdata['Mean'].shape[0]\n",
     "            nPixels = rdata['Mean'].shape[1] * rdata['Mean'].shape[2]\n",
     "            nBins = nMemToShow * nPixels\n",
@@ -636,11 +618,7 @@
     "                          title=title, cb_label=cb_label,\n",
     "                          fname='{}/{}_{}_g{}_MEM_{}.png'.format(\n",
     "                                  out_folder, const, mod, gain, key),\n",
-    "                          vmin=vmin, vmax=vmax)\n",
-    "\n",
-    "                # break\n",
-    "            #break\n",
-    "        #break"
+    "                          vmin=vmin, vmax=vmax)"
    ]
   }
  ],
diff --git a/notebooks/AGIPD/PlotFromCalDB_Summary_AGIPD_NBC.ipynb b/notebooks/AGIPD/PlotFromCalDB_Summary_AGIPD_NBC.ipynb
index 016a8ef0d9cefb06e346b1ebe10b238e1ae51718..23db813cc49ef042bb56f1975e278aed642cc1c3 100644
--- a/notebooks/AGIPD/PlotFromCalDB_Summary_AGIPD_NBC.ipynb
+++ b/notebooks/AGIPD/PlotFromCalDB_Summary_AGIPD_NBC.ipynb
@@ -34,15 +34,14 @@
    },
    "outputs": [],
    "source": [
-    "from cal_tools.ana_tools import *\n",
+    "import warnings\n",
+    "warnings.filterwarnings('ignore')\n",
+    "\n",
     "import numpy as np\n",
     "import matplotlib\n",
-    "matplotlib.use(\"agg\")\n",
     "% matplotlib inline\n",
-    "import matplotlib.pyplot as plt\n",
     "\n",
-    "import warnings\n",
-    "warnings.filterwarnings('ignore')"
+    "from cal_tools.ana_tools import *"
    ]
   },
   {
@@ -243,7 +242,7 @@
     "                    const, gain_name[gain], keys[key][1])\n",
     "            cb_label = '{}, {} {}'.format(const, keys[key][2], unit)\n",
     "\n",
-    "            HMCombine(np.array(mod_data[key])[mod_idx][::-1],\n",
+    "            hm_combine(np.array(mod_data[key])[mod_idx][::-1],\n",
     "                      y_ticks=np.arange(nModules)[::-1]+0.8,\n",
     "                      y_ticklabels=np.array(mod_names)[mod_idx],\n",
     "                      x_label='Creation Time', y_label='Module ID',\n",
@@ -253,12 +252,7 @@
     "                      fname='{}/{}_all_g{}_{}.png'.format(\n",
     "                out_folder, const, gain, key),\n",
     "                vmin=vmin, vmax=vmax,\n",
-    "                pad=[0.125, 0.151, 0.12, 0.17], type=htype)\n",
-    "\n",
-    "            #plt.show()\n",
-    "            #break\n",
-    "        #break\n",
-    "    #break"
+    "                pad=[0.125, 0.151, 0.12, 0.17], type=htype)"
    ]
   }
  ],
diff --git a/notebooks/LPD/PlotFromCalDB_LPD_NBC.ipynb b/notebooks/LPD/PlotFromCalDB_LPD_NBC.ipynb
index abdbaf26b586131938a238c8b246be3577b863b2..63fb41601cc3cff3d178bb378b3f370dedfa46ef 100644
--- a/notebooks/LPD/PlotFromCalDB_LPD_NBC.ipynb
+++ b/notebooks/LPD/PlotFromCalDB_LPD_NBC.ipynb
@@ -31,12 +31,12 @@
     "start_date = \"2018-01-30\"  # Date to start investigation interval from\n",
     "end_date = \"2018-12-12\"  # Date to end investigation interval at, can be \"now\"\n",
     "constants = [\"Offset\", \"Noise\", \"SlopesFF\", \"SlopesCI\"] # constants to plot\n",
-    "modules = [1]  # Modules, range allowed\n",
+    "modules = [2]  # Modules, range allowed\n",
     "bias_voltages = [250, 500]  # Bias voltage\n",
     "mem_cells = [1, 128, 256, 512]  # Number of used memory cells. Typically: 4,32,64,128,176.\n",
     "photon_energy = 9.2  # Photon energy of the beam\n",
-    "out_folder = \"/gpfs/exfel/data/scratch/karnem/testLPD_16/\"  # Output folder, required\n",
-    "use_existing = \"\" # Input folder\n",
+    "out_folder = \"/gpfs/exfel/data/scratch/karnem/testLPD_15/\"  # Output folder, required\n",
+    "use_existing = \"/gpfs/exfel/data/scratch/karnem/testLPD_16/\" # Input folder\n",
     "cal_db_timeout = 180000 # timeout on caldb requests\",\n",
     "detectorDB = \"LPD1M1\"  # detector entry in the DB to investigate\n",
     "dclass = \"LPD\"  # Detector class\n",
@@ -52,24 +52,20 @@
    },
    "outputs": [],
    "source": [
-    "import os\n",
-    "import numpy as np\n",
-    "import matplotlib\n",
-    "\n",
-    "##matplotlib.use(\"agg\")\n",
-    "import matplotlib.pyplot as plt\n",
-    "% matplotlib inline\n",
-    "\n",
-    "import sys\n",
     "import datetime\n",
     "import dateutil.parser\n",
+    "import numpy as np\n",
+    "import os\n",
+    "import sys\n",
     "import warnings\n",
-    "\n",
     "warnings.filterwarnings('ignore')\n",
     "\n",
+    "import matplotlib\n",
+    "% matplotlib inline\n",
+    "\n",
     "from iCalibrationDB import Constants, Conditions, Detectors\n",
     "from cal_tools.tools import get_from_db\n",
-    "from cal_tools.ana_tools import *\n"
+    "from cal_tools.ana_tools import *"
    ]
   },
   {
@@ -83,8 +79,10 @@
     "# Prepare variables\n",
     "interval = 1  # interval for evaluation in days\n",
     "\n",
-    "if modules[0] == -1:\n",
-    "    modules = list(range(16))\n",
+    "nMem = 512 # Number of mem Cells to store\n",
+    "spShape = (64,64) # Shape of superpixel\n",
+    "\n",
+    "adu_to_photon = 8000 / 3.6 / 67.# ADU to photon conversion factor\n",
     "\n",
     "in_mod_names = []\n",
     "for mod in modules:\n",
@@ -130,12 +128,14 @@
    "source": [
     "import copy\n",
     "\n",
+    "\n",
     "def prepare_to_store(a, nMem):\n",
-    "    shape = list(a.shape[:2])+[nMem,2]\n",
+    "    shape = list(a.shape[:2])+[nMem, 2]\n",
     "    b = np.full(shape, np.nan)\n",
     "    b[:, :, :a.shape[2]] = a[:, :, :, :2]\n",
     "    return b\n",
     "\n",
+    "\n",
     "def get_rebined(a, rebin):\n",
     "    return a.reshape(\n",
     "                int(a.shape[0] / rebin[0]),\n",
@@ -144,10 +144,24 @@
     "                rebin[1],\n",
     "                a.shape[2],\n",
     "                a.shape[3])\n",
-    "    \n",
     "\n",
-    "nMem = 512 # Number of mem Cells to store\n",
-    "spShape = (64,64) # Shape of superpixel\n",
+    "\n",
+    "def modify_const(const, data):\n",
+    "\n",
+    "    if const in ['SlopesFF']:\n",
+    "        data = data[..., None, None]\n",
+    "\n",
+    "    if(len(data.shape)==5):\n",
+    "        data = data[:,:,:,:,0]\n",
+    "\n",
+    "    if len(data.shape) < 4:\n",
+    "        print(data.shape, \"Unexpected shape !!!!!!!!!\")\n",
+    "\n",
+    "    if data.shape[0] != 256:\n",
+    "        data = data.swapaxes(0, 2).swapaxes(1,3).swapaxes(2,3) \n",
+    "                            \n",
+    "    return data\n",
+    "\n",
     "\n",
     "ret_constants = {}\n",
     "\n",
@@ -214,25 +228,11 @@
     "                                                                  cdata is not None),\n",
     "                          ctime)\n",
     "                    print(cdata.shape)\n",
-    "\n",
-    "                    if const in ['SlopesFF']:\n",
-    "                        cdata = cdata[...,None,None]\n",
-    "                        \n",
-    "                    if(len(cdata.shape)==5):\n",
-    "                        cdata = cdata[:,:,:,:,0]\n",
-    "\n",
-    "                    if len(cdata.shape) < 4:\n",
-    "                        print(cdata.shape, \"Unexpected shape !!!!!!!!!\")\n",
-    "\n",
-    "                    if cdata.shape[0] != 256:\n",
-    "                        cdata = cdata.swapaxes(0, 2).swapaxes(1,3).swapaxes(2,3) \n",
-    "\n",
+    "                    cdata = modify_const(const, cdata)\n",
     "                    print(cdata.shape)\n",
     "\n",
     "                    # Request bad pixel mask\n",
     "                    if const in constantsDark:\n",
-    "                        #for par in mcond.parameters:\n",
-    "                        #    print (par.name, par.value)\n",
     "                        print('RequestBP ',\n",
     "                              (creation_time + step + step + step + step))\n",
     "                        cdataBP, ctimeBP = get_from_db(getattr(det, qm),\n",
@@ -256,21 +256,11 @@
     "\n",
     "                        print(\"Found BP {}\".format(ctimeBP))\n",
     "                        print(cdataBP.shape)\n",
-    "\n",
-    "                        if const in ['SlopesFF']:\n",
-    "                            cdataBP = cdataBP[...,None,None]\n",
-    "                        \n",
-    "                        if(len(cdataBP.shape)==5):\n",
-    "                            cdataBP = cdataBP[:,:,:,:,0]\n",
-    "\n",
-    "                        if cdataBP.shape[0] != 256:\n",
-    "                            cdataBP = cdataBP.swapaxes(0, 2).swapaxes(1,3).swapaxes(2,3) \n",
-    "\n",
-    "                        if (len(cdataBP.shape) < 4):\n",
-    "                            print(cdataBP.shape, \"Unexpected shape !!!!!!!!!\")\n",
+    "                        cdataBP = modify_const(const, cdataBP)\n",
+    "                        print(cdataBP.shape)\n",
     "\n",
     "                        if cdataBP.shape != cdata.shape:\n",
-    "                            print(cdataBP.shape, 'Wrong BP shape!!!')\n",
+    "                            print('Wrong BP shape!!!')\n",
     "                            ctime = ctime.replace(tzinfo=None)\n",
     "                            dt = ctime - step\n",
     "                            continue\n",
@@ -311,7 +301,7 @@
     "                                                     'mdata': dpar})\n",
     "                    \n",
     "                    ctime = ctime.replace(tzinfo=None)\n",
-    "                    dt = ctime - step\n"
+    "                    dt = ctime - step"
    ]
   },
   {
@@ -355,13 +345,15 @@
    },
    "outputs": [],
    "source": [
-    "print ('Combine Gain FF and CI and Noise in [e-]')\n",
+    "# Combine FF and PC data to calculate Gain\n",
+    "# Estimate Noise in units of electrons\n",
+    "print ('Calculate Gain and Noise in electron units')\n",
+    "\n",
     "ret_constants[\"Gain\"] = {}\n",
     "ret_constants[\"Noise-e\"] = {}\n",
-    "\n",
     "for module in list(range(16)):\n",
     "    if (\"SlopesFF\" not in ret_constants or\n",
-    "            \"SlopesPC\" not in ret_constants):\n",
+    "            \"SlopesCI\" not in ret_constants):\n",
     "        break\n",
     "\n",
     "    qm = \"Q{}M{}\".format(module // 4 + 1, module % 4 + 1)\n",
@@ -404,6 +396,7 @@
     "    \n",
     "    ret_constants[\"Gain\"][qm][\"ctime\"] = ctime\n",
     "    ret_constants[\"Gain\"][qm][\"data\"] = np.array(gain_vs_time)\n",
+    "    # Fill missing data for compatibility with plotting code\n",
     "    ret_constants[\"Gain\"][qm][\"dataBP\"] = np.array(gain_vs_time)\n",
     "    ret_constants[\"Gain\"][qm][\"nBP\"] = np.array(gain_vs_time)\n",
     "\n",
@@ -430,12 +423,13 @@
     "    data_vs_time = []\n",
     "    for iG, iN in icomb:\n",
     "        data_vs_time.append(\n",
-    "            cdataN_vs_time[iN] * (8000 / 3.6 / 67.) / cdataG_vs_time[iG])\n",
+    "            cdataN_vs_time[iN] * adu_to_photon / cdataG_vs_time[iG])\n",
     "\n",
     "    print(np.array(gain_vs_time).shape)\n",
     "    ctime_ts = [t.timestamp() for t in ctime]\n",
     "    ret_constants[\"Noise-e\"][qm][\"ctime\"] = ctime\n",
     "    ret_constants[\"Noise-e\"][qm][\"data\"] = np.array(data_vs_time)\n",
+    "    # Fill missing data for compatibility with plotting code\n",
     "    ret_constants[\"Noise-e\"][qm][\"dataBP\"] = np.array(data_vs_time)\n",
     "    ret_constants[\"Noise-e\"][qm][\"nBP\"] = np.array(data_vs_time)\n",
     "    \n",
@@ -536,7 +530,6 @@
     "                if item[0] in data:\n",
     "                    rdata[key] = np.array(data[item[0]])[sort_ind]\n",
     "\n",
-    "            # print(rdata['Mean'].shape)\n",
     "            nTimes = rdata['Mean'].shape[0]\n",
     "            nPixels = rdata['Mean'].shape[1] * rdata['Mean'].shape[2]\n",
     "            nBins = nMemToShow * nPixels\n",
@@ -619,12 +612,7 @@
     "                          title=title, cb_label=cb_label,\n",
     "                          fname='{}/{}_{}_g{}_MEM_{}.png'.format(\n",
     "                                  out_folder, const, mod, gain, key),\n",
-    "                          vmin=vmin, vmax=vmax)\n",
-    "\n",
-    "                #break\n",
-    "            #break\n",
-    "        #break\n",
-    "    #break"
+    "                          vmin=vmin, vmax=vmax)"
    ]
   }
  ],
diff --git a/xfel_calibrate/notebooks.py b/xfel_calibrate/notebooks.py
index 3dcfef45e2f320a61d16c259a734e183f509e446..fa8da6fe36eed80986f70d8da740f4b2a062d786 100644
--- a/xfel_calibrate/notebooks.py
+++ b/xfel_calibrate/notebooks.py
@@ -33,6 +33,13 @@ notebooks = {
                                                "default concurrency": None,
                                                "cluster cores": 8},
                                },
+                       "STATS_FROM_DB":   {
+                               "notebook": "notebooks/AGIPD/PlotFromCalDB_AGIPD_NBC.ipynb",
+			       "dep_notebooks": ["notebooks/AGIPD/PlotFromCalDB_Summary_AGIPD_NBC.ipynb"],
+                               "concurrency": {"parameter": "modules",
+                                               "default concurrency": None,
+                                               "cluster cores": 1},
+                               },
                       },
              "LPD": {
                        "DARK": {
@@ -68,8 +75,9 @@ notebooks = {
                                                "cluster cores": 2},
                                },
                        "STATS_FROM_DB":   {
-                               "notebook": "notebooks/LPD/PlotFromCalDB.ipynb",
-                               "concurrency": {"parameter": None,
+                               "notebook": "notebooks/LPD/PlotFromCalDB_LPD_NBC.ipynb",
+			       "dep_notebooks": ["notebooks/AGIPD/PlotFromCalDB_Summary_AGIPD_NBC.ipynb"],
+                               "concurrency": {"parameter": "modules",
                                                "default concurrency": None,
                                                "cluster cores": 1},
                                },