diff --git a/docs/source/advanced.rst b/docs/source/advanced.rst
index c9c707b1fd84ffd2e7136e5f464f75ee2a7caef8..f2fb149984a442afeb8dd77a92b803cde20c311e 100644
--- a/docs/source/advanced.rst
+++ b/docs/source/advanced.rst
@@ -108,4 +108,98 @@ This can be useful to add user requests while running. For this:
    manually, assuming the correction notebook allows run and overwrite paramters::
    
        xfel-calibrate ...... --run XYZ,ZXY-YYS --overwrite
+  
+  
+Using a Parameter Generator Function
+------------------------------------
+
+By default, the parameters to be exposed to the command line are deduced from the
+first code cell of the notebook, after resolving the notebook itself from the 
+detector and characterization type. For some applications it might be beneficial
+to define a context-specific parameter range within the same notebook, based on
+additional user input. This can be done via a parameter generation function which
+is defined in one of the code cell::
+
+    def extend_parms(detector_instance):
+        from iCalibrationDB import Conditions
+        import inspect
+        existing = set()
+        def extract_parms(cls):
+            args, varargs, varkw, defaults = inspect.getargspec(cls.__init__)
+            pList = []        
+            for i, arg in enumerate(args[1:][::-1]):
+                if arg in existing:
+                    continue
+
+                existing.add(arg)
+
+                if i < len(defaults):
+                    default = defaults[::-1][i]                
+                    if str(default).isdigit():
+                        pList.append("{} = {}".format(arg, default))
+                    elif default is None or default == "None":
+                        pList.append("{} = \"None\"".format(arg))
+                    else:
+                        pList.append("{} = \"{}\"".format(arg, default))
+                else:
+                    pList.append("{} = 0.  # required".format(arg))
+            return set(pList[::-1])  # mandatories first
+        dtype = "LPD" if "LPD" in detector_instance.upper() else "AGIPD"
+        all_conditions = set()
+        for c in dir(Conditions):
+            if c[:2] != "__":
+                condition = getattr(Conditions, c)
+                parms = extract_parms(getattr(condition, dtype))
+                [all_conditions.add(p) for p in parms]
+        return "\n".join(all_conditions)
+        
+
+.. note::
+
+   Note how all imports are inlined, as the function is executed outside the
+   notebook context.
+       
+In the example, the function generates a list of additional parameters depending
+on the `detector_instance` given. Here, `detector_instance` is defined in the first
+code cell the usual way. Any other parameters defined such, that have names matching 
+those of the generator function signature are passed to this function. The function
+should then return a string containing additional code to be appended to the first
+code cell.
+
+To make use of this functionality, the parameter generator function needs to be 
+configured in `notebooks.py`, e.g. ::
+
+    ...
+    "GENERIC": {
+        "DBTOH5": {
+            "notebook": "notebooks/generic/DB_Constants_to_HDF5_NBC.ipynb",
+            "concurrency": {"parameter": None,
+                            "default concurrency": None,
+                            "cluster cores": 32},
+            "extend parms": "extend_parms",
+        },
+    }
+    ...
        
+To generically query which parameters are defined in the first code cell, the
+code execution history feature of iPython can be used::
+
+    ip = get_ipython()
+    session = ip.history_manager.get_last_session_id()
+    first_cell = next(ip.history_manager.get_range(session, 1, 2, raw=True))
+    _, _, code = first_cell
+    code = code.split("\n")
+    parms = {}
+    for c in code:
+        n, v = c.split("=")
+        n = n.strip()
+        v = v.strip()
+        try:
+            parms[n] = float(v)
+        except:
+            parms[n] = str(v) if not isinstance(v, str) else v
+        if parms[n] == "None" or parms[n] == "'None'":
+            parms[n] = None
+                      
+This will create a dictionary `parms` which contains all parameters either
+as `float` or `str` values.
\ No newline at end of file
diff --git a/notebooks/generic/DB_Constants_to_HDF5_NBC.ipynb b/notebooks/generic/DB_Constants_to_HDF5_NBC.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..a15dc3ff49b603f4e1a465ba26e43a78311818f1
--- /dev/null
+++ b/notebooks/generic/DB_Constants_to_HDF5_NBC.ipynb
@@ -0,0 +1,267 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Constants from DB to HDF5 #\n",
+    "\n",
+    "Version 0.1, Author: S. Hauf\n",
+    "\n",
+    "Currently available instances are LPD1M1 and AGIPD1M1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "detector_instance = \"LPD1M1\"  # the detector instance to get constants for e.g. LPD1M1, required\n",
+    "out_file = \"/gpfs/exfel/data/scratch/haufs/test/test.h5\"  # HDF5 file to output constants into, required\n",
+    "valid_at = \"\"  # ISO formatted date for which constants shoudl be valid. Leave empty to get most current ones\n",
+    "cal_db_interface = \"tcp://max-exfl015:5005\"\n",
+    "modules = [-1]  # modules to get data from, in terms of numerical quadrant indices, range allowed"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "dtype = \"LPD\" if \"LPD\" in detector_instance.upper() else \"AGIPD\"\n",
+    "darkconst = [\"Offset\", \"Noise\", \"SlopesPC\", \"SlopesCI\", \"BadPixelsDark\", \"BadPixelsPC\", \"BadPixelsCI\"]\n",
+    "skip = [\"BadPixels\"]\n",
+    "\n",
+    "overwrites = {\"LPD\": {\"SlopesFF\": {\"memory_cells\": 1},\n",
+    "                      \"BadPixelsFF\": {\"memory_cells\": 1}}}\n",
+    "\n",
+    "if modules[0] == -1:\n",
+    "    modules = list(range(16))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "import copy\n",
+    "import datetime\n",
+    "import h5py\n",
+    "import inspect\n",
+    "\n",
+    "from iCalibrationDB import ConstantMetaData, Constants, Conditions, Detectors, Versions\n",
+    "\n",
+    "def extend_parms(detector_instance):\n",
+    "    from iCalibrationDB import Conditions\n",
+    "    import inspect\n",
+    "    existing = set()\n",
+    "    def extract_parms(cls):\n",
+    "        args, varargs, varkw, defaults = inspect.getargspec(cls.__init__)\n",
+    "        pList = []        \n",
+    "        for i, arg in enumerate(args[1:][::-1]):\n",
+    "            if arg in existing:\n",
+    "                continue\n",
+    "            \n",
+    "            existing.add(arg)\n",
+    "            \n",
+    "            if i < len(defaults):\n",
+    "                default = defaults[::-1][i]                \n",
+    "                if str(default).isdigit():\n",
+    "                    pList.append(\"{} = {}\".format(arg, default))\n",
+    "                elif default is None or default == \"None\":\n",
+    "                    pList.append(\"{} = \\\"None\\\"\".format(arg))\n",
+    "                else:\n",
+    "                    pList.append(\"{} = \\\"{}\\\"\".format(arg, default))\n",
+    "            else:\n",
+    "                pList.append(\"{} = 0.  # required\".format(arg))\n",
+    "        return set(pList[::-1])  # mandatories first\n",
+    "    dtype = \"LPD\" if \"LPD\" in detector_instance.upper() else \"AGIPD\"\n",
+    "    all_conditions = set()\n",
+    "    for c in dir(Conditions):\n",
+    "        if c[:2] != \"__\":\n",
+    "            condition = getattr(Conditions, c)\n",
+    "            parms = extract_parms(getattr(condition, dtype))\n",
+    "            [all_conditions.add(p) for p in parms]\n",
+    "    return \"\\n\".join(all_conditions)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "det = getattr(Detectors, detector_instance)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "ip = get_ipython()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "first_cell = next(ip.history_manager.get_range(ip.history_manager.get_last_session_id(), 1, 2, raw=True))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "_, _, code = first_cell\n",
+    "code = code.split(\"\\n\")\n",
+    "parms = {}\n",
+    "for c in code:\n",
+    "    n, v = c.split(\"=\")\n",
+    "    n = n.strip()\n",
+    "    v = v.strip()\n",
+    "    try:\n",
+    "        parms[n] = float(v)\n",
+    "    except:\n",
+    "        parms[n] = str(v) if not isinstance(v, str) else v\n",
+    "    if parms[n] == \"None\" or parms[n] == \"'None'\":\n",
+    "        parms[n] = None"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Failed for const RelativeGain of Q2M1: Error sending to database: {'reason': '\\'NoneType\\' object has no attribute \\'get\\':  File \"/gpfs/exfel/data/scratch/haufs/karabo-2.2.1/karabo/devices/calibrationDbRemote/src/calibrationDBRemote/calibration_db_remote.py\", line 373, in zmq_server_runner\\n    krb_ccv)\\n  File \"/gpfs/exfel/data/scratch/haufs/karabo-2.2.1/karabo/devices/calibrationDbRemote/src/calibrationDBRemote/calibration_karabo.py\", line 53, in get_calib_const_version_file\\n    file_name_abs_url = \\'{0}{1}\\'.format(ccv_krb_h.get(\\'hdf5path\\'),\\n', 'success': False}\n"
+     ]
+    }
+   ],
+   "source": [
+    "ofile = h5py.File(out_file, \"w\")\n",
+    "\n",
+    "detector = getattr(Detectors, detector_instance)\n",
+    "for i in modules:\n",
+    "    qm = \"Q{}M{}\".format(i//4+1, i%4+1)\n",
+    "    module = getattr(detector, qm)\n",
+    "    dconstants = getattr(Constants, dtype)\n",
+    "    for const in dir(dconstants):\n",
+    "        if const[:2] != \"__\":\n",
+    "            \n",
+    "            if const in skip:\n",
+    "                continue\n",
+    "            \n",
+    "            cparms = copy.copy(parms)\n",
+    "            if dtype in overwrites:\n",
+    "                do = overwrites[dtype]\n",
+    "                if const in do:\n",
+    "                    for arg, v in do[const].items():\n",
+    "                        cparms[arg] = v\n",
+    "            \n",
+    "            try:\n",
+    "                metadata = ConstantMetaData()\n",
+    "                cons = getattr(dconstants, const)()\n",
+    "                metadata.calibration_constant = cons\n",
+    "\n",
+    "                # set the operating condition\n",
+    "\n",
+    "                cond =  Conditions.Dark if const in darkconst else Conditions.Illuminated\n",
+    "\n",
+    "                condition = getattr(cond, dtype)\n",
+    "\n",
+    "                args, varargs, varkw, defaults = inspect.getargspec(condition.__init__)\n",
+    "                alist = []\n",
+    "                plist = {}\n",
+    "                for i, arg in enumerate(args[1:][::-1]):\n",
+    "                    #if i < len(defaults):\n",
+    "                    #    plist[arg] = parms[arg]\n",
+    "                    #else:\n",
+    "                    #    alist.append(parms[arg])\n",
+    "                    plist[arg] = cparms[arg]\n",
+    "\n",
+    "\n",
+    "                condition = condition(**plist)\n",
+    "\n",
+    "                metadata.detector_condition = condition\n",
+    "\n",
+    "                # specify the a version for this constant\n",
+    "                if valid_at is None or valid_at == \"\":\n",
+    "                    creation_time = datetime.datetime.now()\n",
+    "                    metadata.calibration_constant_version = Versions.Now(\n",
+    "                        device=module)\n",
+    "                else:\n",
+    "                    metadata.calibration_constant_version = Versions.Timespan(\n",
+    "                        device=module,\n",
+    "                        start=valid_at)\n",
+    "                    creation_time = valid_at\n",
+    "\n",
+    "                ctime = creation_time.isoformat() if not isinstance(creation_time, str) else creation_time\n",
+    "\n",
+    "                metadata.retrieve(cal_db_interface, when=ctime)\n",
+    "                \n",
+    "                ofile[\"{}/{}/data\".format(qm, const)] = metadata.calibration_constant.data\n",
+    "            except Exception as e:\n",
+    "                print(\"Failed for const {} of {}: {}\".format(const, qm, e))\n",
+    "ofile.close()         "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.4.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}